first structure
This commit is contained in:
parent
a7512253ba
commit
da8871b0d6
28
.eslintrc.json
Normal file
28
.eslintrc.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
"ecmaVersion": 2018,
|
||||
"ecmaFeatures": {
|
||||
"experimentalObjectRestSpread": true
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"indent": [
|
||||
"error",
|
||||
4
|
||||
],
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"semi": [
|
||||
"warn",
|
||||
"always"
|
||||
]
|
||||
}
|
||||
}
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
options.json
|
||||
node_modules
|
9
Logger.js
Normal file
9
Logger.js
Normal file
@ -0,0 +1,9 @@
|
||||
const Winston = require('winstonjs');
|
||||
|
||||
class Logger extends Winston {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
module.exports = Logger;
|
24
Manager.js
24
Manager.js
@ -1,8 +1,32 @@
|
||||
const { EventEmitter } = require('events');
|
||||
const options = require('./options.json');
|
||||
|
||||
|
||||
|
||||
class Manager extends EventEmitter {
|
||||
|
||||
constructor(options) {
|
||||
|
||||
this.registry = new Registry(this);
|
||||
this.storageManager = new StorageManager(this, options.storage)
|
||||
.initialize();
|
||||
|
||||
this.logger = new Logger(this);
|
||||
|
||||
this._built = false;
|
||||
|
||||
}
|
||||
|
||||
async build() {
|
||||
|
||||
await this.registry.loadComponents('components/commands/', Command);
|
||||
|
||||
this._built = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = Manager;
|
9
Registry.js
Normal file
9
Registry.js
Normal file
@ -0,0 +1,9 @@
|
||||
const { EventEmitter } = require('events');
|
||||
|
||||
class Registry extends EventEmitter {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
module.exports = Registry;
|
7
middleware/Shard.js
Normal file
7
middleware/Shard.js
Normal file
@ -0,0 +1,7 @@
|
||||
const { EventEmitter } = require('events');
|
||||
|
||||
class Shard extends EventEmitter {
|
||||
|
||||
}
|
||||
|
||||
module.exports = Shard;
|
3
middleware/ShardManager.js
Normal file
3
middleware/ShardManager.js
Normal file
@ -0,0 +1,3 @@
|
||||
class ShardManager {
|
||||
|
||||
}
|
@ -15,5 +15,10 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/Navy-gif/New-GBot/issues"
|
||||
},
|
||||
"homepage": "https://github.com/Navy-gif/New-GBot#readme"
|
||||
"homepage": "https://github.com/Navy-gif/New-GBot#readme",
|
||||
"dependencies": {
|
||||
"discord.js": "discordjs/discord.js",
|
||||
"eslint": "^6.8.0",
|
||||
"mongodb": "^3.5.5"
|
||||
}
|
||||
}
|
||||
|
5
storage/Provider.js
Normal file
5
storage/Provider.js
Normal file
@ -0,0 +1,5 @@
|
||||
class Provider {
|
||||
|
||||
}
|
||||
|
||||
module.exports = Provider;
|
13
storage/StorageManager.js
Normal file
13
storage/StorageManager.js
Normal file
@ -0,0 +1,13 @@
|
||||
const { Collection } = require('../util/');
|
||||
|
||||
class StorageManager {
|
||||
|
||||
constructor(manager) {
|
||||
|
||||
this.providers = new Collection();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = StorageManager;
|
0
storage/providers/Mariadb.js
Normal file
0
storage/providers/Mariadb.js
Normal file
175
storage/providers/Mongodb.js
Normal file
175
storage/providers/Mongodb.js
Normal file
@ -0,0 +1,175 @@
|
||||
const Provider = require('./Provider.js');
|
||||
const { MongoClient } = require('mongodb');
|
||||
|
||||
class MongodbProvider extends Provider {
|
||||
|
||||
constructor(manager, config) {
|
||||
|
||||
super(manager, config);
|
||||
|
||||
if(!config) throw new Error('No config file provided!');
|
||||
if(config && (!config.database || !config.url)) throw new Error('Invalid config file provided!');
|
||||
|
||||
this.config = config;
|
||||
this.client;
|
||||
this.db;
|
||||
this.manager = manager;
|
||||
|
||||
}
|
||||
|
||||
async init() {
|
||||
|
||||
this.manager.logger.log('Initializing mongodb.');
|
||||
|
||||
try {
|
||||
|
||||
this.client = await MongoClient.connect(this.config.url+this.config.database, { useUnifiedTopology: true });
|
||||
this.manager.db = await this.client.db(this.config.database);
|
||||
this.db = this.manager.db;
|
||||
// this.manager.logger.print('Database connected.');
|
||||
|
||||
} catch(err) {
|
||||
|
||||
// this.manager.logger.error('Database connection failed!\n' + err);
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and return the first match
|
||||
*
|
||||
* @param {String} db The collection in which the data is to be updated
|
||||
* @param {Object} query The filter that is used to find the data
|
||||
* @returns {Array} An array containing the corresponding objects for the query
|
||||
* @memberof Database
|
||||
*/
|
||||
|
||||
find(db, query) {
|
||||
|
||||
//if(this.manager.debug) this.manager.logger.debug(`Incoming find query for ${db} with parameters ${JSON.stringify(query)}`);
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
this.db.collection(db).find(query, async (error, cursor) => {
|
||||
|
||||
if(error) return reject(error);
|
||||
return resolve(await cursor.toArray());
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and return the first match
|
||||
*
|
||||
* @param {String} db The collection in which the data is to be updated
|
||||
* @param {Object} query The filter that is used to find the data
|
||||
* @returns {Object} An object containing the queried data
|
||||
* @memberof Database
|
||||
*/
|
||||
|
||||
findOne(db, query) {
|
||||
|
||||
//if(this.manager.debug) this.manager.logger.debug(`Incoming findOne query for ${db} with parameters ${JSON.stringify(query)}`);
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
this.db.collection(db).findOne(query, async (error, item) => {
|
||||
|
||||
if(error) return reject(error);
|
||||
return resolve(item);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the first filter match.
|
||||
*
|
||||
* @param {String} db The collection in which the data is to be updated
|
||||
* @param {Object} filter The filter that is used to find the data
|
||||
* @param {Object} data The updated data
|
||||
* @param {Boolean} [upsert=false] Create a new entry if no match is found
|
||||
* @returns {WriteResult} Object containing the followint counts: Matched, Upserted, Modified
|
||||
* @memberof Database
|
||||
*/
|
||||
updateOne(db, query, data, upsert = false) {
|
||||
|
||||
if(this.manager.debug) this.manager.logger.debug(`Incoming updateOne query for ${db} with parameters ${JSON.stringify(filter)}`);
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
this.db.collection(db).updateOne(query, { $set: data }, { upsert: upsert }, async (error, result) => {
|
||||
|
||||
if(error) return reject(error);
|
||||
else {
|
||||
//return resolve(result)
|
||||
let { matchedCount, upsertedCount, modifiedCount } = result;
|
||||
return resolve({ matched: matchedCount, upserted: upsertedCount, modified: modifiedCount });
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Push data to an array
|
||||
*
|
||||
* @param {string} db The collection to query
|
||||
* @param {object} filter The filter to find the document to update
|
||||
* @param {object} data The data to be pushed
|
||||
* @param {boolean} [upsert=false] Create a new entry if no match is found
|
||||
* @returns
|
||||
* @memberof Database
|
||||
*/
|
||||
push(db, query, data, upsert = false) {
|
||||
|
||||
//if(this.manager.debug) this.manager.logger.debug(`Incoming push query for ${db}, with upsert ${upsert} and with parameters ${JSON.stringify(filter)} and data ${JSON.stringify(data)}`);
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
this.db.collection(db).updateOne(query, { $push: data }, { upsert: upsert }, async (error, result) => {
|
||||
|
||||
if(error) return reject(error);
|
||||
else return resolve(result);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a random element from a database
|
||||
*
|
||||
* @param {string} db The collection to query
|
||||
* @param {object} [filter={}] The filtering object to narrow down the sample pool
|
||||
* @param {number} [amount=1] Amount of items to return
|
||||
* @returns {object}
|
||||
* @memberof Database
|
||||
*/
|
||||
random(db, query = {}, amount = 1) {
|
||||
|
||||
//if(this.manager.debug) this.manager.logger.debug(`Incoming random query for ${db} with parameters ${JSON.stringify(filter)} and amount ${amount}`);
|
||||
if(amount > 100) amount = 100;
|
||||
|
||||
return new Promise((resolve, reject)=>{
|
||||
|
||||
this.db.collection(db).aggregate([{ $match: query }, { $sample: {size: amount}}], function(err, item) {
|
||||
|
||||
if(err) return reject(err);
|
||||
resolve(item);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = MongodbProvider;
|
6
structure/CacheManager.js
Normal file
6
structure/CacheManager.js
Normal file
@ -0,0 +1,6 @@
|
||||
class CacheManager {
|
||||
|
||||
|
||||
}
|
||||
|
||||
module.exports = CacheManager;
|
5
structure/interfaces/Command.js
Normal file
5
structure/interfaces/Command.js
Normal file
@ -0,0 +1,5 @@
|
||||
class Command {
|
||||
|
||||
}
|
||||
|
||||
module.exports = Command;
|
5
structure/interfaces/Inhibitor.js
Normal file
5
structure/interfaces/Inhibitor.js
Normal file
@ -0,0 +1,5 @@
|
||||
class Inhibitor {
|
||||
|
||||
}
|
||||
|
||||
module.exports = Inhibitor;
|
6
structure/interfaces/Setting.js
Normal file
6
structure/interfaces/Setting.js
Normal file
@ -0,0 +1,6 @@
|
||||
class Setting {
|
||||
|
||||
|
||||
}
|
||||
|
||||
module.exports = Setting;
|
5
structure/interfaces/index.js
Normal file
5
structure/interfaces/index.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
Command: require('./Command.js'),
|
||||
Inhibitor: require('./Inhibitor.js'),
|
||||
Setting: require('./Setting.js')
|
||||
}
|
230
util/Collection.js
Normal file
230
util/Collection.js
Normal file
@ -0,0 +1,230 @@
|
||||
/* Adopted from Discord.js */
|
||||
|
||||
class Collection extends Map {
|
||||
constructor(iterable) {
|
||||
super(iterable);
|
||||
|
||||
Object.defineProperty(this, '_array', {
|
||||
value: null,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
Object.defineProperty(this, '_keyArray', {
|
||||
value: null,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
|
||||
set(key, val) {
|
||||
this._array = null;
|
||||
this._keyArray = null;
|
||||
return super.set(key, val);
|
||||
}
|
||||
|
||||
delete(key) {
|
||||
this._array = null;
|
||||
this._keyArray = null;
|
||||
return super.delete(key);
|
||||
}
|
||||
|
||||
array() {
|
||||
if (!this._array || this._array.length !== this.size) this._array = [...this.values()];
|
||||
return this._array;
|
||||
}
|
||||
|
||||
keyArray() {
|
||||
if (!this._keyArray || this._keyArray.length !== this.size) this._keyArray = [...this.keys()];
|
||||
return this._keyArray;
|
||||
}
|
||||
|
||||
first(amount) {
|
||||
if (typeof amount === 'undefined') return this.values().next().value;
|
||||
if (amount < 0) return this.last(amount * -1);
|
||||
amount = Math.min(this.size, amount);
|
||||
const arr = new Array(amount);
|
||||
const iter = this.values();
|
||||
for (let i = 0; i < amount; i++) arr[i] = iter.next().value;
|
||||
return arr;
|
||||
}
|
||||
|
||||
firstKey(amount) {
|
||||
if (typeof amount === 'undefined') return this.keys().next().value;
|
||||
if (amount < 0) return this.lastKey(amount * -1);
|
||||
amount = Math.min(this.size, amount);
|
||||
const arr = new Array(amount);
|
||||
const iter = this.keys();
|
||||
for (let i = 0; i < amount; i++) arr[i] = iter.next().value;
|
||||
return arr;
|
||||
}
|
||||
|
||||
last(amount) {
|
||||
const arr = this.array();
|
||||
if (typeof amount === 'undefined') return arr[arr.length - 1];
|
||||
if (amount < 0) return this.first(amount * -1);
|
||||
if (!amount) return [];
|
||||
return arr.slice(-amount);
|
||||
}
|
||||
|
||||
lastKey(amount) {
|
||||
const arr = this.keyArray();
|
||||
if (typeof amount === 'undefined') return arr[arr.length - 1];
|
||||
if (amount < 0) return this.firstKey(amount * -1);
|
||||
if (!amount) return [];
|
||||
return arr.slice(-amount);
|
||||
}
|
||||
|
||||
random(amount) {
|
||||
let arr = this.array();
|
||||
if (typeof amount === 'undefined') return arr[Math.floor(Math.random() * arr.length)];
|
||||
if (arr.length === 0 || !amount) return [];
|
||||
const rand = new Array(amount);
|
||||
arr = arr.slice();
|
||||
for (let i = 0; i < amount; i++) rand[i] = arr.splice(Math.floor(Math.random() * arr.length), 1)[0];
|
||||
return rand;
|
||||
}
|
||||
|
||||
randomKey(amount) {
|
||||
let arr = this.keyArray();
|
||||
if (typeof amount === 'undefined') return arr[Math.floor(Math.random() * arr.length)];
|
||||
if (arr.length === 0 || !amount) return [];
|
||||
const rand = new Array(amount);
|
||||
arr = arr.slice();
|
||||
for (let i = 0; i < amount; i++) rand[i] = arr.splice(Math.floor(Math.random() * arr.length), 1)[0];
|
||||
return rand;
|
||||
}
|
||||
|
||||
find(fn, thisArg) {
|
||||
if (typeof thisArg !== 'undefined') fn = fn.bind(thisArg);
|
||||
for (const [key, val] of this) {
|
||||
if (fn(val, key, this)) return val;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
findKey(fn, thisArg) {
|
||||
if (typeof thisArg !== 'undefined') fn = fn.bind(thisArg);
|
||||
for (const [key, val] of this) {
|
||||
if (fn(val, key, this)) return key;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
sweep(fn, thisArg) {
|
||||
if (typeof thisArg !== 'undefined') fn = fn.bind(thisArg);
|
||||
const previousSize = this.size;
|
||||
for (const [key, val] of this) {
|
||||
if (fn(val, key, this)) this.delete(key);
|
||||
}
|
||||
return previousSize - this.size;
|
||||
}
|
||||
|
||||
filter(fn, thisArg) {
|
||||
if (typeof thisArg !== 'undefined') fn = fn.bind(thisArg);
|
||||
const results = new Collection();
|
||||
for (const [key, val] of this) {
|
||||
if (fn(val, key, this)) results.set(key, val);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
partition(fn, thisArg) {
|
||||
if (typeof thisArg !== 'undefined') fn = fn.bind(thisArg);
|
||||
const results = [new Collection(), new Collection()];
|
||||
for (const [key, val] of this) {
|
||||
if (fn(val, key, this)) {
|
||||
results[0].set(key, val);
|
||||
} else {
|
||||
results[1].set(key, val);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
map(fn, thisArg) {
|
||||
if (typeof thisArg !== 'undefined') fn = fn.bind(thisArg);
|
||||
const arr = new Array(this.size);
|
||||
let i = 0;
|
||||
for (const [key, val] of this) arr[i++] = fn(val, key, this);
|
||||
return arr;
|
||||
}
|
||||
|
||||
some(fn, thisArg) {
|
||||
if (typeof thisArg !== 'undefined') fn = fn.bind(thisArg);
|
||||
for (const [key, val] of this) {
|
||||
if (fn(val, key, this)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
every(fn, thisArg) {
|
||||
if (typeof thisArg !== 'undefined') fn = fn.bind(thisArg);
|
||||
for (const [key, val] of this) {
|
||||
if (!fn(val, key, this)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
reduce(fn, initialValue) {
|
||||
let accumulator;
|
||||
if (typeof initialValue !== 'undefined') {
|
||||
accumulator = initialValue;
|
||||
for (const [key, val] of this) accumulator = fn(accumulator, val, key, this);
|
||||
} else {
|
||||
let first = true;
|
||||
for (const [key, val] of this) {
|
||||
if (first) {
|
||||
accumulator = val;
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
accumulator = fn(accumulator, val, key, this);
|
||||
}
|
||||
}
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
tap(fn, thisArg) {
|
||||
this.forEach(fn, thisArg);
|
||||
return this;
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new this.constructor(this);
|
||||
}
|
||||
|
||||
concat(...collections) {
|
||||
const newColl = this.clone();
|
||||
for (const coll of collections) {
|
||||
for (const [key, val] of coll) newColl.set(key, val);
|
||||
}
|
||||
return newColl;
|
||||
}
|
||||
|
||||
deleteAll() {
|
||||
const returns = [];
|
||||
for (const item of this.values()) {
|
||||
if (item.delete) returns.push(item.delete());
|
||||
}
|
||||
return returns;
|
||||
}
|
||||
|
||||
equals(collection) {
|
||||
if (!collection) return false;
|
||||
if (this === collection) return true;
|
||||
if (this.size !== collection.size) return false;
|
||||
return !this.find((value, key) => {
|
||||
const testVal = collection.get(key);
|
||||
return testVal !== value || (testVal === undefined && !collection.has(key));
|
||||
});
|
||||
}
|
||||
|
||||
sort(compareFunction = (x, y) => +(x > y) || +(x === y) - 1) {
|
||||
return new Collection([...this.entries()].sort((a, b) => compareFunction(a[1], b[1], a[0], b[0])));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = Collection;
|
3
util/index.js
Normal file
3
util/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
Collection: require('./Collection.js');
|
||||
}
|
Loading…
Reference in New Issue
Block a user