first structure

This commit is contained in:
noolaan 2020-04-08 08:27:34 -06:00
parent a7512253ba
commit da8871b0d6
20 changed files with 1623 additions and 1 deletions

28
.eslintrc.json Normal file
View 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
View File

@ -0,0 +1,2 @@
options.json
node_modules

9
Logger.js Normal file
View File

@ -0,0 +1,9 @@
const Winston = require('winstonjs');
class Logger extends Winston {
}
module.exports = Logger;

View File

@ -1,8 +1,32 @@
const { EventEmitter } = require('events'); const { EventEmitter } = require('events');
const options = require('./options.json');
class Manager extends EventEmitter { 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; module.exports = Manager;

9
Registry.js Normal file
View File

@ -0,0 +1,9 @@
const { EventEmitter } = require('events');
class Registry extends EventEmitter {
}
module.exports = Registry;

7
middleware/Shard.js Normal file
View File

@ -0,0 +1,7 @@
const { EventEmitter } = require('events');
class Shard extends EventEmitter {
}
module.exports = Shard;

View File

@ -0,0 +1,3 @@
class ShardManager {
}

View File

@ -15,5 +15,10 @@
"bugs": { "bugs": {
"url": "https://github.com/Navy-gif/New-GBot/issues" "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
View File

@ -0,0 +1,5 @@
class Provider {
}
module.exports = Provider;

13
storage/StorageManager.js Normal file
View File

@ -0,0 +1,13 @@
const { Collection } = require('../util/');
class StorageManager {
constructor(manager) {
this.providers = new Collection();
}
}
module.exports = StorageManager;

View File

View 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;

View File

@ -0,0 +1,6 @@
class CacheManager {
}
module.exports = CacheManager;

View File

@ -0,0 +1,5 @@
class Command {
}
module.exports = Command;

View File

@ -0,0 +1,5 @@
class Inhibitor {
}
module.exports = Inhibitor;

View File

@ -0,0 +1,6 @@
class Setting {
}
module.exports = Setting;

View 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
View 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
View File

@ -0,0 +1,3 @@
module.exports = {
Collection: require('./Collection.js');
}

1082
yarn.lock Normal file

File diff suppressed because it is too large Load Diff