Compare commits
138 commits
Author | SHA1 | Date | |
---|---|---|---|
Alexander Yakovlev | 0b8e772fb6 | ||
Alexander Yakovlev | ddc0bac972 | ||
Alexander Yakovlev | 5a49817e56 | ||
Alexander Yakovlev | e2f36f65f4 | ||
9940e04431 | |||
7adcdb89cd | |||
792b62fc73 | |||
70f078c4b2 | |||
5122eafc74 | |||
6a140afbe8 | |||
4b815523f3 | |||
d678f9db38 | |||
e514f7af91 | |||
6a9a725cac | |||
5e0250731c | |||
78960db384 | |||
f378a3a47b | |||
ee938ff563 | |||
5f2b3af2d7 | |||
19677b7626 | |||
17eb0554fe | |||
f1f81a9ba4 | |||
672c07f5b0 | |||
381ff1d219 | |||
1e0d8d3266 | |||
71c77d41a3 | |||
f7c00f898c | |||
559a61828d | |||
1a60292860 | |||
1d5ba2561b | |||
b77eded7c2 | |||
f37c114624 | |||
120e1f66d8 | |||
b407f66c88 | |||
7a60083945 | |||
309286b528 | |||
f996eb363b | |||
3cdf6b2b2a | |||
91d200eb44 | |||
1150911a93 | |||
25f67948b2 | |||
7b7645cb5e | |||
d452569ad1 | |||
fbf762ff16 | |||
7ee7d4c704 | |||
021abe31f7 | |||
2ff31f8ec2 | |||
adab6692e7 | |||
84cbe10eba | |||
79ce4d2501 | |||
4afadaaa26 | |||
a0e94ae86d | |||
5f7fb483da | |||
d97468ebd2 | |||
e953e1cdca | |||
2b921c84e9 | |||
784ef72392 | |||
446df2f8a7 | |||
71f0e344e1 | |||
cafecb4e13 | |||
94c16927d3 | |||
5b054b520b | |||
c48c443854 | |||
6013b0dcbf | |||
c93fe0d6ce | |||
fe9781bdfe | |||
b2c849e8c4 | |||
834898a2f2 | |||
30ea6239b9 | |||
b1ac656bee | |||
b6ac3b2518 | |||
18f300d46d | |||
987473ffa6 | |||
96def786a4 | |||
80f49e5564 | |||
c92688c80a | |||
73d40eafc0 | |||
663ef8ccba | |||
13267db0d2 | |||
538732cbf4 | |||
db86cacaa0 | |||
21c51fbc3d | |||
d2fa55beae | |||
f2313c7da4 | |||
723bbb1098 | |||
f3c3e57e41 | |||
2e985ad5fa | |||
8a71425dc4 | |||
c151201384 | |||
446292b057 | |||
1cb65ade49 | |||
e29283af1c | |||
20bc117dae | |||
f6d1b5f7a6 | |||
caf664e014 | |||
90619bef9a | |||
607a3804bc | |||
0047f31770 | |||
e733a8b481 | |||
e882ffa82e | |||
a0571cfc11 | |||
b65d9e89cf | |||
9d4aad4cf9 | |||
d348d7e41f | |||
7c5ef008d8 | |||
53fc953caa | |||
3e268d2231 | |||
8980dad584 | |||
3beeea1588 | |||
6343ae50ea | |||
f4e39a69dc | |||
f193393a2a | |||
b4eb3d3551 | |||
1b2e06c2d5 | |||
b777046b0b | |||
328623b8dd | |||
3fc93e06cd | |||
f00b7ec876 | |||
8989daef49 | |||
1fc45e85b4 | |||
e249b8d45d | |||
4dc73a6783 | |||
a5371c4711 | |||
07ca4336fb | |||
a19c626753 | |||
4ba9f21e69 | |||
d8795740f9 | |||
35ce6a56be | |||
e447c1c07f | |||
691af2761f | |||
347aedc4ab | |||
aeba653e9f | |||
2b0750dada | |||
0601c29c85 | |||
1cfc7a19c3 | |||
4332c66b43 | |||
b6cc8298bc | |||
2a7cd67506 |
35
.eslintrc
Normal file
35
.eslintrc
Normal file
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"commonjs": true,
|
||||
"es6": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"parserOptions": {
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"indent": [
|
||||
"warn",
|
||||
4,
|
||||
{
|
||||
"SwitchCase": 1
|
||||
}
|
||||
],
|
||||
"quotes": [
|
||||
"warn",
|
||||
"double"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"no-undef": "error",
|
||||
"no-unused-vars": "warn",
|
||||
"eqeqeq": [
|
||||
"error",
|
||||
"always"
|
||||
]
|
||||
}
|
||||
}
|
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -1,8 +1,6 @@
|
|||
### Discord bots ####
|
||||
guilds.json
|
||||
token.json
|
||||
log
|
||||
|
||||
update.sh
|
||||
guilds-data/*
|
||||
token.json*
|
||||
|
||||
# Created by https://www.gitignore.io/api/node,visualstudiocode
|
||||
|
||||
|
|
6
.vscode/launch.json
vendored
6
.vscode/launch.json
vendored
|
@ -8,7 +8,11 @@
|
|||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Launch Program",
|
||||
"program": "${workspaceRoot}/bootstrap.js"
|
||||
"program": "${workspaceRoot}/app/index.js",
|
||||
"args":[
|
||||
"token.json",
|
||||
"guilds.json"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"files.exclude": {
|
||||
"log": true,
|
||||
".npmrc": true,
|
||||
"node_modules": true,
|
||||
"node_cache": true,
|
||||
"token.json": true
|
||||
}
|
||||
}
|
139
CHANGELOG.md
139
CHANGELOG.md
|
@ -1,22 +1,119 @@
|
|||
# Changelog
|
||||
|
||||
## v3.0.0-b2
|
||||
## v3.5.2
|
||||
### Added
|
||||
- Added bot name to version command
|
||||
- Added stats command
|
||||
|
||||
### Fixed
|
||||
- Fixed reset command not being admin only
|
||||
|
||||
- Full and short youtube urls not being properly converted
|
||||
|
||||
## v3.0.0-b1
|
||||
|
||||
### Added
|
||||
- Fancy new @bot help command
|
||||
## v3.5.1
|
||||
### Fixed
|
||||
- Fixed reset command not working
|
||||
|
||||
### Updated
|
||||
- Removed deletion of data for removed guilds on startup, as Discord outages can wrongly report the bot as being removed
|
||||
|
||||
## v3.5.0
|
||||
### Added
|
||||
- MongoDB support
|
||||
- Reset command to clear all data for a guild
|
||||
|
||||
### Updated
|
||||
- Removed automatic daily restart (I think it shouldn't be needed now that MongoDB support is working)
|
||||
|
||||
### Fixed
|
||||
- Guild data being deleted on a Discord outage
|
||||
|
||||
## v3.4.0
|
||||
### Added
|
||||
- Added automatic daily restart
|
||||
|
||||
### Updated
|
||||
- Disabled a few unused websocket events
|
||||
- Update database compaction to be more frequent
|
||||
|
||||
### Fixed
|
||||
- Fixed YouTube feeds not updating
|
||||
|
||||
## v3.3.0
|
||||
### Updated
|
||||
- Updated RSS parser to now use [rss-parser](https://www.npmjs.com/package/rss-parser) module to increase compatibility with feeds
|
||||
- Updated RSS entry caching to exclude 'www.' prefix to avoid certain mis-caches
|
||||
|
||||
## v3.2.2
|
||||
### Fixed
|
||||
- Fixed a couple of edge case errors
|
||||
|
||||
## v3.2.1
|
||||
### Fixed
|
||||
- Fixed memory leak due to unconfigured discord.js caching
|
||||
|
||||
## v3.2.0
|
||||
### Updated
|
||||
- Updated data storage to use a NeDB database rather than a json file
|
||||
- Updated feed checking interval to check one guild every 10 seconds (this may slow down the time it takes to post, but will improve performance)
|
||||
- Improve stability of feed checking
|
||||
- Tidy up some console spam
|
||||
### Fixed
|
||||
- Fix bot crash if feed article contains link with invalid host name
|
||||
- Temporary fix for bot crash if used with a feed without links in the articles (didn't realise this was possible...)
|
||||
- Attempt fix for issues caused by every feed of every guild being checked at the same time
|
||||
|
||||
## v3.1.3
|
||||
### Added
|
||||
- Add rudimentary pagination for viewing feeds when there are more than 10
|
||||
|
||||
### Fixed
|
||||
- Fix articles not posting if contents too long for a single discord message
|
||||
|
||||
## v3.1.2
|
||||
### Fixed
|
||||
- Deleted channels with feeds sending the bot into a reconnect loop
|
||||
|
||||
## v3.1.1
|
||||
### Fixed
|
||||
- Empty RSS feed crash
|
||||
|
||||
## v3.1.0
|
||||
### Added
|
||||
- RSS element content is now included in the post the bot makes when there is a new feed
|
||||
- Warning message after setup command if supplied URL does not return valid RSS
|
||||
- Guild join and leave messages in the console
|
||||
- Removal of guild data if the bot leaves a guild
|
||||
|
||||
### Updated
|
||||
- Route a lot of mostly irrelevant console spam to a file instead of the console
|
||||
- Updated launch command to pass max-old-space-size parameter to limit memory usage
|
||||
|
||||
### Fixed
|
||||
- Fixed syntax error when role omitted in feed setup command; it is now properly optional
|
||||
- Fixed the wrong feed sometimes being removed when using the remove-feed command
|
||||
|
||||
## v3.0.1
|
||||
### Fixed
|
||||
- Fixed nicknamed bot not responding to users on android
|
||||
- Fixed "playing" message including "https://" in front of site url
|
||||
|
||||
## v3.0.0
|
||||
### Added
|
||||
- Significantly more debug logging
|
||||
- Fancy new @bot help command
|
||||
|
||||
### Updatd
|
||||
- Significant back-end updates
|
||||
- Commands now invoked with an @mention to the bot
|
||||
- Updated error handling for Discord API errors
|
||||
- Removed "Body is not RSS or ATOM" error from being console logged
|
||||
- These seem to happen quite a lot, but don't actually impair the functionality, so just cause un-necessary spam
|
||||
- Removed "command not recognised" response, it caused 'fake' errors if multiple bots being run off the same token
|
||||
|
||||
### Fixed
|
||||
- Fixed full and short youtube urls not being properly converted
|
||||
- Fixed "multiple instance" issue
|
||||
- Fixed a couple of occasional memory leaks
|
||||
|
||||
## v2.0.0-b1
|
||||
|
||||
### Added
|
||||
- Multi-guild support
|
||||
- In-chat commands for setup and configuration
|
||||
|
@ -25,47 +122,35 @@
|
|||
- Remove an existing feed
|
||||
|
||||
### Updated
|
||||
|
||||
- Make save file configurable to allow use as a module with other bots
|
||||
- Update config file structure
|
||||
- Now uses discord.js instead of discord.io
|
||||
- YouTube links automatically handled; no more separate "YouTube mode" config item
|
||||
|
||||
### Fixed
|
||||
|
||||
- Crash if trying to view feeds list before any feeds have been set up
|
||||
|
||||
## v1.4.0
|
||||
|
||||
### Added
|
||||
|
||||
- Support for posting links from multiple feeds
|
||||
- Tagging of separate roles for each feed being checked
|
||||
|
||||
### Updated
|
||||
|
||||
- Updated bot connection code to use my discord-bot-wrapper
|
||||
|
||||
### Removed
|
||||
|
||||
- !logsplease command removed as the OTT logging was just being annoying
|
||||
|
||||
## v1.3.2
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed list posting channel messages being ignored
|
||||
|
||||
## v1.3.1
|
||||
|
||||
### Fixed
|
||||
|
||||
- Developer commands can now be used from any channel or PM
|
||||
|
||||
## v1.3.0
|
||||
|
||||
### Added
|
||||
|
||||
- Deletion of "You have successfully subscribed" messages after a short delay (configurable)
|
||||
- 'Developer' commands that can only be accessed by specified users
|
||||
- !cacheList developer command to view the cached URLs
|
||||
|
@ -78,44 +163,34 @@
|
|||
- The role is mentioned when the link is posted, rather than a long chain of user IDs
|
||||
|
||||
## v1.2.1
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed multiple users being unsubscribed when one user unsubscribes
|
||||
|
||||
## v1.2.0
|
||||
|
||||
### Added
|
||||
|
||||
- Chat message/command to request a list of subscribed users
|
||||
- The ability for users to 'subscribe' so they are tagged whenever a new link is posted
|
||||
- Logging to a file
|
||||
- Ability for user to request an upload of the logs file
|
||||
|
||||
### Updated
|
||||
|
||||
- Added basic spam reduction when logging so the same message won't get logged multiple times in a row
|
||||
- Refactored a bunch of code to improve efficiency
|
||||
- Updated timer logic to only ever use a single timer, and share it between posting and reconnecting
|
||||
|
||||
## v1.1.2
|
||||
|
||||
### Updated
|
||||
- Updated reconnect logic to hopefully be more stable
|
||||
|
||||
## v1.1.1
|
||||
|
||||
### Added
|
||||
- Reconnect timer to repeatedly try reconnect at intervals
|
||||
|
||||
### Updated
|
||||
|
||||
- Updated support for https conversion to http to hopefully be more consistent
|
||||
|
||||
## v1.1.0
|
||||
|
||||
### Added
|
||||
|
||||
- Added togglable YouTube mode
|
||||
- Converts full URLs to YouTube share URLs
|
||||
- Checks against both YouTube full and share URLs to ensure same video not posted twice
|
||||
|
@ -126,4 +201,4 @@
|
|||
- Changed expected name for bot config file to bot-config.json rather than botConfig.json
|
||||
|
||||
### Fixed
|
||||
- New timer being created every time the bot reconnected
|
||||
- New timer being created every time the bot reconnected
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2017 Benjamin Higgins
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
33
README.md
33
README.md
|
@ -1,4 +1,4 @@
|
|||
# Discord rss bot
|
||||
# Discord RSS Bot
|
||||
|
||||
<!--summary-->
|
||||
Posts the latest URLs from an RSS feed, optionally @mention-ing a role when posted
|
||||
|
@ -18,46 +18,48 @@ Posts the latest URLs from an RSS feed, optionally @mention-ing a role when post
|
|||
## Invite
|
||||
|
||||
By inviting this bot to your server you agree to the [terms and conditions](#privacy-statement) laid out in the privacy section of this document.
|
||||
If you agree, invite to your server with [this link](https://discordapp.com/oauth2/authorize?client_id=343909688045469698&scope=bot&permissions=0x00010c00).
|
||||
~~If you agree, invite to your server with this link~~.
|
||||
*Temporarily unavailable due to scaling issues and the large amount of attention recently.*
|
||||
|
||||
## Setup
|
||||
|
||||
You can ask the bot for help with commands by typing `@RSS_Bot help`
|
||||
You can ask the bot for help with commands by typing `@RSS Bot help`
|
||||
|
||||
### Add a new feed
|
||||
|
||||
`@RSS_Bot add-feed <url> <#channel> [@role]`
|
||||
`@RSS Bot add-feed <url> <#channel> [@role]`
|
||||
- *url* must be an RSS feed URL
|
||||
- *#channel* must be a channel mention
|
||||
- *@role* must be a role mention (make sure "Anyone can mention this role" is turned on during setup)
|
||||
|
||||
Example:
|
||||
`@RSS_Bot add-feed http://lorem-rss.herokuapp.com/feed?unit=second&interval=30 #rss-posts @subscribers`
|
||||
`@RSS Bot add-feed http://lorem-rss.herokuapp.com/feed?unit=second&interval=30 #rss-posts @subscribers`
|
||||
|
||||
### View feeds configured for this server
|
||||
|
||||
`@RSS_Bot view-feeds`
|
||||
`@RSS Bot view-feeds`
|
||||
This will display a list of RSS feeds configured for this server, along with a unique ID for each
|
||||
|
||||
### Remove a configured feed
|
||||
|
||||
`@RSS_Bot remove-feed <feed-id>`
|
||||
`@RSS Bot remove-feed <feed-id>`
|
||||
|
||||
To remove a feed you will need it's unique ID, which you can find by running the above *view-feeds* command
|
||||
|
||||
Example:
|
||||
`@RSS_Bot remove-feed ABc-123dEF`
|
||||
`@RSS Bot remove-feed ABc-123dEF`
|
||||
|
||||
## Permissions
|
||||
|
||||
The bot requires certain permissions, which you are prompted for on the invite screen.
|
||||
Each permission has a reason for being required, explained below.
|
||||
|
||||
| Permission | Reason |
|
||||
|----------------------|-------------------------------------------------------------|
|
||||
| Read messages | Detect when you use commands |
|
||||
| Send messages | Respond when you use commands; post new RSS links |
|
||||
| Read message history | Check if any new RSS links have been posted during downtime |
|
||||
| Permission | Reason |
|
||||
|----------------------|--------------------------------------------------------------|
|
||||
| Read messages | Detect when you use commands |
|
||||
| Send messages | Respond when you use commands; post new RSS links |
|
||||
| Read message history | Check if any new RSS links have been posted during downtime |
|
||||
| Embed links | Responses to 'help' requests use message embeds for nice formatting |
|
||||
|
||||
## Privacy statement
|
||||
|
||||
|
@ -78,9 +80,12 @@ Should you wish for the data stored about your server to be removed, please cont
|
|||
1. Clone the repository, or download and extract the zip file (preferrably from the release page)
|
||||
2. Make sure you have *npm* and *git* installed
|
||||
3. Run `npm install`
|
||||
4. Add *token.json* in the root folder: `{ "token": "your-token-goes-here" }`
|
||||
4. Add *token.json* in the root folder (make sure to include the quotes ""): `"your-token-goes-here"`
|
||||
5. Run `npm start`
|
||||
|
||||
**Note for git users**
|
||||
If you cloned the repository with git, make sure you `git reset --hard vX.Y` to a specific version, as latest master isn't always production ready!
|
||||
|
||||
## Need help?
|
||||
|
||||
I am available for contact via my [support Discord server](https://discordapp.com/invite/SSkbwSJ). I will always do my best to respond, however I am often busy so can't always be available right away, and as this is a free service I may not always be able to resolve your query.
|
||||
|
|
108
app/bot.js
108
app/bot.js
|
@ -1,108 +0,0 @@
|
|||
//external lib imports
|
||||
const GetUrls = require("get-urls"); //for extracting urls from messages
|
||||
|
||||
//my imports
|
||||
const DiscordUtil = require("discordjs-util");
|
||||
|
||||
//app component imports
|
||||
const GuildData = require("./models/guild-data.js");
|
||||
const FeedData = require("./models/feed-data.js");
|
||||
|
||||
module.exports = {
|
||||
onReady(client, guildsData, config) {
|
||||
return new Promise((resolve, reject) => {
|
||||
parseLinksInGuilds(client.guilds, guildsData)
|
||||
.then(() => checkFeedsInGuilds(client.guilds, guildsData))
|
||||
.then(() => setInterval(() => checkFeedsInGuilds(client.guilds, guildsData), config.feedCheckIntervalSec * 1000)); //set up an interval to check all the feeds
|
||||
});
|
||||
},
|
||||
onCommand(commandObj, commandsObj, params, guildData, message, config, client, botName) {
|
||||
switch (commandObj.command) {
|
||||
case commandsObj.addFeed.command:
|
||||
return addFeed(client, guildData, message, config.maxCacheSize);
|
||||
case commandsObj.removeFeed.command:
|
||||
return removeFeed(guildData, message, botName);
|
||||
case commandsObj.viewFeeds.command:
|
||||
return viewFeeds(guildData);
|
||||
}
|
||||
},
|
||||
onNonCommandMsg(message, guildData) {
|
||||
guildData.feeds.forEach(feedData => {
|
||||
if (message.channel.name === feedData.channelName)
|
||||
feedData.cachedLinks.push(...GetUrls(message.content)); //spread the urlSet returned by GetUrls into the cache array
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function addFeed(client, guildData, message, maxCacheSize) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const feedUrl = [...GetUrls(message.content)][0];
|
||||
const channel = message.mentions.channels.first();
|
||||
|
||||
if (!feedUrl || !channel)
|
||||
reject("Please provide both a channel and an RSS feed URL. You can optionally @mention a role also.");
|
||||
|
||||
const role = message.mentions.roles.first();
|
||||
|
||||
const feedData = new FeedData({
|
||||
url: feedUrl,
|
||||
channelName: channel.name,
|
||||
roleName: role ? role.name : null,
|
||||
maxCacheSize: maxCacheSize
|
||||
});
|
||||
|
||||
//ask the user if they're happy with the details they set up, save if yes, don't if no
|
||||
DiscordUtil.ask(client, message.channel, message.member, "Are you happy with this?\n" + feedData.toString())
|
||||
.then(responseMessage => {
|
||||
|
||||
//if they responded yes, save the feed and let them know, else tell them to start again
|
||||
if (responseMessage.content.toLowerCase() === "yes") {
|
||||
if (!guildData)
|
||||
guildData = new GuildData({ id: message.guild.id, feeds: [] });
|
||||
|
||||
guildData.feeds.push(feedData);
|
||||
resolve("Your new feed has been saved!");
|
||||
}
|
||||
else
|
||||
reject("Your feed has not been saved, please add it again with the correct details");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function removeFeed(guildData, message, botName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const parameters = message.content.split(" ");
|
||||
if (parameters.length !== 3)
|
||||
resolve(`Please use the command as such:\n\`\`\` ${botName} remove-feed feedid\`\`\``);
|
||||
else {
|
||||
const idx = guildData.feeds.findIndex(feed => feed.id === parameters[2]);
|
||||
if (!Number.isInteger(idx))
|
||||
reject("Can't find feed with id " + parameters[2]);
|
||||
else {
|
||||
guildData.feeds.splice(idx, 1);
|
||||
resolve("Feed removed!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function viewFeeds(guildData) {
|
||||
if (!guildData)
|
||||
return Promise.reject("Guild not setup");
|
||||
|
||||
return Promise.resolve(guildData.feeds.map(f => f.toString()).join("\n"));
|
||||
}
|
||||
|
||||
function checkFeedsInGuilds(guilds, guildsData) {
|
||||
Object.keys(guildsData).forEach(key => guildsData[key].checkFeeds(guilds));
|
||||
}
|
||||
|
||||
function parseLinksInGuilds(guilds, guildsData) {
|
||||
const promises = [];
|
||||
for (let guildId of guilds.keys()) {
|
||||
const guildData = guildsData[guildId];
|
||||
if (guildData)
|
||||
promises.push(guildData.cachePastPostedLinks(guilds.get(guildId)));
|
||||
}
|
||||
return Promise.all(promises);
|
||||
}
|
51
app/commands/add-feed.js
Normal file
51
app/commands/add-feed.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
const { promisify } = require("util");
|
||||
const Config = require("../config.json");
|
||||
const Core = require("../../core");
|
||||
const FeedData = require("../models/feed-data.js");
|
||||
const GetUrls = require("get-urls");
|
||||
const ShortID = require("shortid");
|
||||
|
||||
// @ts-ignore
|
||||
const readFeed = url => promisify(require("rss-parser").parseURL)(url);
|
||||
|
||||
module.exports = new Core.Command({
|
||||
name: "add-feed",
|
||||
description: "Add an RSS feed to be posted in a channel, with an optional role to tag",
|
||||
syntax: "add-feed <url> <#channel> [@role]",
|
||||
admin: true,
|
||||
invoke: invoke
|
||||
});
|
||||
|
||||
function invoke({ message, params, guildData, client }) {
|
||||
const feedUrl = [...GetUrls(message.content)][0],
|
||||
channel = message.mentions.channels.first();
|
||||
|
||||
if (!feedUrl || !channel)
|
||||
return Promise.reject("Please provide both a channel and an RSS feed URL. You can optionally @mention a role also.");
|
||||
|
||||
const role = message.mentions.roles.first(),
|
||||
feedData = FeedData.create({
|
||||
feedID: ShortID.generate(),
|
||||
url: feedUrl,
|
||||
channelID: channel.id,
|
||||
roleID: role ? role.id : null,
|
||||
maxCacheSize: Config.maxCacheSize
|
||||
});
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
readFeed(feedUrl)
|
||||
.then(() => {
|
||||
Core.util.ask(client, message.channel, message.member, "Are you happy with this (yes/no)?\n" + feedData.toString())
|
||||
.then(responseMessage => {
|
||||
if (responseMessage.content.toLowerCase() === "yes") {
|
||||
guildData.feeds.push(feedData);
|
||||
guildData.cachePastPostedLinks(message.guild)
|
||||
.then(() => resolve("Your new feed has been saved!"));
|
||||
}
|
||||
else
|
||||
reject("Your feed has not been saved, please add it again with the correct details");
|
||||
});
|
||||
})
|
||||
.catch(err => reject(`Unable to add the feed due to the following error:\n${err.message}`));
|
||||
});
|
||||
}
|
18
app/commands/remove-feed.js
Normal file
18
app/commands/remove-feed.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
const Core = require("../../core");
|
||||
|
||||
module.exports = new Core.Command({
|
||||
name: "remove-feed",
|
||||
description: "Remove an RSS feed by it's ID",
|
||||
syntax: "remove-feed <dir>",
|
||||
admin: true,
|
||||
invoke: invoke
|
||||
});
|
||||
|
||||
function invoke({ message, params, guildData, client }) {
|
||||
const idx = guildData.feeds.findIndex(feed => feed.feedID === params[0]);
|
||||
if (!Number.isInteger(idx))
|
||||
return Promise.reject("Can't find feed with id " + params[0]);
|
||||
|
||||
guildData.feeds.splice(idx, 1);
|
||||
return Promise.resolve("Feed removed!");
|
||||
}
|
23
app/commands/view-feeds.js
Normal file
23
app/commands/view-feeds.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
const Core = require("../../core");
|
||||
const Config = require("../config.json");
|
||||
|
||||
module.exports = new Core.Command({
|
||||
name: "view-feeds",
|
||||
description: "View a list of configured feeds and their associated details",
|
||||
syntax: "view-feed",
|
||||
admin: true,
|
||||
invoke: invoke
|
||||
});
|
||||
|
||||
function invoke({ message, params, guildData, client }) {
|
||||
if (!guildData)
|
||||
return Promise.reject("Guild not setup");
|
||||
|
||||
const startIdx = params[0] ? (params[0] - 1) * Config.viewFeedsPaginationLimit : 0;
|
||||
const endIdx = startIdx + Config.viewFeedsPaginationLimit + 1;
|
||||
|
||||
let responseStr = guildData.feeds.map(f => f.toString()).slice(startIdx, endIdx).join("\n");
|
||||
if (guildData.feeds.length > endIdx)
|
||||
responseStr += `Use *view-feeds ${startIdx + 2}* to view more`;
|
||||
return Promise.resolve(responseStr || "No feeds configured");
|
||||
}
|
|
@ -1,43 +1,6 @@
|
|||
{
|
||||
"generic": {
|
||||
"saveFile": "./guilds.json",
|
||||
"saveIntervalSec": 60,
|
||||
"website": "https://benji7425.github.io",
|
||||
"discordInvite": "https://discord.gg/SSkbwSJ",
|
||||
"defaultDMResponse": "This bot does not have any handling for direct messages. To learn more or get help please visit %s, or join my Discord server here: %s"
|
||||
},
|
||||
"maxCacheSize": 100,
|
||||
"feedCheckIntervalSec": 30,
|
||||
"commands": {
|
||||
"version": {
|
||||
"command": "version",
|
||||
"description": "Returns the bot version",
|
||||
"syntax": "version",
|
||||
"admin": false
|
||||
},
|
||||
"help": {
|
||||
"command": "help",
|
||||
"description": "Display information about commands available to you",
|
||||
"syntax": "help",
|
||||
"admin": false
|
||||
},
|
||||
"addFeed": {
|
||||
"command": "add-feed",
|
||||
"description": "Add an RSS feed to be posted in a channel, with an optional role to tag",
|
||||
"syntax": "add-feed <url> <#channel> [@role]",
|
||||
"admin": true
|
||||
},
|
||||
"removeFeed": {
|
||||
"command": "remove-feed",
|
||||
"description": "Remove an RSS feed by it's ID",
|
||||
"syntax": "remove-feed <id>",
|
||||
"admin": true
|
||||
},
|
||||
"viewFeeds": {
|
||||
"command": "view-feeds",
|
||||
"description": "View a list of configured feeds and their associated details",
|
||||
"syntax": "view-feed",
|
||||
"admin": true
|
||||
}
|
||||
}
|
||||
"feedCheckInterval": 10000,
|
||||
"charLimit": 500,
|
||||
"viewFeedsPaginationLimit": 10
|
||||
}
|
163
app/index.js
163
app/index.js
|
@ -1,123 +1,74 @@
|
|||
//node imports
|
||||
const FileSystem = require("fs"); //manage files
|
||||
const Util = require("util"); //various node utilities
|
||||
const Core = require("../core");
|
||||
const GetUrls = require("get-urls");
|
||||
const GuildData = require("./models/guild-data.js");
|
||||
// @ts-ignore
|
||||
const Config = require("./config.json");
|
||||
|
||||
//external lib imports
|
||||
const Discord = require("discord.js");
|
||||
const JsonFile = require("jsonfile"); //save/load data to/from json
|
||||
const guildsIterator = (function* () {
|
||||
while (true) {
|
||||
if (client.guilds.size === 0)
|
||||
yield null;
|
||||
else
|
||||
for (let i = 0; i < client.guilds.size; i++)
|
||||
yield [...client.guilds.values()][i];
|
||||
}
|
||||
})();
|
||||
|
||||
//my imports
|
||||
const DiscordUtil = require("discordjs-util"); //some discordjs helper functions of mine
|
||||
// @ts-ignore
|
||||
const client = new Core.Client(require("../token.json"), __dirname + "/commands", GuildData);
|
||||
|
||||
//app components
|
||||
const GuildData = require("./models/guild-data.js"); //data structure for guilds
|
||||
const PackageJSON = require("../package.json"); //used to provide some info about the bot
|
||||
const Bot = require("./bot.js");
|
||||
client.on("beforeLogin", () =>
|
||||
setInterval(doGuildIteration, Config.feedCheckInterval));
|
||||
|
||||
//global vars
|
||||
let writeFile = null;
|
||||
client.on("ready", () => {
|
||||
parseLinksInGuilds().then(doGuildIteration);
|
||||
require("./legacy-upgrader.js")(); //upgrade legacy json into new database format
|
||||
});
|
||||
|
||||
//use module.exports as a psuedo "onready" function
|
||||
module.exports = (client, config = null) => {
|
||||
config = config || require("./config.json"); //load config file
|
||||
const guildsData = FileSystem.existsSync(config.generic.saveFile) ? fromJSON(JsonFile.readFileSync(config.generic.saveFile)) : {}; //read data from file, or generate new one if file doesn't exist
|
||||
client.on("message", message => {
|
||||
if (message.channel.type !== "text" || !message.member)
|
||||
return;
|
||||
|
||||
//create our writeFile function that will allow other functions to save data to json without needing access to the full guildsData or config objects
|
||||
//then set an interval to automatically save data to file
|
||||
writeFile = () => JsonFile.writeFile(config.generic.saveFile, guildsData, err => { if (err) DiscordUtil.dateError("Error writing file", err); });
|
||||
setInterval(() => writeFile(), config.generic.saveIntervalSec * 1000);
|
||||
client.guildDataModel.findOne({ guildID: message.guild.id })
|
||||
.then(guildData => guildData && cacheUrlsInMessage(message, guildData));
|
||||
});
|
||||
|
||||
//handle messages
|
||||
client.on("message", message => {
|
||||
if (message.author.id !== client.user.id) { //check the bot isn't triggering itself
|
||||
client.bootstrap();
|
||||
|
||||
//check whether we need to use DM or text channel handling
|
||||
if (message.channel.type === "dm")
|
||||
HandleMessage.dm(client, config, message);
|
||||
else if (message.channel.type === "text" && message.member)
|
||||
HandleMessage.text(client, config, message, guildsData);
|
||||
}
|
||||
});
|
||||
//INTERNAL FUNCTIONS//
|
||||
function parseLinksInGuilds() {
|
||||
const promises = [];
|
||||
|
||||
Bot.onReady(client, guildsData, config).then(() => writeFile).catch(err => DiscordUtil.dateError(err));
|
||||
};
|
||||
client.guildDataModel.find().then(guildDatas =>
|
||||
guildDatas
|
||||
.filter(guildData => client.guilds.get(guildData.guildID))
|
||||
.map(guildData => ({ guildData, guild: client.guilds.get(guildData.guildID) }))
|
||||
.forEach(({ guildData, guild }) => promises.push(guildData.cachePastPostedLinks(guild).catch()))
|
||||
);
|
||||
|
||||
const HandleMessage = {
|
||||
dm: (client, config, message) => {
|
||||
message.reply(Util.format(config.generic.defaultDMResponse, config.generic.website, config.generic.discordInvite));
|
||||
},
|
||||
text: (client, config, message, guildsData) => {
|
||||
const isCommand = message.content.startsWith(message.guild.me.toString());
|
||||
let guildData = guildsData[message.guild.id];
|
||||
|
||||
if (!guildData)
|
||||
guildData = guildsData[message.guild.id] = new GuildData({ id: message.guild.id });
|
||||
|
||||
if (isCommand) {
|
||||
const userIsAdmin = message.member.permissions.has("ADMINISTRATOR");
|
||||
const botName = "@" + (message.guild.me.nickname || client.user.username);
|
||||
|
||||
const split = message.content.toLowerCase().split(/\ +/); //split the message at whitespace
|
||||
const command = split[1]; //extract the command used
|
||||
const commandObj = config.commands[Object.keys(config.commands).find(x => config.commands[x].command.toLowerCase() === command)]; //find the matching command object
|
||||
|
||||
if (!commandObj || (!commandObj.admin && !userIsAdmin))
|
||||
return;
|
||||
|
||||
const params = split.slice(2, split.length); //extract the parameters passed for the command
|
||||
const expectedParamCount = commandObj.syntax.split(/\ +/).length - 1; //calculate the number of expected command params
|
||||
|
||||
let finalisedParams;
|
||||
if (params.length > expectedParamCount) //if we have more params than needed
|
||||
finalisedParams = params.slice(0, expectedParamCount - 1).concat([params.slice(expectedParamCount - 1, params.length).join(" ")]);
|
||||
else //else we either have exactly the right amount, or not enough
|
||||
finalisedParams = params;
|
||||
|
||||
//find which command was used and handle it
|
||||
switch (command) {
|
||||
case config.commands.version.command:
|
||||
message.reply(`${PackageJSON.name} v${PackageJSON.version}`);
|
||||
break;
|
||||
case config.commands.help.command:
|
||||
message.channel.send(createHelpEmbed(botName, config, userIsAdmin));
|
||||
break;
|
||||
default:
|
||||
if (finalisedParams.length >= expectedParamCount)
|
||||
Bot.onCommand(commandObj, config.commands, finalisedParams, guildData, message, config, client, botName)
|
||||
.then(msg => {
|
||||
message.reply(msg);
|
||||
writeFile();
|
||||
})
|
||||
.catch(err => {
|
||||
message.reply(err);
|
||||
DiscordUtil.dateError(err);
|
||||
});
|
||||
else
|
||||
message.reply(`Incorrect syntax!\n**Expected:** *${botName} ${commandObj.syntax}*\n**Need help?** *${botName} ${config.commands.help.command}*`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
Bot.onNonCommandMsg(message, guildData);
|
||||
}
|
||||
};
|
||||
|
||||
function fromJSON(json) {
|
||||
const guildsData = Object.keys(json);
|
||||
guildsData.forEach(guildID => { json[guildID] = new GuildData(json[guildID]); });
|
||||
return json;
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
function createHelpEmbed(name, config, userIsAdmin) {
|
||||
const commandsArr = Object.keys(config.commands).map(x => config.commands[x]).filter(x => userIsAdmin || !x.admin);
|
||||
function doGuildIteration() {
|
||||
const guild = guildsIterator.next().value;
|
||||
|
||||
const embed = new Discord.RichEmbed().setTitle("__Help__");
|
||||
if (guild)
|
||||
client.guildDataModel.findOne({ guildID: guild.id })
|
||||
.then(guildData => guildData && checkGuildFeeds(guild, guildData));
|
||||
}
|
||||
|
||||
commandsArr.forEach(command => {
|
||||
embed.addField(command.command, `${command.description}\n**Usage:** *${name} ${command.syntax}*${userIsAdmin && command.admin ? "\n***Admin only***" : ""}`);
|
||||
});
|
||||
function checkGuildFeeds(guild, guildData) {
|
||||
guildData.checkFeeds(guild)
|
||||
.then(values => values.some(x => x) && guildData.save());
|
||||
}
|
||||
|
||||
embed.addField("__Need more help?__", `[Visit my website](${config.generic.website}) or [Join my Discord](${config.generic.discordInvite})`, true);
|
||||
function cacheUrlsInMessage(message, guildData) {
|
||||
const anyNewLinksPosted = [];
|
||||
|
||||
return { embed };
|
||||
guildData.feeds
|
||||
.filter(feedData => message.channel.id === feedData.channelID)
|
||||
.forEach(feedData => anyNewLinksPosted.push(feedData.cache(...GetUrls(message.content))));
|
||||
|
||||
if (anyNewLinksPosted.some(x => x))
|
||||
guildData.save();
|
||||
}
|
30
app/legacy-upgrader.js
Normal file
30
app/legacy-upgrader.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
// @ts-nocheck
|
||||
const NewGuildData = require("./models/guild-data.js");
|
||||
const NewFeedData = require("./models/feed-data.js");
|
||||
const FileSystem = require("fs");
|
||||
|
||||
module.exports = function () {
|
||||
if (!FileSystem.existsSync("./guilds.json"))
|
||||
return;
|
||||
|
||||
const legacyJson = require("../guilds.json");
|
||||
|
||||
for (let guildID of Object.keys(legacyJson)) {
|
||||
const guildData = NewGuildData.create({ guildID });
|
||||
|
||||
for (let feed of legacyJson[guildID].feeds) {
|
||||
guildData.feeds.push(NewFeedData.create({
|
||||
feedID: feed.id,
|
||||
url: feed.url,
|
||||
roleID: feed.roleID,
|
||||
channelID: feed.channelID,
|
||||
cachedLinks: feed.cachedLinks,
|
||||
maxCacheSize: feed.maxCacheSize
|
||||
}));
|
||||
}
|
||||
|
||||
guildData.save();
|
||||
}
|
||||
|
||||
FileSystem.rename("./guilds.json", "./guilds.json.backup");
|
||||
};
|
|
@ -1,89 +1,137 @@
|
|||
//my imports
|
||||
const DiscordUtil = require("discordjs-util");
|
||||
// @ts-ignore
|
||||
const Config = require("../config.json");
|
||||
|
||||
//external lib imports
|
||||
const Dns = require("dns"); //for host resolution checking
|
||||
const Url = require("url"); //for url parsing
|
||||
const FeedRead = require("feed-read"); //for extracing new links from RSS feeds
|
||||
const GetUrls = require("get-urls"); //for extracting urls from messages
|
||||
const ShortID = require("shortid"); //to provide ids for each feed, allowing guilds to remove them
|
||||
const { promisify } = require("util");
|
||||
const Core = require("../../core");
|
||||
const DiscordUtil = require("../../core").util;
|
||||
const GetUrls = require("get-urls");
|
||||
const Url = require("url");
|
||||
|
||||
module.exports = class FeedData {
|
||||
constructor({ id, url, channelName, roleName, cachedLinks, maxCacheSize }) {
|
||||
this.id = id || ShortID.generate();
|
||||
this.url = url;
|
||||
this.channelName = channelName;
|
||||
this.roleName = roleName;
|
||||
this.cachedLinks = cachedLinks || [];
|
||||
this.maxCacheSize = maxCacheSize || 10;
|
||||
// @ts-ignore
|
||||
const readFeed = url => promisify(require("rss-parser").parseURL)(url);
|
||||
const resolveDns = promisify(require("dns").resolve);
|
||||
|
||||
this.cachedLinks.push = (...elements) => {
|
||||
const unique = elements
|
||||
.map(el => normaliseUrl(el)) //normalise all the urls
|
||||
.filter(el => !this.cachedLinks.includes(el)); //filter out any already cached
|
||||
Array.prototype.push.apply(this.cachedLinks, unique);
|
||||
module.exports = class FeedData extends Core.BaseEmbeddedData {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
if (this.cachedLinks.length > this.maxCacheSize)
|
||||
this.cachedLinks.splice(0, this.cachedLinks.length - this.maxCacheSize); //remove the # of elements above the max from the beginning
|
||||
};
|
||||
}
|
||||
this.feedID = "";
|
||||
this.url = "";
|
||||
this.channelID = "";
|
||||
this.roleID = "";
|
||||
this.cachedLinks = [];
|
||||
this.maxCacheSize = 100;
|
||||
|
||||
/**
|
||||
* Returns a promise providing all the links posted in the last 100 messages
|
||||
* @param {Discord.Guild} guild The guild this feed belongs to
|
||||
* @returns {Promise<string[]>} Links posted in last 100 messages
|
||||
*/
|
||||
updatePastPostedLinks(guild) {
|
||||
const channel = guild.channels.find(ch => ch.type === "text" && ch.name === this.channelName);
|
||||
// @ts-ignore
|
||||
this.schema({
|
||||
feedID: String,
|
||||
url: String,
|
||||
channelID: String,
|
||||
roleID: String,
|
||||
cachedLinks: [String],
|
||||
maxCacheSize: Number
|
||||
});
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
channel.fetchMessages({ limit: 100 })
|
||||
.then(messages => {
|
||||
new Map([...messages].reverse()).forEach(m => this.cachedLinks.push(...GetUrls(m.content))); //push all the links in each message into our links array
|
||||
resolve(this);
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
}
|
||||
cache(...elements) {
|
||||
const newArticles = elements
|
||||
.map(el => normaliseUrlForCache(el))
|
||||
.filter(el => !this._isCached(el));
|
||||
|
||||
check(guild) {
|
||||
Dns.resolve(Url.parse(this.url).host || "", err => { //check we can resolve the host, so we can throw an appropriate error if it fails
|
||||
if (err)
|
||||
DiscordUtil.dateError("Connection Error: Can't resolve host", err); //log our error if we can't resolve the host
|
||||
else
|
||||
FeedRead(this.url, (err, articles) => { //check the feed
|
||||
if (err)
|
||||
DiscordUtil.dateError(err);
|
||||
else {
|
||||
let latest = articles[0].link; //extract the latest link
|
||||
latest = normaliseUrl(latest); //standardise it a bit
|
||||
Array.prototype.push.apply(this.cachedLinks, newArticles);
|
||||
|
||||
//if we don't have it cached already, cache it and callback
|
||||
if (!this.cachedLinks.includes(latest)) {
|
||||
this.cachedLinks.push(latest);
|
||||
this.cachedLinks.splice(0, this.cachedLinks.length - this.maxCacheSize); //seeing as new links come in at the end of the array, we need to remove the old links from the beginning
|
||||
|
||||
const channel = guild.channels.find(ch => ch.type === "text" && ch.name.toLowerCase() === this.channelName.toLowerCase());
|
||||
const role = this.roleName ? guild.roles.find(role => role.name.toLowerCase() === this.roleName.toLowerCase()) : null;
|
||||
channel.send((role ? role + " " : "") + latest);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return elements.length > 0;
|
||||
}
|
||||
|
||||
toString() {
|
||||
const blacklist = ["cachedLinks", "maxCacheSize"];
|
||||
return `\`\`\`JavaScript\n ${JSON.stringify(this, (k, v) => !blacklist.includes(k) ? v : undefined, "\t")} \`\`\``;
|
||||
}
|
||||
updatePastPostedLinks(guild) {
|
||||
const channel = guild.channels.get(this.channelID);
|
||||
|
||||
if (!channel)
|
||||
return Promise.reject("Channel not found!");
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
channel.fetchMessages({ limit: 100 })
|
||||
.then(messages => {
|
||||
/* we want to push the links in oldest first, but discord.js returns messages newest first, so we need to reverse them
|
||||
* discord.js returns a map, and maps don't have .reverse methods, hence needing to spread the elements into an array first */
|
||||
[...messages.values()].reverse().forEach(m => this.cache(...GetUrls(m.content)));
|
||||
resolve();
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
fetchLatest(guild) {
|
||||
const dnsPromise = resolveDns(Url.parse(this.url).host).then(() => this._doFetchRSS(guild));
|
||||
|
||||
dnsPromise.catch(err => DiscordUtil.dateDebugError("Connection error: Can't resolve host", err.message || err));
|
||||
|
||||
return dnsPromise;
|
||||
}
|
||||
|
||||
toString() {
|
||||
const blacklist = ["cachedLinks", "maxCacheSize"];
|
||||
return `\`\`\`JavaScript\n ${JSON.stringify(this, (k, v) => !blacklist.find(x => x === k) ? v : undefined, "\t")} \`\`\``;
|
||||
}
|
||||
|
||||
_isCached(url) {
|
||||
return this.cachedLinks.indexOf(normaliseUrlForCache(url)) > -1;
|
||||
}
|
||||
|
||||
_doFetchRSS(guild) {
|
||||
const feedPromise = readFeed(this.url).then(parsed => this._processLatestArticle(guild, parsed.feed.entries));
|
||||
|
||||
feedPromise.catch(err => DiscordUtil.dateDebugError([`Error reading feed ${this.url}`, err]));
|
||||
|
||||
return feedPromise;
|
||||
}
|
||||
|
||||
_processLatestArticle(guild, entries) {
|
||||
if (entries.length === 0 || !entries[0].link)
|
||||
return false;
|
||||
|
||||
if (this._isCached(entries[0].link))
|
||||
return false;
|
||||
|
||||
this.cache(entries[0].link);
|
||||
|
||||
const channel = guild.channels.get(this.channelID),
|
||||
role = guild.roles.get(this.roleID);
|
||||
|
||||
channel.send((role || "") + formatPost(entries[0]))
|
||||
.catch(err => DiscordUtil.dateDebugError(`Error posting in ${channel.id}: ${err.message || err}`));
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
function normaliseUrl(url) {
|
||||
url = url.replace("https://", "http://"); //hacky way to treat http and https the same
|
||||
function formatPost(article) {
|
||||
let message = "";
|
||||
|
||||
if (Url.parse(url).host.startsWith("http://youtu"))
|
||||
url = url.split("?")[0]; //quick way to chop off stuff like ?feature=youtube
|
||||
if (article.title) message += `\n**${article.title}**`;
|
||||
if (article.link) message += `\n\n${normaliseUrlForDiscord(article.link)}`;
|
||||
|
||||
url = url.replace(/(www.)?youtube.com\/watch\?v=/, "youtu.be/"); //convert youtube full url to short
|
||||
return message;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
function normaliseUrlForDiscord(url) {
|
||||
const parsedUrl = Url.parse(url);
|
||||
if (parsedUrl.host && parsedUrl.host.includes("youtube.com"))
|
||||
url = normaliseYouTubeUrl(url, parsedUrl);
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
function normaliseYouTubeUrl(origUrl, parsedUrl) {
|
||||
const videoIDParam = parsedUrl.query ? parsedUrl.query.split("&").find(x => x.startsWith("v=")) : null;
|
||||
if (!videoIDParam)
|
||||
return origUrl;
|
||||
const videoID = videoIDParam.substring(videoIDParam.indexOf("=") + 1, videoIDParam.length);
|
||||
return `http://youtu.be/${videoID}`
|
||||
}
|
||||
|
||||
function normaliseUrlForCache(url) {
|
||||
return normaliseUrlForDiscord(url).replace(/^((https?:\/\/)?(www.)?)/, "");
|
||||
}
|
||||
|
|
|
@ -1,23 +1,34 @@
|
|||
const Core = require("../../core");
|
||||
const FeedData = require("./feed-data.js");
|
||||
const Util = require("discordjs-util");
|
||||
|
||||
module.exports = class GuildData {
|
||||
constructor({ id, feeds }) {
|
||||
this.id = id;
|
||||
this.feeds = (feeds || []).map(feed => new FeedData(feed));
|
||||
}
|
||||
module.exports = class GuildData extends Core.BaseGuildData {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
cachePastPostedLinks(guild) {
|
||||
const promises = [];
|
||||
this.feeds = [];
|
||||
|
||||
this.feeds.forEach(feed => {
|
||||
promises.push(feed.updatePastPostedLinks(guild).catch(Util.dateError));
|
||||
});
|
||||
this.schema({
|
||||
feeds: [FeedData]
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
cachePastPostedLinks(guild) {
|
||||
return Promise.all(
|
||||
this.feeds
|
||||
.filter(feed => feedIsActive(feed, guild))
|
||||
.map(feed => feed.updatePastPostedLinks(guild).catch(err => null))
|
||||
);
|
||||
}
|
||||
|
||||
checkFeeds(guilds) {
|
||||
this.feeds.forEach(feed => feed.check(guilds.get(this.id)));
|
||||
}
|
||||
};
|
||||
checkFeeds(guild) {
|
||||
return Promise.all(
|
||||
this.feeds
|
||||
.filter(feed => feedIsActive(feed, guild))
|
||||
.map(feed => feed.fetchLatest(guild).catch(err => null))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
function feedIsActive(feed, guild) {
|
||||
return guild.channels.get(feed.channelID);
|
||||
}
|
20
bootstrap.js
vendored
20
bootstrap.js
vendored
|
@ -1,20 +0,0 @@
|
|||
const Discord = require("discord.js");
|
||||
const DiscordUtil = require("discordjs-util");
|
||||
|
||||
const client = new Discord.Client();
|
||||
|
||||
process.on("uncaughtException", (err) => {
|
||||
DiscordUtil.dateError("Uncaught exception!", err);
|
||||
});
|
||||
|
||||
client.login(require("./token.json").token);
|
||||
|
||||
client.on("ready", () => {
|
||||
DiscordUtil.dateLog("Registered bot " + client.user.username);
|
||||
require("./app/index.js")(client);
|
||||
client.user.setPresence({ game: { name: "benji7425.github.io", type: 0 } });
|
||||
});
|
||||
|
||||
client.on("disconnect", eventData => {
|
||||
DiscordUtil.dateError("Bot was disconnected!", eventData.code, eventData.reason);
|
||||
});
|
79
core/.gitignore
vendored
Normal file
79
core/.gitignore
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
### Discord bots ####
|
||||
guilds.json
|
||||
token.json
|
||||
log
|
||||
|
||||
|
||||
# Created by https://www.gitignore.io/api/node,visualstudiocode
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_cache
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
|
||||
### VisualStudioCode ###
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
.history
|
||||
|
||||
# End of https://www.gitignore.io/api/node,visualstudiocode
|
12
core/.gitrepo
Normal file
12
core/.gitrepo
Normal file
|
@ -0,0 +1,12 @@
|
|||
; DO NOT EDIT (unless you know what you are doing)
|
||||
;
|
||||
; This subdirectory is a git "subrepo", and this file is maintained by the
|
||||
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||
;
|
||||
[subrepo]
|
||||
remote = git@github.com:benji7425/discord-bot-core.git
|
||||
branch = master
|
||||
commit = 7a3eed3eff576ed51cfdfbbad18df07d4fcf52a7
|
||||
parent = 09cf5233db442fa0af452e84e90289619532418a
|
||||
method = merge
|
||||
cmdver = 0.3.1
|
2
core/.npmrc
Normal file
2
core/.npmrc
Normal file
|
@ -0,0 +1,2 @@
|
|||
save=true
|
||||
save-exact=true
|
21
core/LICENSE
Normal file
21
core/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2017 Benjamin Higgins
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
27
core/README.md
Normal file
27
core/README.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Discord bot core
|
||||
|
||||
Core code for connection and command handling for my Discord bots.
|
||||
This is not actually a Discord bot. To learn about some of my available Discord bots please visit [my website](https://benji7425.github.io/)
|
||||
This code is included in the repo for each bot using [git subrepo](https://github.com/ingydotnet/git-subrepo), which I prefer over submodules and subtrees.
|
||||
|
||||
This code does not function on it's own, it simply provides common functionality my Discord bots can make use of.
|
||||
To test/modify this code, it needs to be run in the context of an actual bot.
|
||||
A good candidate is my [template project](https://github.com/benji7425/discord-bot-template), which should run and connect just fine, just won't do much.
|
||||
|
||||
## Built with
|
||||
- [discord.js](https://discord.js.org/#/)
|
||||
- [NeDB](https://github.com/louischatriot/nedb)
|
||||
- [camo](https://github.com/scottwrobinson/camo)
|
||||
|
||||
## Contributing
|
||||
|
||||
The easiest way to get setup would be a fork of this repo, and the fork of a bot to use as a development context.
|
||||
I suggest using my [template project](https://github.com/benji7425/discord-bot-template) as a development context, along with [git subrepo](https://github.com/ingydotnet/git-subrepo) to push back to your core fork.
|
||||
If you are uncomfortable using git subrepo, you could just as easily copy/paste your child `core` directory back into your fork.
|
||||
|
||||
My [template project](https://github.com/benji7425/discord-bot-template) has more in-depth details about how to setup and test.
|
||||
|
||||
If you have a completed change, please submit a pull request from your `core` fork back to this repo.
|
||||
|
||||
Whilst this is very easy to use once you know how, I appreciate this might be a little tricky if you aren't familiar with developing in this way.
|
||||
Feel free to contact me if you would like assistance. Find contact details [here](https://benji7425.github.io/contact).
|
8
core/base-embedded-data.js
Normal file
8
core/base-embedded-data.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
const Camo = require("camo");
|
||||
|
||||
// @ts-ignore
|
||||
module.exports = class BaseEmbeddedData extends Camo.EmbeddedDocument {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
};
|
9
core/base-guild-data.js
Normal file
9
core/base-guild-data.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
const Camo = require("camo");
|
||||
|
||||
module.exports = class BaseGuildData extends Camo.Document {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.guildID = String;
|
||||
}
|
||||
};
|
83
core/client.js
Normal file
83
core/client.js
Normal file
|
@ -0,0 +1,83 @@
|
|||
const CoreUtil = require("./util.js");
|
||||
const Camo = require("camo");
|
||||
const CronJob = require("cron").CronJob;
|
||||
const Discord = require("discord.js");
|
||||
const HandleGuildMessage = require("./handle-guild-message.js");
|
||||
// @ts-ignore
|
||||
const InternalConfig = require("./internal-config.json");
|
||||
const RequireAll = require("require-all");
|
||||
|
||||
let database;
|
||||
|
||||
module.exports = class Client extends Discord.Client {
|
||||
/**
|
||||
* Construct a new Discord.Client with some added functionality
|
||||
* @param {string} token bot token
|
||||
* @param {string} commandsDir location of dir containing commands .js files
|
||||
* @param {*} guildDataModel GuildData model to be used for app; must extend BaseGuildData
|
||||
*/
|
||||
constructor(token, commandsDir, guildDataModel) {
|
||||
super({
|
||||
messageCacheMaxSize: 16,
|
||||
disabledEvents: InternalConfig.disabledEvents
|
||||
});
|
||||
|
||||
this._token = token;
|
||||
this.commandsDir = commandsDir;
|
||||
this.guildDataModel = guildDataModel;
|
||||
|
||||
this.commands = RequireAll(this.commandsDir);
|
||||
|
||||
this.on("ready", this._onReady);
|
||||
this.on("message", this._onMessage);
|
||||
this.on("debug", this._onDebug);
|
||||
this.on("guildCreate", this._onGuildCreate);
|
||||
process.on("uncaughtException", err => this._onUnhandledException(this, err));
|
||||
}
|
||||
|
||||
_onReady() {
|
||||
this.user.setGame(InternalConfig.website.replace(/^https?:\/\//, ""));
|
||||
CoreUtil.dateLog(`Registered bot ${this.user.username}`);
|
||||
}
|
||||
|
||||
_onMessage(message) {
|
||||
if (message.channel.type === "text" && message.member)
|
||||
HandleGuildMessage(this, message, this.commands);
|
||||
}
|
||||
|
||||
_onDebug(info) {
|
||||
info = info.replace(/Authenticated using token [^ ]+/, "Authenticated using token [redacted]");
|
||||
if (!InternalConfig.debugIgnores.some(x => info.startsWith(x)))
|
||||
CoreUtil.dateDebug(info);
|
||||
}
|
||||
|
||||
_onGuildCreate(guild) {
|
||||
CoreUtil.dateLog(`Added to guild ${guild.name}`);
|
||||
}
|
||||
|
||||
_onUnhandledException(client, err) {
|
||||
CoreUtil.dateError("Unhandled exception!\n", err);
|
||||
CoreUtil.dateLog("Destroying existing client...");
|
||||
client.destroy().then(() => {
|
||||
CoreUtil.dateLog("Client destroyed, recreating...");
|
||||
setTimeout(() => client.login(client._token), InternalConfig.reconnectTimeout);
|
||||
});
|
||||
}
|
||||
|
||||
bootstrap() {
|
||||
Camo.connect(InternalConfig.dbConnectionString).then(db => {
|
||||
database = db;
|
||||
|
||||
const dbProtocol = InternalConfig.dbConnectionString.match(/^(.+):\/\//)[1];
|
||||
CoreUtil.dateLog(`Database protocol: ${dbProtocol}`);
|
||||
|
||||
if (dbProtocol === "nedb") {
|
||||
CoreUtil.dateLog(`Seting up NeDB collection compaction cron job; schedule: ${InternalConfig.neDBCompactionSchedule}`);
|
||||
new CronJob(InternalConfig.neDBCompactionSchedule, () => database.compactCollectionFiles(), null, true);
|
||||
}
|
||||
|
||||
this.emit("beforeLogin");
|
||||
this.login(this._token);
|
||||
});
|
||||
}
|
||||
};
|
15
core/command.js
Normal file
15
core/command.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
module.exports = class Command {
|
||||
constructor({ name, description, syntax, admin, invoke }) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.syntax = syntax;
|
||||
this.admin = admin;
|
||||
this.invoke = invoke;
|
||||
|
||||
const params = this.syntax.split(/ +/);
|
||||
const optionalParams = params.filter(x => x.match(/^\[.+\]$/));
|
||||
|
||||
this.maxParamCount = params.length - 1;
|
||||
this.expectedParamCount = this.maxParamCount - optionalParams.length;
|
||||
}
|
||||
};
|
30
core/commands/help.js
Normal file
30
core/commands/help.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
const Command = require("../command.js");
|
||||
const Discord = require("discord.js");
|
||||
const InternalConfig = require("../internal-config.json");
|
||||
const ParentPackageJson = require("../../package.json");
|
||||
|
||||
module.exports = new Command({
|
||||
name: "help",
|
||||
description: "Display available commands with descriptions",
|
||||
syntax: "help",
|
||||
admin: false,
|
||||
invoke
|
||||
});
|
||||
|
||||
function invoke({ commands, isMemberAdmin, client }) {
|
||||
return Promise.resolve(createHelpEmbed(ParentPackageJson.name, commands, isMemberAdmin, client.user.username));
|
||||
}
|
||||
|
||||
function createHelpEmbed(name, commands, userIsAdmin, username) {
|
||||
const commandsArr = Object.keys(commands).map(x => commands[x]).filter(x => userIsAdmin || !x.admin);
|
||||
|
||||
const embed = new Discord.RichEmbed().setTitle(`__${(ParentPackageJson.name + "").replace("discord-bot-", "")} help__`);
|
||||
|
||||
commandsArr.forEach(command => {
|
||||
embed.addField(command.name, `${command.description}\n**Usage:** *@${username} ${command.syntax}*${userIsAdmin && command.admin ? "\n***Admin only***" : ""}`);
|
||||
});
|
||||
|
||||
embed.addField("__Need more help?__", `[Visit my website](${InternalConfig.website}) or [Join my Discord](${InternalConfig.discordInvite})`, true);
|
||||
|
||||
return { embed };
|
||||
}
|
31
core/commands/reset.js
Normal file
31
core/commands/reset.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
const Command = require("../command.js");
|
||||
const Util = require("../util.js");
|
||||
|
||||
module.exports = new Command({
|
||||
name: "reset",
|
||||
description: "Reset all data for this Discord server. WARNING: YOU WILL LOSE ALL YOUR SETTINGS!",
|
||||
syntax: "reset",
|
||||
admin: true,
|
||||
invoke
|
||||
});
|
||||
|
||||
function invoke({ guildData, client, message }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
/* this is a very hacky way of doing this, but when using .resolve()
|
||||
the guildData object gets saved back to the database straight away,
|
||||
meaning it'd be deleted and instnantly re-created. Using .reject
|
||||
means that .save doesn't get called by the parent. Very hacky but works. */
|
||||
|
||||
Util.ask(client, message.channel, message.member, "Are you sure you want to delete all the data for this server? (yes/no)")
|
||||
.then(response => {
|
||||
if (response.toLowerCase() === "yes")
|
||||
guildData
|
||||
.delete()
|
||||
.then(() => reject("Data for this server successfully deleted"));
|
||||
else
|
||||
reject("Guild data was not deleted");
|
||||
});
|
||||
// .then(() => resolve("Data for this server successfully deleted"))
|
||||
// .catch(() => reject("Error deleting data for this server"));
|
||||
});
|
||||
}
|
31
core/commands/stats.js
Normal file
31
core/commands/stats.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
const Command = require("../command.js");
|
||||
|
||||
module.exports = new Command({
|
||||
name: "stats",
|
||||
description: "Show some stats about the bot",
|
||||
syntax: "stats",
|
||||
admin: false,
|
||||
invoke
|
||||
});
|
||||
|
||||
function invoke({ message, params, guildData, client }) {
|
||||
return Promise.resolve(`
|
||||
**Server count:** ${client.guilds.size}
|
||||
**Cached users:** ${client.users.size}
|
||||
**Uptime:** ${toHHMMSS(client.uptime)}
|
||||
`);
|
||||
}
|
||||
|
||||
function toHHMMSS(ms) {
|
||||
const secsTruncated = Math.trunc(ms / 1000); // don't forget the second param
|
||||
const hrs = Math.floor(secsTruncated / 3600);
|
||||
const mins = Math.floor((secsTruncated - (hrs * 3600)) / 60);
|
||||
const secs = secsTruncated - (hrs * 3600) - (mins * 60);
|
||||
|
||||
let hoursStr = hrs.toString(), minsStr = mins.toString(), secsStr = secs.toString();
|
||||
|
||||
if (hrs < 10) { hoursStr = "0" + hrs; }
|
||||
if (mins < 10) { minsStr = "0" + mins; }
|
||||
if (secs < 10) { secsStr = "0" + secs; }
|
||||
return hoursStr + ":" + minsStr + ":" + secsStr;
|
||||
}
|
15
core/commands/version.js
Normal file
15
core/commands/version.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
const Command = require("../command.js");
|
||||
// @ts-ignore
|
||||
const ParentPackageJson = require("../../package.json");
|
||||
|
||||
module.exports = new Command({
|
||||
name: "version",
|
||||
description: "Return version number",
|
||||
syntax: "version",
|
||||
admin: false,
|
||||
invoke
|
||||
});
|
||||
|
||||
function invoke() {
|
||||
return Promise.resolve(`${(ParentPackageJson.name + "").replace("discord-bot-", "")} v${ParentPackageJson.version}`);
|
||||
}
|
54
core/handle-guild-message.js
Normal file
54
core/handle-guild-message.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
const RequireAll = require("require-all");
|
||||
|
||||
const internalCommands = RequireAll(__dirname + "/commands");
|
||||
|
||||
function handleGuildMessage(client, message, commands) {
|
||||
if (isCommand(message))
|
||||
client.guildDataModel.findOne({ guildID: message.guild.id })
|
||||
.then(guildData =>
|
||||
handleGuildCommand(
|
||||
client,
|
||||
message,
|
||||
Object.assign({}, internalCommands, commands),
|
||||
guildData || client.guildDataModel.create({ guildID: message.guild.id })
|
||||
));
|
||||
}
|
||||
|
||||
function handleGuildCommand(client, message, commands, guildData) {
|
||||
const { botName, isMemberAdmin, params, command } = parseDetails(message, commands);
|
||||
|
||||
if (!command)
|
||||
return;
|
||||
|
||||
if (params.length < command.expectedParamCount)
|
||||
message.reply(`Incorrect syntax!\n**Expected:** *${botName} ${command.syntax}*\n**Need help?** *${botName} help*`);
|
||||
|
||||
else if (isMemberAdmin || !command.admin)
|
||||
command.invoke({ message, params, guildData, client, commands, isMemberAdmin })
|
||||
.then(response => {
|
||||
guildData.save()
|
||||
.then(() => response && message.reply(response))
|
||||
.catch(() => message.reply("Error saving"));
|
||||
})
|
||||
.catch(err => err && message.reply(err));
|
||||
}
|
||||
|
||||
function parseDetails(message, commands) {
|
||||
const split = message.content.split(/ +/);
|
||||
const commandName = Object.keys(commands).find(x =>
|
||||
/**/ commands[x].name.toLowerCase() === (split[1] || "").toLowerCase());
|
||||
|
||||
return {
|
||||
botName: "@" + (message.guild.me.nickname || message.guild.me.user.username),
|
||||
isMemberAdmin: message.member.permissions.has("ADMINISTRATOR"),
|
||||
params: split.slice(2, split.length),
|
||||
command: commands[commandName]
|
||||
};
|
||||
}
|
||||
|
||||
function isCommand(message) {
|
||||
//criteria for a command is bot being mentioned
|
||||
return new RegExp(`^<@!?${/[0-9]{18}/.exec(message.guild.me.toString())[0]}>`).exec(message.content);
|
||||
}
|
||||
|
||||
module.exports = handleGuildMessage;
|
14
core/index.js
Normal file
14
core/index.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
// @ts-ignore
|
||||
const InternalConfig = require("./internal-config.json");
|
||||
|
||||
module.exports = {
|
||||
Client: require("./client.js"),
|
||||
BaseGuildData: require("./base-guild-data.js"),
|
||||
BaseEmbeddedData: require("./base-embedded-data.js"),
|
||||
Command: require("./command.js"),
|
||||
util: require("./util.js"),
|
||||
details: {
|
||||
website: InternalConfig.website,
|
||||
discordInvite: InternalConfig.discordInvite
|
||||
}
|
||||
};
|
20
core/internal-config.json
Normal file
20
core/internal-config.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"dbConnectionString": "nedb://guilds-data",
|
||||
"neDBCompactionSchedule": "0 0 * * * *",
|
||||
"website": "https://benji7425.github.io",
|
||||
"discordInvite": "https://discord.gg/SSkbwSJ",
|
||||
"debugIgnores": [
|
||||
"[ws] [connection] Sending a heartbeat",
|
||||
"[ws] [connection] Heartbeat acknowledged"
|
||||
],
|
||||
"disabledEvents": [
|
||||
"CHANNEL_PINS_UPDATE",
|
||||
"GUILD_BAN_ADD",
|
||||
"GUILD_BAN_REMOVE",
|
||||
"PRESENCE_UPDATE",
|
||||
"TYPING_START",
|
||||
"USER_NOTE_UPDATE",
|
||||
"USER_SETTINGS_UPDATE"
|
||||
],
|
||||
"askTimeout": 60000
|
||||
}
|
476
core/package-lock.json
generated
Normal file
476
core/package-lock.json
generated
Normal file
|
@ -0,0 +1,476 @@
|
|||
{
|
||||
"name": "discord-bot-core",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "8.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.9.1.tgz",
|
||||
"integrity": "sha512-4JFGIC1RSoFngVsT5EZcL793/uRi/OJ3ilsp9DQUr4LZOaMhNM1pPrt9TqlXOnXj3h73hl6NF31v87eQAPXYTg=="
|
||||
},
|
||||
"acorn": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-1.2.2.tgz",
|
||||
"integrity": "sha1-yM4n3grMdtiW0rH6099YjZ6C8BQ="
|
||||
},
|
||||
"amdefine": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
|
||||
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
|
||||
},
|
||||
"ast-types": {
|
||||
"version": "0.8.15",
|
||||
"resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.8.15.tgz",
|
||||
"integrity": "sha1-ju8IJ/BN/w7IhXupJavj/qYZTlI="
|
||||
},
|
||||
"async": {
|
||||
"version": "0.2.10",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
|
||||
"integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E="
|
||||
},
|
||||
"async-limiter": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
|
||||
"integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg="
|
||||
},
|
||||
"base62": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/base62/-/base62-0.1.1.tgz",
|
||||
"integrity": "sha1-e0F0wvlESXU7EcJlHAg9qEGnsIQ="
|
||||
},
|
||||
"binary-search-tree": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/binary-search-tree/-/binary-search-tree-0.2.5.tgz",
|
||||
"integrity": "sha1-fbs7IQ/coIJFDa0jNMMErzm9x4Q=",
|
||||
"requires": {
|
||||
"underscore": "~1.4.4"
|
||||
}
|
||||
},
|
||||
"bson": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz",
|
||||
"integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==",
|
||||
"optional": true
|
||||
},
|
||||
"buffer-shims": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
|
||||
"integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=",
|
||||
"optional": true
|
||||
},
|
||||
"camo": {
|
||||
"version": "git+https://github.com/benji7425/camo.git#51d63d2441827b430884400f511ae911f1961727",
|
||||
"from": "git+https://github.com/benji7425/camo.git#v0.12.4",
|
||||
"requires": {
|
||||
"depd": "1.1.0",
|
||||
"lodash": "3.9.3",
|
||||
"mongodb": "^2.2.34",
|
||||
"nedb": "1.8.0"
|
||||
}
|
||||
},
|
||||
"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="
|
||||
},
|
||||
"cron": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/cron/-/cron-1.3.0.tgz",
|
||||
"integrity": "sha512-K/SF7JlgMmNjcThWxkKvsHhey2EDB4CeOEWJ9aXWj3fbQJppsvTPIeyLdHfNq5IbbsMUUjRW1nr5dSO95f2E4w==",
|
||||
"requires": {
|
||||
"moment-timezone": "^0.5.x"
|
||||
}
|
||||
},
|
||||
"depd": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz",
|
||||
"integrity": "sha1-4b2Cxqq2ztlluXuIsX7T5SjKGMM="
|
||||
},
|
||||
"discord.js": {
|
||||
"version": "11.2.0",
|
||||
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-11.2.0.tgz",
|
||||
"integrity": "sha1-qt3iuGtpuQUWa4O8Sc/ENSOOGus=",
|
||||
"requires": {
|
||||
"long": "^3.2.0",
|
||||
"prism-media": "^0.0.1",
|
||||
"snekfetch": "^3.3.0",
|
||||
"tweetnacl": "^1.0.0",
|
||||
"ws": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"es3ify": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/es3ify/-/es3ify-0.1.4.tgz",
|
||||
"integrity": "sha1-rZ+l3xrjTz8x4SEbWBiy1RB439E=",
|
||||
"requires": {
|
||||
"esprima-fb": "~3001.0001.0000-dev-harmony-fb",
|
||||
"jstransform": "~3.0.0",
|
||||
"through": "~2.3.4"
|
||||
}
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz",
|
||||
"integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=",
|
||||
"optional": true
|
||||
},
|
||||
"esmangle-evaluator": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esmangle-evaluator/-/esmangle-evaluator-1.0.1.tgz",
|
||||
"integrity": "sha1-Yg2GbvSGGzMR91dm1SqFcrs8YzY="
|
||||
},
|
||||
"esprima-fb": {
|
||||
"version": "3001.1.0-dev-harmony-fb",
|
||||
"resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-3001.0001.0000-dev-harmony-fb.tgz",
|
||||
"integrity": "sha1-t303q8046gt3Qmu4vCkizmtCZBE="
|
||||
},
|
||||
"falafel": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/falafel/-/falafel-1.2.0.tgz",
|
||||
"integrity": "sha1-wY0k71CRF0pJfzGM0ksCaiXN2rQ=",
|
||||
"requires": {
|
||||
"acorn": "^1.0.3",
|
||||
"foreach": "^2.0.5",
|
||||
"isarray": "0.0.1",
|
||||
"object-keys": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"foreach": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
|
||||
"integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
|
||||
},
|
||||
"immediate": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"inline-process-browser": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/inline-process-browser/-/inline-process-browser-1.0.0.tgz",
|
||||
"integrity": "sha1-RqYbFT3TybFiSxoAYm7bT39BTyI=",
|
||||
"requires": {
|
||||
"falafel": "^1.0.1",
|
||||
"through2": "^0.6.5"
|
||||
}
|
||||
},
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||
},
|
||||
"jstransform": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jstransform/-/jstransform-3.0.0.tgz",
|
||||
"integrity": "sha1-olkats7o2XvzvoMNv6IxO4fNZAs=",
|
||||
"requires": {
|
||||
"base62": "0.1.1",
|
||||
"esprima-fb": "~3001.1.0-dev-harmony-fb",
|
||||
"source-map": "0.1.31"
|
||||
}
|
||||
},
|
||||
"lie": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/lie/-/lie-3.0.2.tgz",
|
||||
"integrity": "sha1-/9oh17uibzd8rYZdNkmy/Izjn+o=",
|
||||
"requires": {
|
||||
"es3ify": "^0.1.3",
|
||||
"immediate": "~3.0.5",
|
||||
"inline-process-browser": "^1.0.0",
|
||||
"unreachable-branch-transform": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"localforage": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.5.5.tgz",
|
||||
"integrity": "sha1-VfwcOoikf2f1+sbxIxsl/xNVZCM=",
|
||||
"requires": {
|
||||
"lie": "3.0.2"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "3.9.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.9.3.tgz",
|
||||
"integrity": "sha1-AVnoaDL+/8bWHYUrEqlTuZSWvTI="
|
||||
},
|
||||
"long": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz",
|
||||
"integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s="
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.19.3",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.19.3.tgz",
|
||||
"integrity": "sha1-vbmdJw1tf9p4zA+6zoVeJ/59pp8="
|
||||
},
|
||||
"moment-timezone": {
|
||||
"version": "0.5.14",
|
||||
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.14.tgz",
|
||||
"integrity": "sha1-TrOP+VOLgBCLpGekWPPtQmjM/LE=",
|
||||
"requires": {
|
||||
"moment": ">= 2.9.0"
|
||||
}
|
||||
},
|
||||
"mongodb": {
|
||||
"version": "2.2.35",
|
||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.35.tgz",
|
||||
"integrity": "sha512-3HGLucDg/8EeYMin3k+nFWChTA85hcYDCw1lPsWR6yV9A6RgKb24BkLiZ9ySZR+S0nfBjWoIUS7cyV6ceGx5Gg==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"es6-promise": "3.2.1",
|
||||
"mongodb-core": "2.1.19",
|
||||
"readable-stream": "2.2.7"
|
||||
}
|
||||
},
|
||||
"mongodb-core": {
|
||||
"version": "2.1.19",
|
||||
"resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.19.tgz",
|
||||
"integrity": "sha512-Jt4AtWUkpuW03kRdYGxga4O65O1UHlFfvvInslEfLlGi+zDMxbBe3J2NVmN9qPJ957Mn6Iz0UpMtV80cmxCVxw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"bson": "~1.0.4",
|
||||
"require_optional": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"nedb": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/nedb/-/nedb-1.8.0.tgz",
|
||||
"integrity": "sha1-DjUCzYLABNU1WkPJ5VV3vXvZHYg=",
|
||||
"requires": {
|
||||
"async": "0.2.10",
|
||||
"binary-search-tree": "0.2.5",
|
||||
"localforage": "^1.3.0",
|
||||
"mkdirp": "~0.5.1",
|
||||
"underscore": "~1.4.4"
|
||||
}
|
||||
},
|
||||
"object-keys": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
|
||||
"integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0="
|
||||
},
|
||||
"parent-package-json": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parent-package-json/-/parent-package-json-2.0.1.tgz",
|
||||
"integrity": "sha1-SbVUqeLcyu1F1+GiXqjOyde7axI="
|
||||
},
|
||||
"prism-media": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/prism-media/-/prism-media-0.0.1.tgz",
|
||||
"integrity": "sha1-o0JcnKvVDRxsAuVDlBoRiVZnvRA="
|
||||
},
|
||||
"private": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
|
||||
"integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg=="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
|
||||
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
|
||||
"optional": true
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.2.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz",
|
||||
"integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"buffer-shims": "~1.0.0",
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~1.0.6",
|
||||
"string_decoder": "~1.0.0",
|
||||
"util-deprecate": "~1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"optional": true
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
|
||||
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"recast": {
|
||||
"version": "0.10.43",
|
||||
"resolved": "https://registry.npmjs.org/recast/-/recast-0.10.43.tgz",
|
||||
"integrity": "sha1-uV1Q9tYHYaX2JS4V2AZ4FoSRzn8=",
|
||||
"requires": {
|
||||
"ast-types": "0.8.15",
|
||||
"esprima-fb": "~15001.1001.0-dev-harmony-fb",
|
||||
"private": "~0.1.5",
|
||||
"source-map": "~0.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"esprima-fb": {
|
||||
"version": "15001.1001.0-dev-harmony-fb",
|
||||
"resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz",
|
||||
"integrity": "sha1-Q761fsJujPI3092LM+QlM1d/Jlk="
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
|
||||
}
|
||||
}
|
||||
},
|
||||
"require-all": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/require-all/-/require-all-2.2.0.tgz",
|
||||
"integrity": "sha1-tEIMIzrAKC0P9Jsnf7iAqLXeCJQ="
|
||||
},
|
||||
"require_optional": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
|
||||
"integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"resolve-from": "^2.0.0",
|
||||
"semver": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"resolve-from": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
|
||||
"integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=",
|
||||
"optional": true
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||
"integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM="
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
||||
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
|
||||
"optional": true
|
||||
},
|
||||
"simple-file-writer": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-file-writer/-/simple-file-writer-2.0.0.tgz",
|
||||
"integrity": "sha1-4oPAoghoptQhnX7aGUwe9eK1gvo="
|
||||
},
|
||||
"snekfetch": {
|
||||
"version": "3.6.1",
|
||||
"resolved": "https://registry.npmjs.org/snekfetch/-/snekfetch-3.6.1.tgz",
|
||||
"integrity": "sha512-aLEvf1YR440pINb0LEo/SL2Q2s/A26+YEqPlx09A0XpGH7qWp8iqIFFolVILHn2yudWXJne9QWyQu+lzDp+ksQ=="
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.1.31",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.31.tgz",
|
||||
"integrity": "sha1-n3BNDWnZ4TioG63267T94z0VHGE=",
|
||||
"requires": {
|
||||
"amdefine": ">=0.0.4"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
},
|
||||
"through": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
|
||||
},
|
||||
"through2": {
|
||||
"version": "0.6.5",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
|
||||
"integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
|
||||
"requires": {
|
||||
"readable-stream": ">=1.0.33-1 <1.1.0-0",
|
||||
"xtend": ">=4.0.0 <4.1.0-0"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.0.tgz",
|
||||
"integrity": "sha1-cT2LgY2kIGh0C/aDhtBHnmb8ins="
|
||||
},
|
||||
"ultron": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
|
||||
"integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
|
||||
},
|
||||
"underscore": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz",
|
||||
"integrity": "sha1-YaajIBBiKvoHljvzJSA88SI51gQ="
|
||||
},
|
||||
"unreachable-branch-transform": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/unreachable-branch-transform/-/unreachable-branch-transform-0.3.0.tgz",
|
||||
"integrity": "sha1-2ZzExudG0mSSiEW2EdtUsPNHTKo=",
|
||||
"requires": {
|
||||
"esmangle-evaluator": "^1.0.0",
|
||||
"recast": "^0.10.1",
|
||||
"through2": "^0.6.2"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"optional": true
|
||||
},
|
||||
"ws": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.2.tgz",
|
||||
"integrity": "sha512-t+WGpsNxhMR4v6EClXS8r8km5ZljKJzyGhJf7goJz9k5Ye3+b5Bvno5rjqPuIBn5mnn5GBb7o8IrIWHxX1qOLQ==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0",
|
||||
"safe-buffer": "~5.1.0",
|
||||
"ultron": "~1.1.0"
|
||||
}
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
|
||||
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
|
||||
}
|
||||
}
|
||||
}
|
26
core/package.json
Normal file
26
core/package.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@types/node": "8.9.1",
|
||||
"camo": "git+https://github.com/benji7425/camo.git#v0.12.4",
|
||||
"cron": "1.3.0",
|
||||
"discord.js": "11.2.0",
|
||||
"nedb": "1.8.0",
|
||||
"parent-package-json": "2.0.1",
|
||||
"require-all": "2.2.0",
|
||||
"simple-file-writer": "2.0.0"
|
||||
},
|
||||
"name": "discord-bot-core",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/benji7425/discord-bot-core.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/benji7425/discord-bot-core/issues"
|
||||
},
|
||||
"homepage": "https://github.com/benji7425/discord-bot-core#readme",
|
||||
"description": "Core code shared amongst my Discord bots"
|
||||
}
|
74
core/util.js
Normal file
74
core/util.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
// @ts-ignore
|
||||
const InternalConfig = require("./internal-config.json");
|
||||
const Console = require("console");
|
||||
const SimpleFileWriter = require("simple-file-writer");
|
||||
|
||||
const logWriter = new SimpleFileWriter("./console.log");
|
||||
const debugLogWriter = new SimpleFileWriter("./debug.log");
|
||||
|
||||
function ask(client, textChannel, member, question) {
|
||||
//return a promise which will resolve once the user next sends a message in this textChannel
|
||||
return new Promise((resolve, reject) => {
|
||||
const cancelAsk = () => {
|
||||
client.removeListener("message", handler);
|
||||
textChannel.send("Response to question timed out");
|
||||
};
|
||||
|
||||
const askTimeout = setTimeout(cancelAsk, InternalConfig.askTimeout);
|
||||
|
||||
const handler = responseMessage => {
|
||||
if (responseMessage.channel.id === textChannel.id && responseMessage.member && responseMessage.member.id === member.id) {
|
||||
clearTimeout(askTimeout);
|
||||
resolve(responseMessage);
|
||||
}
|
||||
};
|
||||
|
||||
client.on("message", handler);
|
||||
|
||||
textChannel.send(member.toString() + " " + question).catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
function dateLog(...args) {
|
||||
doDateLog(Console.log, logWriter, args, "INFO");
|
||||
}
|
||||
|
||||
function dateError(...args) {
|
||||
doDateLog(Console.error, logWriter, args, "ERROR");
|
||||
}
|
||||
|
||||
function dateDebugError(...args) {
|
||||
doDateLog(null, null, args, "DEBUG ERROR");
|
||||
}
|
||||
|
||||
function dateDebug(...args) {
|
||||
doDateLog(null, null, args, "DEBUG");
|
||||
}
|
||||
|
||||
function doDateLog(consoleMethod, fileWriter, args, prefix = "") {
|
||||
args = formatArgs([`[${prefix}]`].concat(args));
|
||||
|
||||
if (consoleMethod !== null)
|
||||
consoleMethod.apply(this, args);
|
||||
|
||||
if (fileWriter !== null)
|
||||
fileWriter.write(formatArgsForFile(args));
|
||||
|
||||
debugLogWriter.write(formatArgsForFile(args));
|
||||
}
|
||||
|
||||
function formatArgs(args) {
|
||||
return [`[${new Date().toUTCString()}]`].concat(args);
|
||||
}
|
||||
|
||||
function formatArgsForFile(args) {
|
||||
return args.join(" ") + "\n";
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
dateError,
|
||||
dateLog,
|
||||
dateDebug,
|
||||
dateDebugError,
|
||||
ask
|
||||
};
|
229
core/yarn.lock
Normal file
229
core/yarn.lock
Normal file
|
@ -0,0 +1,229 @@
|
|||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/node@8.9.1":
|
||||
version "8.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.9.1.tgz#5a329d73a97f3c5a626dfe0ed8c0b831fee5357a"
|
||||
|
||||
async-limiter@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
|
||||
|
||||
async@0.2.10:
|
||||
version "0.2.10"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1"
|
||||
|
||||
binary-search-tree@0.2.5:
|
||||
version "0.2.5"
|
||||
resolved "https://registry.yarnpkg.com/binary-search-tree/-/binary-search-tree-0.2.5.tgz#7dbb3b210fdca082450dad2334c304af39bdc784"
|
||||
dependencies:
|
||||
underscore "~1.4.4"
|
||||
|
||||
bson@~1.0.4:
|
||||
version "1.0.9"
|
||||
resolved "https://registry.yarnpkg.com/bson/-/bson-1.0.9.tgz#12319f8323b1254739b7c6bef8d3e89ae05a2f57"
|
||||
|
||||
buffer-shims@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51"
|
||||
|
||||
"camo@git+https://github.com/benji7425/camo.git#v0.12.4":
|
||||
version "0.12.4"
|
||||
resolved "git+https://github.com/benji7425/camo.git#51d63d2441827b430884400f511ae911f1961727"
|
||||
dependencies:
|
||||
depd "1.1.0"
|
||||
lodash "3.9.3"
|
||||
optionalDependencies:
|
||||
mongodb "^2.2.34"
|
||||
nedb "1.8.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"
|
||||
|
||||
cron@1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/cron/-/cron-1.3.0.tgz#7e459968eaf94e1a445be796ce402166c234659d"
|
||||
dependencies:
|
||||
moment-timezone "^0.5.x"
|
||||
|
||||
depd@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3"
|
||||
|
||||
discord.js@11.2.0:
|
||||
version "11.2.0"
|
||||
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-11.2.0.tgz#aadde2b86b69b905166b83bc49cfc435238e1aeb"
|
||||
dependencies:
|
||||
long "^3.2.0"
|
||||
prism-media "^0.0.1"
|
||||
snekfetch "^3.3.0"
|
||||
tweetnacl "^1.0.0"
|
||||
ws "^3.1.0"
|
||||
|
||||
es6-promise@3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.2.1.tgz#ec56233868032909207170c39448e24449dd1fc4"
|
||||
|
||||
immediate@~3.0.5:
|
||||
version "3.0.6"
|
||||
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
|
||||
|
||||
inherits@~2.0.1:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
|
||||
isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
|
||||
lie@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e"
|
||||
dependencies:
|
||||
immediate "~3.0.5"
|
||||
|
||||
localforage@^1.3.0:
|
||||
version "1.7.2"
|
||||
resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.7.2.tgz#fa4442602f806edd2bca6a54ab4e656f031f121c"
|
||||
dependencies:
|
||||
lie "3.1.1"
|
||||
|
||||
lodash@3.9.3:
|
||||
version "3.9.3"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.9.3.tgz#0159e86832feffc6d61d852b12a953b99496bd32"
|
||||
|
||||
long@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b"
|
||||
|
||||
minimist@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
|
||||
|
||||
mkdirp@~0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
||||
dependencies:
|
||||
minimist "0.0.8"
|
||||
|
||||
moment-timezone@^0.5.x:
|
||||
version "0.5.21"
|
||||
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.21.tgz#3cba247d84492174dbf71de2a9848fa13207b845"
|
||||
dependencies:
|
||||
moment ">= 2.9.0"
|
||||
|
||||
"moment@>= 2.9.0":
|
||||
version "2.22.2"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66"
|
||||
|
||||
mongodb-core@2.1.19:
|
||||
version "2.1.19"
|
||||
resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.19.tgz#00fbd5e5a3573763b9171cfd844e60a8f2a3a18b"
|
||||
dependencies:
|
||||
bson "~1.0.4"
|
||||
require_optional "~1.0.0"
|
||||
|
||||
mongodb@^2.2.34:
|
||||
version "2.2.35"
|
||||
resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.35.tgz#cd1b5af8a9463e3f9a787fa5b3d05565579730f9"
|
||||
dependencies:
|
||||
es6-promise "3.2.1"
|
||||
mongodb-core "2.1.19"
|
||||
readable-stream "2.2.7"
|
||||
|
||||
nedb@1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/nedb/-/nedb-1.8.0.tgz#0e3502cd82c004d5355a43c9e55577bd7bd91d88"
|
||||
dependencies:
|
||||
async "0.2.10"
|
||||
binary-search-tree "0.2.5"
|
||||
localforage "^1.3.0"
|
||||
mkdirp "~0.5.1"
|
||||
underscore "~1.4.4"
|
||||
|
||||
parent-package-json@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parent-package-json/-/parent-package-json-2.0.1.tgz#49b554a9e2dccaed45d7e1a25ea8cec9d7bb6b12"
|
||||
|
||||
prism-media@^0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-0.0.1.tgz#a3425c9cabd50d1c6c02e543941a11895667bd10"
|
||||
|
||||
process-nextick-args@~1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
|
||||
|
||||
readable-stream@2.2.7:
|
||||
version "2.2.7"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.7.tgz#07057acbe2467b22042d36f98c5ad507054e95b1"
|
||||
dependencies:
|
||||
buffer-shims "~1.0.0"
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.1"
|
||||
isarray "~1.0.0"
|
||||
process-nextick-args "~1.0.6"
|
||||
string_decoder "~1.0.0"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
require-all@2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/require-all/-/require-all-2.2.0.tgz#b4420c233ac0282d0ff49b277fb880a8b5de0894"
|
||||
|
||||
require_optional@~1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/require_optional/-/require_optional-1.0.1.tgz#4cf35a4247f64ca3df8c2ef208cc494b1ca8fc2e"
|
||||
dependencies:
|
||||
resolve-from "^2.0.0"
|
||||
semver "^5.1.0"
|
||||
|
||||
resolve-from@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57"
|
||||
|
||||
safe-buffer@~5.1.0:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||
|
||||
semver@^5.1.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
|
||||
|
||||
simple-file-writer@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/simple-file-writer/-/simple-file-writer-2.0.0.tgz#e283c0a20868a6d4219d7eda194c1ef5e2b582fa"
|
||||
|
||||
snekfetch@^3.3.0:
|
||||
version "3.6.4"
|
||||
resolved "https://registry.yarnpkg.com/snekfetch/-/snekfetch-3.6.4.tgz#d13e80a616d892f3d38daae4289f4d258a645120"
|
||||
|
||||
string_decoder@~1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
tweetnacl@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.0.tgz#713d8b818da42068740bf68386d0479e66fc8a7b"
|
||||
|
||||
ultron@~1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
|
||||
|
||||
underscore@~1.4.4:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604"
|
||||
|
||||
util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
|
||||
ws@^3.1.0:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2"
|
||||
dependencies:
|
||||
async-limiter "~1.0.0"
|
||||
safe-buffer "~5.1.0"
|
||||
ultron "~1.1.0"
|
1329
package-lock.json
generated
Normal file
1329
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
54
package.json
54
package.json
|
@ -1,28 +1,30 @@
|
|||
{
|
||||
"version": "3.0.0-b2",
|
||||
"main": "app/index.js",
|
||||
"scripts": {
|
||||
"start": "node bootstrap.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"discord.js": "11.1.0",
|
||||
"discordjs-util": "git+https://github.com/benji7425/discordjs-util.git",
|
||||
"feed-read": "0.0.1",
|
||||
"get-urls": "7.0.0",
|
||||
"jsonfile": "3.0.1",
|
||||
"shortid": "2.2.8"
|
||||
},
|
||||
"name": "discord-bot-rss-feed",
|
||||
"devDependencies": {},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/benji7425/discord-bot-rss-feed.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/benji7425/discord-bot-rss-feed/issues"
|
||||
},
|
||||
"homepage": "https://github.com/benji7425/discord-bot-rss-feed#readme",
|
||||
"description": ""
|
||||
"version": "3.5.2",
|
||||
"main": "app/index.js",
|
||||
"scripts": {
|
||||
"postinstall": "cd ./core && npm install",
|
||||
"start": "node ./app/index.js --name=rss-feed"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": "9.3.0",
|
||||
"discord.js": "11.2.0",
|
||||
"eslint": "4.16.0",
|
||||
"get-urls": "7.0.0",
|
||||
"jsonfile": "3.0.1",
|
||||
"rss-parser": "2.12.0",
|
||||
"shortid": "2.2.8"
|
||||
},
|
||||
"name": "discord-bot-rss-feed",
|
||||
"devDependencies": {},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/benji7425/discord-bot-rss-feed.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/benji7425/discord-bot-rss-feed/issues"
|
||||
},
|
||||
"homepage": "https://github.com/benji7425/discord-bot-rss-feed#readme",
|
||||
"description": ""
|
||||
}
|
||||
|
|
967
yarn.lock
Normal file
967
yarn.lock
Normal file
|
@ -0,0 +1,967 @@
|
|||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/node@9.3.0":
|
||||
version "9.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-9.3.0.tgz#3a129cda7c4e5df2409702626892cb4b96546dd5"
|
||||
|
||||
acorn-jsx@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
|
||||
dependencies:
|
||||
acorn "^3.0.4"
|
||||
|
||||
acorn@^3.0.4:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
|
||||
|
||||
acorn@^5.5.0:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8"
|
||||
|
||||
ajv-keywords@^3.0.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a"
|
||||
|
||||
ajv@^5.3.0:
|
||||
version "5.5.2"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
|
||||
dependencies:
|
||||
co "^4.6.0"
|
||||
fast-deep-equal "^1.0.0"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
json-schema-traverse "^0.3.0"
|
||||
|
||||
ajv@^6.0.1:
|
||||
version "6.5.2"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.2.tgz#678495f9b82f7cca6be248dd92f59bff5e1f4360"
|
||||
dependencies:
|
||||
fast-deep-equal "^2.0.1"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.1"
|
||||
|
||||
ansi-escapes@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30"
|
||||
|
||||
ansi-regex@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
|
||||
|
||||
ansi-regex@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
|
||||
|
||||
ansi-styles@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
|
||||
|
||||
ansi-styles@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
||||
dependencies:
|
||||
color-convert "^1.9.0"
|
||||
|
||||
argparse@^1.0.7:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
||||
dependencies:
|
||||
sprintf-js "~1.0.2"
|
||||
|
||||
array-union@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
|
||||
dependencies:
|
||||
array-uniq "^1.0.1"
|
||||
|
||||
array-uniq@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
|
||||
|
||||
arrify@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
|
||||
|
||||
async-limiter@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
|
||||
|
||||
babel-code-frame@^6.22.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
|
||||
dependencies:
|
||||
chalk "^1.1.3"
|
||||
esutils "^2.0.2"
|
||||
js-tokens "^3.0.2"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
buffer-from@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.0.tgz#87fcaa3a298358e0ade6e442cfce840740d1ad04"
|
||||
|
||||
caller-path@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
|
||||
dependencies:
|
||||
callsites "^0.2.0"
|
||||
|
||||
callsites@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
|
||||
|
||||
chalk@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
|
||||
dependencies:
|
||||
ansi-styles "^2.2.1"
|
||||
escape-string-regexp "^1.0.2"
|
||||
has-ansi "^2.0.0"
|
||||
strip-ansi "^3.0.0"
|
||||
supports-color "^2.0.0"
|
||||
|
||||
chalk@^2.0.0, chalk@^2.1.0:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
|
||||
dependencies:
|
||||
ansi-styles "^3.2.1"
|
||||
escape-string-regexp "^1.0.5"
|
||||
supports-color "^5.3.0"
|
||||
|
||||
chardet@^0.4.0:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
|
||||
|
||||
circular-json@^0.3.1:
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
|
||||
|
||||
cli-cursor@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
|
||||
dependencies:
|
||||
restore-cursor "^2.0.0"
|
||||
|
||||
cli-width@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
|
||||
|
||||
co@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
||||
|
||||
color-convert@^1.9.0:
|
||||
version "1.9.2"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147"
|
||||
dependencies:
|
||||
color-name "1.1.1"
|
||||
|
||||
color-name@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689"
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
|
||||
concat-stream@^1.6.0:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
|
||||
dependencies:
|
||||
buffer-from "^1.0.0"
|
||||
inherits "^2.0.3"
|
||||
readable-stream "^2.2.2"
|
||||
typedarray "^0.0.6"
|
||||
|
||||
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"
|
||||
|
||||
cross-spawn@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
|
||||
dependencies:
|
||||
lru-cache "^4.0.1"
|
||||
shebang-command "^1.2.0"
|
||||
which "^1.2.9"
|
||||
|
||||
debug@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
deep-is@~0.1.3:
|
||||
version "0.1.3"
|
||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
||||
|
||||
del@^2.0.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8"
|
||||
dependencies:
|
||||
globby "^5.0.0"
|
||||
is-path-cwd "^1.0.0"
|
||||
is-path-in-cwd "^1.0.0"
|
||||
object-assign "^4.0.1"
|
||||
pify "^2.0.0"
|
||||
pinkie-promise "^2.0.0"
|
||||
rimraf "^2.2.8"
|
||||
|
||||
discord.js@11.2.0:
|
||||
version "11.2.0"
|
||||
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-11.2.0.tgz#aadde2b86b69b905166b83bc49cfc435238e1aeb"
|
||||
dependencies:
|
||||
long "^3.2.0"
|
||||
prism-media "^0.0.1"
|
||||
snekfetch "^3.3.0"
|
||||
tweetnacl "^1.0.0"
|
||||
ws "^3.1.0"
|
||||
|
||||
doctrine@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
|
||||
entities@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
|
||||
|
||||
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
|
||||
eslint-scope@^3.7.1:
|
||||
version "3.7.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
|
||||
dependencies:
|
||||
esrecurse "^4.1.0"
|
||||
estraverse "^4.1.1"
|
||||
|
||||
eslint-visitor-keys@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
|
||||
|
||||
eslint@4.16.0:
|
||||
version "4.16.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.16.0.tgz#934ada9e98715e1d7bbfd6f6f0519ed2fab35cc1"
|
||||
dependencies:
|
||||
ajv "^5.3.0"
|
||||
babel-code-frame "^6.22.0"
|
||||
chalk "^2.1.0"
|
||||
concat-stream "^1.6.0"
|
||||
cross-spawn "^5.1.0"
|
||||
debug "^3.1.0"
|
||||
doctrine "^2.1.0"
|
||||
eslint-scope "^3.7.1"
|
||||
eslint-visitor-keys "^1.0.0"
|
||||
espree "^3.5.2"
|
||||
esquery "^1.0.0"
|
||||
esutils "^2.0.2"
|
||||
file-entry-cache "^2.0.0"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
glob "^7.1.2"
|
||||
globals "^11.0.1"
|
||||
ignore "^3.3.3"
|
||||
imurmurhash "^0.1.4"
|
||||
inquirer "^3.0.6"
|
||||
is-resolvable "^1.0.0"
|
||||
js-yaml "^3.9.1"
|
||||
json-stable-stringify-without-jsonify "^1.0.1"
|
||||
levn "^0.3.0"
|
||||
lodash "^4.17.4"
|
||||
minimatch "^3.0.2"
|
||||
mkdirp "^0.5.1"
|
||||
natural-compare "^1.4.0"
|
||||
optionator "^0.8.2"
|
||||
path-is-inside "^1.0.2"
|
||||
pluralize "^7.0.0"
|
||||
progress "^2.0.0"
|
||||
require-uncached "^1.0.3"
|
||||
semver "^5.3.0"
|
||||
strip-ansi "^4.0.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
table "^4.0.1"
|
||||
text-table "~0.2.0"
|
||||
|
||||
espree@^3.5.2:
|
||||
version "3.5.4"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7"
|
||||
dependencies:
|
||||
acorn "^5.5.0"
|
||||
acorn-jsx "^3.0.0"
|
||||
|
||||
esprima@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
|
||||
|
||||
esquery@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708"
|
||||
dependencies:
|
||||
estraverse "^4.0.0"
|
||||
|
||||
esrecurse@^4.1.0:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf"
|
||||
dependencies:
|
||||
estraverse "^4.1.0"
|
||||
|
||||
estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
|
||||
|
||||
esutils@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
|
||||
|
||||
external-editor@^2.0.4:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5"
|
||||
dependencies:
|
||||
chardet "^0.4.0"
|
||||
iconv-lite "^0.4.17"
|
||||
tmp "^0.0.33"
|
||||
|
||||
fast-deep-equal@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
|
||||
|
||||
fast-deep-equal@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
|
||||
|
||||
fast-json-stable-stringify@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
|
||||
|
||||
fast-levenshtein@~2.0.4:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||
|
||||
figures@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
|
||||
dependencies:
|
||||
escape-string-regexp "^1.0.5"
|
||||
|
||||
file-entry-cache@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361"
|
||||
dependencies:
|
||||
flat-cache "^1.2.1"
|
||||
object-assign "^4.0.1"
|
||||
|
||||
flat-cache@^1.2.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481"
|
||||
dependencies:
|
||||
circular-json "^0.3.1"
|
||||
del "^2.0.2"
|
||||
graceful-fs "^4.1.2"
|
||||
write "^0.2.1"
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
|
||||
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"
|
||||
|
||||
get-urls@7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/get-urls/-/get-urls-7.0.0.tgz#c480adc7d4c6cc5cbb64b531823dc63b99ec1e5a"
|
||||
dependencies:
|
||||
normalize-url "^1.3.0"
|
||||
url-regex "^4.0.0"
|
||||
|
||||
glob@^7.0.3, glob@^7.0.5, glob@^7.1.2:
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
|
||||
dependencies:
|
||||
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"
|
||||
|
||||
globals@^11.0.1:
|
||||
version "11.7.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673"
|
||||
|
||||
globby@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d"
|
||||
dependencies:
|
||||
array-union "^1.0.1"
|
||||
arrify "^1.0.0"
|
||||
glob "^7.0.3"
|
||||
object-assign "^4.0.1"
|
||||
pify "^2.0.0"
|
||||
pinkie-promise "^2.0.0"
|
||||
|
||||
graceful-fs@^4.1.2, graceful-fs@^4.1.6:
|
||||
version "4.1.11"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
|
||||
|
||||
has-ansi@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
|
||||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
has-flag@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
|
||||
iconv-lite@^0.4.17:
|
||||
version "0.4.23"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63"
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
ignore@^3.3.3:
|
||||
version "3.3.10"
|
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043"
|
||||
|
||||
imurmurhash@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2, inherits@^2.0.3, inherits@~2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
|
||||
inquirer@^3.0.6:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9"
|
||||
dependencies:
|
||||
ansi-escapes "^3.0.0"
|
||||
chalk "^2.0.0"
|
||||
cli-cursor "^2.1.0"
|
||||
cli-width "^2.0.0"
|
||||
external-editor "^2.0.4"
|
||||
figures "^2.0.0"
|
||||
lodash "^4.3.0"
|
||||
mute-stream "0.0.7"
|
||||
run-async "^2.2.0"
|
||||
rx-lite "^4.0.8"
|
||||
rx-lite-aggregates "^4.0.8"
|
||||
string-width "^2.1.0"
|
||||
strip-ansi "^4.0.0"
|
||||
through "^2.3.6"
|
||||
|
||||
ip-regex@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd"
|
||||
|
||||
is-fullwidth-code-point@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
|
||||
|
||||
is-path-cwd@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
|
||||
|
||||
is-path-in-cwd@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52"
|
||||
dependencies:
|
||||
is-path-inside "^1.0.0"
|
||||
|
||||
is-path-inside@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036"
|
||||
dependencies:
|
||||
path-is-inside "^1.0.1"
|
||||
|
||||
is-plain-obj@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
|
||||
|
||||
is-promise@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
|
||||
|
||||
is-resolvable@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
|
||||
|
||||
isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
|
||||
isexe@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
|
||||
js-tokens@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
|
||||
|
||||
js-yaml@^3.9.1:
|
||||
version "3.12.0"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1"
|
||||
dependencies:
|
||||
argparse "^1.0.7"
|
||||
esprima "^4.0.0"
|
||||
|
||||
json-schema-traverse@^0.3.0:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
|
||||
|
||||
json-schema-traverse@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
|
||||
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"
|
||||
|
||||
jsonfile@3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66"
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
levn@^0.3.0, levn@~0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
|
||||
dependencies:
|
||||
prelude-ls "~1.1.2"
|
||||
type-check "~0.3.2"
|
||||
|
||||
lodash@^4.17.4, lodash@^4.3.0:
|
||||
version "4.17.10"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
|
||||
|
||||
long@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b"
|
||||
|
||||
lru-cache@^4.0.1:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c"
|
||||
dependencies:
|
||||
pseudomap "^1.0.2"
|
||||
yallist "^2.1.2"
|
||||
|
||||
mimic-fn@^1.0.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
|
||||
|
||||
minimatch@^3.0.2, minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
|
||||
|
||||
mkdirp@^0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
||||
dependencies:
|
||||
minimist "0.0.8"
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
|
||||
mute-stream@0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
|
||||
|
||||
natural-compare@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
|
||||
normalize-url@^1.3.0:
|
||||
version "1.9.1"
|
||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c"
|
||||
dependencies:
|
||||
object-assign "^4.0.1"
|
||||
prepend-http "^1.0.0"
|
||||
query-string "^4.1.0"
|
||||
sort-keys "^1.0.0"
|
||||
|
||||
object-assign@^4.0.1, object-assign@^4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
once@^1.3.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
onetime@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
|
||||
dependencies:
|
||||
mimic-fn "^1.0.0"
|
||||
|
||||
optionator@^0.8.2:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
|
||||
dependencies:
|
||||
deep-is "~0.1.3"
|
||||
fast-levenshtein "~2.0.4"
|
||||
levn "~0.3.0"
|
||||
prelude-ls "~1.1.2"
|
||||
type-check "~0.3.2"
|
||||
wordwrap "~1.0.0"
|
||||
|
||||
os-tmpdir@~1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
|
||||
path-is-inside@^1.0.1, path-is-inside@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
|
||||
|
||||
pify@^2.0.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
||||
|
||||
pinkie-promise@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
|
||||
dependencies:
|
||||
pinkie "^2.0.0"
|
||||
|
||||
pinkie@^2.0.0:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
|
||||
|
||||
pluralize@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
|
||||
|
||||
prelude-ls@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
||||
|
||||
prepend-http@^1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
|
||||
|
||||
prism-media@^0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-0.0.1.tgz#a3425c9cabd50d1c6c02e543941a11895667bd10"
|
||||
|
||||
process-nextick-args@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
|
||||
|
||||
progress@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
|
||||
|
||||
pseudomap@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
|
||||
|
||||
punycode@^2.1.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
|
||||
query-string@^4.1.0:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb"
|
||||
dependencies:
|
||||
object-assign "^4.1.0"
|
||||
strict-uri-encode "^1.0.0"
|
||||
|
||||
readable-stream@^2.2.2:
|
||||
version "2.3.6"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.3"
|
||||
isarray "~1.0.0"
|
||||
process-nextick-args "~2.0.0"
|
||||
safe-buffer "~5.1.1"
|
||||
string_decoder "~1.1.1"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
require-uncached@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
|
||||
dependencies:
|
||||
caller-path "^0.1.0"
|
||||
resolve-from "^1.0.0"
|
||||
|
||||
resolve-from@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
|
||||
|
||||
restore-cursor@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
|
||||
dependencies:
|
||||
onetime "^2.0.0"
|
||||
signal-exit "^3.0.2"
|
||||
|
||||
rimraf@^2.2.8:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
|
||||
dependencies:
|
||||
glob "^7.0.5"
|
||||
|
||||
rss-parser@2.12.0:
|
||||
version "2.12.0"
|
||||
resolved "https://registry.yarnpkg.com/rss-parser/-/rss-parser-2.12.0.tgz#d8cd173aef9c1f0d66467465092bd6f99a8ec232"
|
||||
dependencies:
|
||||
entities "^1.1.1"
|
||||
xml2js "^0.4.17"
|
||||
|
||||
run-async@^2.2.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
|
||||
dependencies:
|
||||
is-promise "^2.1.0"
|
||||
|
||||
rx-lite-aggregates@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be"
|
||||
dependencies:
|
||||
rx-lite "*"
|
||||
|
||||
rx-lite@*, rx-lite@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444"
|
||||
|
||||
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||
|
||||
"safer-buffer@>= 2.1.2 < 3":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
|
||||
sax@>=0.6.0:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||
|
||||
semver@^5.3.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
|
||||
|
||||
shebang-command@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
||||
dependencies:
|
||||
shebang-regex "^1.0.0"
|
||||
|
||||
shebang-regex@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
|
||||
|
||||
shortid@2.2.8:
|
||||
version "2.2.8"
|
||||
resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.8.tgz#033b117d6a2e975804f6f0969dbe7d3d0b355131"
|
||||
|
||||
signal-exit@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
||||
|
||||
slice-ansi@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d"
|
||||
dependencies:
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
|
||||
snekfetch@^3.3.0:
|
||||
version "3.6.4"
|
||||
resolved "https://registry.yarnpkg.com/snekfetch/-/snekfetch-3.6.4.tgz#d13e80a616d892f3d38daae4289f4d258a645120"
|
||||
|
||||
sort-keys@^1.0.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad"
|
||||
dependencies:
|
||||
is-plain-obj "^1.0.0"
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
|
||||
strict-uri-encode@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
|
||||
|
||||
string-width@^2.1.0, string-width@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
|
||||
dependencies:
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
strip-ansi "^4.0.0"
|
||||
|
||||
string_decoder@~1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
strip-ansi@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
||||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
strip-ansi@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
|
||||
dependencies:
|
||||
ansi-regex "^3.0.0"
|
||||
|
||||
strip-json-comments@~2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||
|
||||
striptags@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/striptags/-/striptags-3.1.1.tgz#c8c3e7fdd6fb4bb3a32a3b752e5b5e3e38093ebd"
|
||||
|
||||
supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
|
||||
supports-color@^5.3.0:
|
||||
version "5.4.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54"
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
table@^4.0.1:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc"
|
||||
dependencies:
|
||||
ajv "^6.0.1"
|
||||
ajv-keywords "^3.0.0"
|
||||
chalk "^2.1.0"
|
||||
lodash "^4.17.4"
|
||||
slice-ansi "1.0.0"
|
||||
string-width "^2.1.1"
|
||||
|
||||
text-table@~0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
|
||||
through@^2.3.6:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
|
||||
tlds@^1.187.0:
|
||||
version "1.203.1"
|
||||
resolved "https://registry.yarnpkg.com/tlds/-/tlds-1.203.1.tgz#4dc9b02f53de3315bc98b80665e13de3edfc1dfc"
|
||||
|
||||
tmp@^0.0.33:
|
||||
version "0.0.33"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
|
||||
dependencies:
|
||||
os-tmpdir "~1.0.2"
|
||||
|
||||
tweetnacl@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.0.tgz#713d8b818da42068740bf68386d0479e66fc8a7b"
|
||||
|
||||
type-check@~0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
|
||||
dependencies:
|
||||
prelude-ls "~1.1.2"
|
||||
|
||||
typedarray@^0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
|
||||
ultron@~1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
|
||||
|
||||
uri-js@^4.2.1:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
url-regex@^4.0.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/url-regex/-/url-regex-4.1.1.tgz#a5617b22e15e26dac57ce74c3f52088bcdfec995"
|
||||
dependencies:
|
||||
ip-regex "^1.0.1"
|
||||
tlds "^1.187.0"
|
||||
|
||||
util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
|
||||
which@^1.2.9:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
wordwrap@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
|
||||
write@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"
|
||||
dependencies:
|
||||
mkdirp "^0.5.1"
|
||||
|
||||
ws@^3.1.0:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2"
|
||||
dependencies:
|
||||
async-limiter "~1.0.0"
|
||||
safe-buffer "~5.1.0"
|
||||
ultron "~1.1.0"
|
||||
|
||||
xml2js@^0.4.17:
|
||||
version "0.4.19"
|
||||
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7"
|
||||
dependencies:
|
||||
sax ">=0.6.0"
|
||||
xmlbuilder "~9.0.1"
|
||||
|
||||
xmlbuilder@~9.0.1:
|
||||
version "9.0.7"
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
|
||||
|
||||
yallist@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
|
Loading…
Reference in a new issue