Major changes to command api
- changed return type of command parsing to response - changed Response to extend the EventEmitter - changed MusicPlayer to extend the EvenEmitter - added continuos update to now playing if the message is the latest in the channel - started redesigning the graphql apifeature/api-rewrite
parent
3da2d098c4
commit
ed1cb1a812
@ -1,163 +0,0 @@
|
||||
let stateLib = require("index.js");
|
||||
|
||||
class DiscordGuildEvents extends EventGroup {
|
||||
|
||||
constructor(client) {
|
||||
super();
|
||||
this._registerClientEvents(client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registeres the client events to the EventGroup
|
||||
* @param client {Discord.Client}
|
||||
* @private
|
||||
*/
|
||||
_registerClientEvents(client) {
|
||||
this.registerEvent(new stateLib.Event('clientUserGuildSettingsUpdate'))
|
||||
.registerEvent(new stateLib.Event('clientUserSettingsUpdate'))
|
||||
.registerEvent(new stateLib.Event('emojiCreate'))
|
||||
.registerEvent(new stateLib.Event('emojiDelete'))
|
||||
.registerEvent(new stateLib.Event('emojiUpdate'))
|
||||
.registerEvent(new stateLib.Event('guildBanAdd'))
|
||||
.registerEvent(new stateLib.Event('guildBanRemove'))
|
||||
.registerEvent(new stateLib.Event('guildCreate'))
|
||||
.registerEvent(new stateLib.Event('guildDelete'))
|
||||
.registerEvent(new stateLib.Event('guildMemberAdd'))
|
||||
.registerEvent(new stateLib.Event('guildMemberAvailable'))
|
||||
.registerEvent(new stateLib.Event('guildMemberRemove'))
|
||||
.registerEvent(new stateLib.Event('guildMemberChunk'))
|
||||
.registerEvent(new stateLib.Event('guildMemberSpeaking'))
|
||||
.registerEvent(new stateLib.Event('guildMemberUpdate'))
|
||||
.registerEvent(new stateLib.Event('guildUnavailable'))
|
||||
.registerEvent(new stateLib.Event('guildUpdate'))
|
||||
.registerEvent(new stateLib.Event('presenceUpdate'))
|
||||
.registerEvent(new stateLib.Event('roleCreate'))
|
||||
.registerEvent(new stateLib.Event('roleDelete'))
|
||||
.registerEvent(new stateLib.Event('roleUpdate'))
|
||||
.registerEvent(new stateLib.Event('userNoteUpdate'))
|
||||
.registerEvent(new stateLib.Event('userUpdate'))
|
||||
.registerEvent(new stateLib.Event('voiceStateUpdate'));
|
||||
|
||||
client.on('clientUserGuildSettingsUpdate', (...o) => this.events.clientUserGuildSettingsUpdate.fire(o));
|
||||
client.on('clientUserSettingsUpdate', (...o) => this.events.clientUserSettingsUpdate.fire(o));
|
||||
client.on('emojiCreate', (...o) => this.events.emojiCreate.fire(o));
|
||||
client.on('emojiDelete', (...o) => this.events.emojiDelete.fire(o));
|
||||
client.on('emojiUpdate', (...o) => this.events.emojiUpdate.fire(o));
|
||||
client.on('guildBanAdd', (...o) => this.events.guildBanAdd.fire(o));
|
||||
client.on('guildBanRemove', (...o) => this.events.guildBanRemove.fire(o));
|
||||
client.on('guildCreate', (...o) => this.events.guildCreate.fire(o));
|
||||
client.on('guildDelete', (...o) => this.events.guildDelete.fire(o));
|
||||
client.on('guildMemberAdd', (...o) => this.events.guildMemberAdd.fire(o));
|
||||
client.on('guildMemberAvailable', (...o) => this.events.guildMemberAvailable.fire(o));
|
||||
client.on('guildMemberRemove', (...o) => this.events.guildMemberRemove.fire(o));
|
||||
client.on('guildMemberChunk', (...o) => this.events.guildMemberChunk.fire(o));
|
||||
client.on('guildMemberSpeaking', (...o) => this.events.guildMemberSpeaking.fire(o));
|
||||
client.on('guildMemberUpdate', (...o) => this.events.guildMemberUpdate.fire(o));
|
||||
client.on('guildUnavailable', (...o) => this.events.guildUnavailable.fire(o));
|
||||
client.on('guildUpdate', (...o) => this.events.guildUpdate.fire(o));
|
||||
client.on('presenceUpdate', (...o) => this.events.presenceUpdate.fire(o));
|
||||
client.on('roleCreate', (...o) => this.events.roleCreate.fire(o));
|
||||
client.on('roleDelete', (...o) => this.events.roleDelete.fire(o));
|
||||
client.on('roleUpdate', (...o) => this.events.roleUpdate.fire(o));
|
||||
client.on('userNoteUpdate', (...o) => this.events.userNoteUpdate.fire(o));
|
||||
client.on('userUpdate', (...o) => this.events.userUpdate.fire(o));
|
||||
client.on('voiceStateUpdate', (...o) => this.events.voiceStateUpdate.fire(o));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class DiscordMessageEvents extends stateLib.EventGroup {
|
||||
|
||||
constructor(client) {
|
||||
super();
|
||||
this._registerMessageEvents(client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registeres all client message events
|
||||
* @param client {Discord.Client}
|
||||
* @private
|
||||
*/
|
||||
_registerMessageEvents(client) {
|
||||
this.registerEvent(new stateLib.Event('messageDelete'))
|
||||
.registerEvent(new stateLib.Event('messageDeleteBulk'))
|
||||
.registerEvent(new stateLib.Event('messageReactionAdd'))
|
||||
.registerEvent(new stateLib.Event('messageReactionRemove'))
|
||||
.registerEvent(new stateLib.Event('messageReactionRemoveAll'))
|
||||
.registerEvent(new stateLib.Event('messageUpdate'))
|
||||
.registerEvent(new stateLib.Event('message'));
|
||||
|
||||
client.on('messageDelete', (...o) => this.events.messageDelete.fire(o));
|
||||
client.on('messageDeleteBulk', (...o) => this.events.messageDeleteBulk.fire(o));
|
||||
client.on('messageReactionAdd', (...o) => this.events.messageReactionAdd.fire(o));
|
||||
client.on('messageReactionRemove', (...o) => this.events.messageReactionRemove.fire(o));
|
||||
client.on('messageReactionRemoveAll', (...o) => this.events.messageReactionRemoveAll.fire(o));
|
||||
client.on('messageUpdate', (...o) => this.events.messageUpdate.fire(o));
|
||||
client.on('message', (...o) => this.events.message.fire(o));
|
||||
}
|
||||
}
|
||||
|
||||
class DiscordChannelEvents extends stateLib.EventGroup {
|
||||
|
||||
constructor(client) {
|
||||
super();
|
||||
this._registerChannelEvents(client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all events for discord channels.
|
||||
* @param client {Discord.Client}
|
||||
* @private
|
||||
*/
|
||||
_registerChannelEvents(client) {
|
||||
this.registerEvent(new stateLib.Event('channelCreate'))
|
||||
.registerEvent(new stateLib.Event('channelDelete'))
|
||||
.registerEvent(new stateLib.Event('channelPinsUpdate'))
|
||||
.registerEvent(new stateLib.Event('channelUpdate'))
|
||||
.registerEvent(new stateLib.Event('typingStart'))
|
||||
.registerEvent(new stateLib.Event('typingStop'));
|
||||
|
||||
client.on('channelCreate', (...o) => this.events.channelCreate.fire(o));
|
||||
client.on('channelDelete', (...o) => this.events.channelDelete.fire(o));
|
||||
client.on('channelPinsUpdate', (...o) => this.events.channelPinsUpdate.fire(o));
|
||||
client.on('channelUpdate', (...o) => this.events.channelUpdate.fire(o));
|
||||
client.on('typingStart', (...o) => this.events.typingStart.fire(o));
|
||||
client.on('typingStop', (...o) => this.events.typingStop.fire(o));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DiscordClientEvents extends stateLib.EventGroup {
|
||||
|
||||
constructor(client) {
|
||||
super();
|
||||
this._registerClientEvents(client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers Discord client events
|
||||
* @param client {Discord.Client}
|
||||
* @private
|
||||
*/
|
||||
_registerClientEvents(client) {
|
||||
this.registerEvent(new stateLib.Event('debug'))
|
||||
.registerEvent(new stateLib.Event('warn'))
|
||||
.registerEvent(new stateLib.Event('error'))
|
||||
.registerEvent(new stateLib.Event('ready'))
|
||||
.registerEvent(new stateLib.Event('resume'))
|
||||
.registerEvent(new stateLib.Event('disconnect'))
|
||||
.registerEvent(new stateLib.Event('reconnecting'))
|
||||
.registerEvent(new stateLib.Event('rateLimit'));
|
||||
|
||||
client.on('debug', (...o) => this.events.debug.fire(o));
|
||||
client.on('warn', (...o) => this.events.warn.fire(o));
|
||||
client.on('error', (...o) => this.events.error.fire(o));
|
||||
client.on('ready', (...o) => this.events.ready.fire(o));
|
||||
client.on('resume', (...o) => this.events.resume.fire(o));
|
||||
client.on('disconnect', (...o) => this.events.disconnect.fire(o));
|
||||
client.on('reconnecting', (...o) => this.events.reconnecting.fire(o));
|
||||
client.on('rateLimit', (...o) => this.events.rateLimit.fire(o));
|
||||
client.on('presenceUpdate', (...o) => this.events.presenceUpdate.fire(o));
|
||||
}
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
const logging = require('../utils/logging');
|
||||
|
||||
class EventRouter {
|
||||
|
||||
constructor() {
|
||||
this._logger = new logging.Logger(this);
|
||||
this.eventGroups = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires an event of an event group with event data.
|
||||
* @param eventGroup {String}
|
||||
* @param eventName {String}
|
||||
* @param eventData {Object}
|
||||
*/
|
||||
fireEvent(eventGroup, eventName, eventData) {
|
||||
if (this.eventGroups[eventGroup] instanceof EventGroup)
|
||||
this.eventGroups[eventGroup].fireEvent(eventName, eventData);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an EventRoute to the EventRouter
|
||||
* @param group {EventGroup}
|
||||
*/
|
||||
registerEventGroup(group) {
|
||||
this.eventGroups[group.name] = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class EventGroup {
|
||||
|
||||
/**
|
||||
* Creates a new EventGroup with the given name.
|
||||
* @param [name] {String}
|
||||
*/
|
||||
constructor(name) {
|
||||
this._logger = new logging.Logger(this);
|
||||
this.name = name || this.constructor.name;
|
||||
this.events = {};
|
||||
}
|
||||
|
||||
fireEvent(eventName, eventData) {
|
||||
if (this.events[eventName] instanceof Event)
|
||||
this.events[eventName].fire(eventData);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registeres an Event to the EventGroup
|
||||
* @param event {Event}
|
||||
*/
|
||||
registerEvent(event) {
|
||||
this.events[event.name] = event;
|
||||
}
|
||||
}
|
||||
|
||||
class Event {
|
||||
|
||||
/**
|
||||
* Creates a new Event with the given name.
|
||||
* @param name
|
||||
*/
|
||||
constructor(name) {
|
||||
this._logger = new logging.Logger(this);
|
||||
this.name = name;
|
||||
this.handlers = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an event handler to the Event
|
||||
* @param handler {Function}
|
||||
*/
|
||||
addHandler(handler) {
|
||||
this.handlers.push(handler);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires the event with the given data.
|
||||
* @param data {Object}
|
||||
*/
|
||||
fire(data) {
|
||||
for (let handler in this.handlers)
|
||||
try {
|
||||
handler(data);
|
||||
} catch (err) {
|
||||
this._logger.verbose(err.message);
|
||||
this._logger.silly(err.stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object.assign(exports, {
|
||||
EventRouter: EventRouter,
|
||||
EventGroup: EventGroup,
|
||||
Event: Event
|
||||
});
|
@ -0,0 +1,76 @@
|
||||
const logging = require('../utils/logging'),
|
||||
EventEmitter = require('events');
|
||||
|
||||
/**
|
||||
* Extends the event emitter with some useful features.
|
||||
*/
|
||||
class ExtendedEventEmitter extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param [name] {String}
|
||||
*/
|
||||
constructor(name) {
|
||||
super();
|
||||
this._logger = new logging.Logger(`${name}-${this.constructor.name}`);
|
||||
this._registerDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registeres the error event to the logger so it won't crash the bot.
|
||||
* @private
|
||||
*/
|
||||
_registerDefault() {
|
||||
this.on('error', (err) => {
|
||||
this._logger.error(err.message);
|
||||
this._logger.debug(err.stack);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an object of events with listeners to the bot.
|
||||
* @param eventListenerObject
|
||||
* @returns {ExtendedEventEmitter}
|
||||
*/
|
||||
addListeners(eventListenerObject) {
|
||||
for (let [event, listener] of Object.entries(eventListenerObject))
|
||||
this.on(event, listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all registered events.
|
||||
* @returns {*|Array<string | symbol>|string[]}
|
||||
*/
|
||||
get events() {
|
||||
return this.eventNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around getMaxListeners function
|
||||
* @returns {*|number}
|
||||
*/
|
||||
get maxListeners() {
|
||||
return this.getMaxListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around setMaxListeners function.
|
||||
* @param n
|
||||
* @returns {this | this | Cluster | *}
|
||||
*/
|
||||
set maxListeners(n) {
|
||||
return this.setMaxListeners(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the emitter has additional listeners apart from the error listener.
|
||||
*/
|
||||
get hasListeners() {
|
||||
return this.events.count > 1;
|
||||
}
|
||||
}
|
||||
|
||||
Object.assign(exports, {
|
||||
ExtendedEventEmitter: ExtendedEventEmitter,
|
||||
});
|
@ -0,0 +1,145 @@
|
||||
const graphql = require('graphql'),
|
||||
fs = require('fs');
|
||||
|
||||
class BotGraphql {
|
||||
constructor(bot) {
|
||||
this.schema = graphql.buildSchema(fs.readFileSync('.lib/web/schema.graphqls', 'utf-8'));
|
||||
this.root = {
|
||||
Query: new Query(bot)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Easyer managing of page info
|
||||
*/
|
||||
class PageInfo {
|
||||
/**
|
||||
* constructor.
|
||||
* @param total {Number} - the total number of entries
|
||||
* @param perPage {Number} - the number of entries per page
|
||||
* @param currentPage {Number} - the current page's index
|
||||
* @param lastPage {Number} - the index of the last page
|
||||
* @param hasNext {Boolean} - is there a next page?
|
||||
*/
|
||||
constructor(total, perPage, currentPage, lastPage, hasNext) {
|
||||
this.total = total;
|
||||
this.perPage = perPage;
|
||||
this.currentPage = currentPage;
|
||||
this.lastPage = lastPage;
|
||||
this.hasNext = hasNext;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic edge
|
||||
*/
|
||||
class Edge {
|
||||
/**
|
||||
* contructor.
|
||||
* @param node {Object} - the node belonging to the edge
|
||||
* @param edgeProps {Object} - additional properties of the edge
|
||||
*/
|
||||
constructor(node, edgeProps) {
|
||||
this.node = node;
|
||||
Object.assign(this, edgeProps);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic connection
|
||||
*/
|
||||
class Connection {
|
||||
/**
|
||||
* constructor.
|
||||
* @param edges {Array<Edge>} - the edges of the connection
|
||||
* @param pageInfo {PageInfo} - page info for the connection
|
||||
*/
|
||||
constructor(edges, pageInfo) {
|
||||
this.edges = edges;
|
||||
this.nodes = this.edges.map(x => x.node);
|
||||
this.pageInfo = pageInfo;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages pagination
|
||||
*/
|
||||
class Paginator {
|
||||
/**
|
||||
* constructor.
|
||||
* @param edges {Array<Object>} - the edges for the pages
|
||||
* @param perPage {Number} - the number of entries per page
|
||||
*/
|
||||
constructor(edges, perPage) {
|
||||
this._entries = edges;
|
||||
this.perPage = perPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specific page
|
||||
* @param page {Number} - the page's number
|
||||
* @param [perPage] {Number} - the number of entries per page
|
||||
* @returns {Connection}
|
||||
*/
|
||||
getPage(page, perPage) {
|
||||
perPage = perPage || this.perPage;
|
||||
let startIndex = (page - 1) * perPage;
|
||||
let endIndex = startIndex + perPage;
|
||||
let lastPage = Math.ceil(this._entries.length / perPage);
|
||||
return new Connection(
|
||||
this._entries.slice(startIndex, endIndex) || [],
|
||||
new PageInfo(this._entries.length, perPage, page, lastPage, page !== lastPage)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the entries of the Paginator.
|
||||
* @param entries
|
||||
*/
|
||||
updateEntries(entries) {
|
||||
this._entries = entries;
|
||||
}
|
||||
}
|
||||
|
||||
class MusicPlayer {
|
||||
constructor(guildHandler) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Guild {
|
||||
constructor(guild) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Client {
|
||||
constructor(bot) {
|
||||
this._bot = bot;
|
||||
this._client = bot.client;
|
||||
this.guildPaginator = new Paginator()
|
||||
}
|
||||
|
||||
_getGuildEdges() {
|
||||
let guildHandlerPaginator = Array.from(this._client.guilds.values()).map(x => new Edge(
|
||||
|
||||
));
|
||||
return Array.from(this._client.guilds.values()).map(x => new Edge(
|
||||
new Guild(x),
|
||||
{
|
||||
musicPlayer: new MusicPlayer(this._bot.getGuildHandler(x)),
|
||||
new Connection(
|
||||
bot.getGuildHandler(x).savedMedia
|
||||
)
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
class Query {
|
||||
constructor(bot) {
|
||||
this._bot = bot;
|
||||
this.client = new Client(bot);
|
||||
}
|
||||
}
|
@ -0,0 +1,440 @@
|
||||
const graphql = require('graphql');
|
||||
|
||||
let pageInfoType = new graphql.GraphQLObjectType({
|
||||
name: 'PageInfo',
|
||||
fields: {
|
||||
total: {
|
||||
type: graphql.assertNonNullType(graphql.GraphQLInt),
|
||||
description: 'total number of pages'
|
||||
},
|
||||
perPage: {
|
||||
type: graphql.assertNonNullType(graphql.GraphQLInt),
|
||||
description: 'number of entries per page'
|
||||
},
|
||||
currentPage: {
|
||||
type: graphql.assertNonNullType(graphql.GraphQLInt),
|
||||
description: 'current page'
|
||||
},
|
||||
lastPage: {
|
||||
type: graphql.assertNonNullType(graphql.GraphQLInt),
|
||||
description: 'last page'
|
||||
},
|
||||
hasNextPage: {
|
||||
type: graphql.assertNonNullType(graphql.GraphQLBoolean),
|
||||
description: 'does the connection have a next page'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let mediaEntryType = new graphql.GraphQLObjectType({
|
||||
|
||||
name: 'MediaEntry',
|
||||
fields: {
|
||||
id: {
|
||||
type: graphql.GraphQLID,
|
||||
description: 'id of the media entry'
|
||||
},
|
||||
url: {
|
||||
type: graphql.GraphQLString,
|
||||
description: 'url to the YouTube video'
|
||||
},
|
||||
name: {
|
||||
type: graphql.GraphQLString,
|
||||
description: 'title of the YouTube video'
|
||||
},
|
||||
thumbnail: {
|
||||
type: graphql.GraphQLString,
|
||||
description: 'thumbnail of the YouTube video'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let mediaEntryEdgeType = new graphql.GraphQLObjectType({
|
||||
name: 'MediaEntryEdge',
|
||||
fields: {
|
||||
id: {
|
||||
type: graphql.GraphQLID,
|
||||
description: 'the connection id'
|
||||
},
|
||||
position: {
|
||||
type: graphql.GraphQLInt,
|
||||
description: 'position in the queue'
|
||||
},
|
||||
node: {
|
||||
type: mediaEntryType,
|
||||
description: 'the media entry node'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let mediaEntryConnectionType = new graphql.GraphQLObjectType({
|
||||
name: 'MediaEntryConnection',
|
||||
fields: {
|
||||
edges: {
|
||||
type: graphql.GraphQLList(mediaEntryEdgeType)
|
||||
},
|
||||
nodes: {
|
||||
type: graphql.GraphQLList(mediaEntryType)
|
||||
},
|
||||
pageInfo: {
|
||||
type: graphql.assertNonNullType(pageInfoType),
|
||||
description: 'pagination information'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let musicPlayerType = new graphql.GraphQLObjectType({
|
||||
|
||||
name: 'MusicPlayer',
|
||||
fields: {
|
||||
queue: {
|
||||
type: new graphql.GraphQLList(mediaEntryConnectionType),
|
||||
description: 'media entries in the music queue'
|
||||
},
|
||||
queueCount: {
|
||||
type: graphql.GraphQLInt,
|
||||
description: 'number of media entries in the queue'
|
||||
},
|
||||
songStartTime: {
|
||||
type: graphql.GraphQLString
|
||||
},
|
||||
playing: {
|
||||
type: graphql.GraphQLBoolean
|
||||
},
|
||||
volume: {
|
||||
type: graphql.GraphQLFloat
|
||||
},
|
||||
repeat: {
|
||||
type: graphql.GraphQLBoolean
|
||||
},
|
||||
currentSong: {
|
||||
type: mediaEntryType
|
||||
},
|
||||
quality: {
|
||||
type: graphql.GraphQLString
|
||||
},
|
||||
voiceChannel: {
|
||||
type: graphql.GraphQLString
|
||||
},
|
||||
connected: {
|
||||
type: graphql.GraphQLBoolean
|
||||
},
|
||||
paused: {
|
||||
type: graphql.GraphQLBoolean
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let presenceType = new graphql.GraphQLObjectType({
|
||||
|
||||
name: 'Presence',
|
||||
fields: {
|
||||
game: {
|
||||
type: graphql.GraphQLString
|
||||
},
|
||||
status: {
|
||||
type: graphql.GraphQLString
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let userType = new graphql.GraphQLObjectType({
|
||||
|
||||
name: 'User',
|
||||
fields: {
|
||||
id: {
|
||||
type: graphql.GraphQLID
|
||||
},
|
||||
discordId: {
|
||||
type: graphql.GraphQLID
|
||||
},
|
||||
name: {
|
||||
type: graphql.GraphQLString
|
||||
},
|
||||
avatar: {
|
||||
type: graphql.GraphQLString
|
||||
},
|
||||
bot: {
|
||||
type: graphql.GraphQLBoolean
|
||||
},
|
||||
tag: {
|
||||
type: graphql.GraphQLString
|
||||
},
|
||||
presence: {
|
||||
type: presenceType
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let guildMemberType = new graphql.GraphQLObjectType({
|
||||
name: 'GuildMember',
|
||||
fields: {
|
||||
id: {
|
||||
type: graphql.assertNonNullType(graphql.GraphQLID),
|
||||
description: 'id of the guild member'
|
||||
},
|
||||
discordId: {
|
||||
type: graphql.GraphQLID
|
||||
},
|
||||
user: {
|
||||
type: userType,
|
||||
description: 'the user instance of the guild member'
|
||||
},
|
||||
nickname: {
|
||||
type: graphql.GraphQLString,
|
||||
description: 'the nickname of the guild member'
|
||||
},
|
||||
roles: {
|
||||
type: graphql.GraphQLList(roleType),
|
||||
description: 'the roles of the guild member'
|
||||
},
|
||||
highestRole: {
|
||||
type: roleType,
|
||||
description: 'the highest role of the guild member'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let userRoleEdgeType = new graphql.GraphQLObjectType({
|
||||
name: 'userRoleEdge',
|
||||
fields: {
|
||||
id: {
|
||||
type: graphql.GraphQLID,
|
||||
description: 'the connection id'
|
||||
},
|
||||
node: {
|
||||
type: guildMemberType,
|
||||
description: 'guild member edge of the role'
|
||||
},
|
||||
isHighest: {
|
||||
type: graphql.GraphQLBoolean,
|
||||
description: 'is the role the highest of the guild member'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let userRoleConnectionType = new graphql.GraphQLObjectType({
|
||||
name: 'UserRoleConnection',
|
||||
fields: {
|
||||
edges: {
|
||||
type: graphql.GraphQLList(userRoleEdgeType)
|
||||
},
|
||||
nodes: {
|
||||
type: graphql.GraphQLList(userType)
|
||||
},
|
||||
pageInfoType: {
|
||||
type: graphql.assertNonNullType(pageInfoType),
|
||||
description: 'pagination information'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let roleType = new graphql.GraphQLObjectType({
|
||||
|
||||
name: 'Role',
|
||||
fields: {
|
||||
id: {
|
||||
type: graphql.GraphQLID
|
||||
},
|
||||
discordId: {
|
||||
type: graphql.GraphQLID
|
||||
},
|
||||
name: {
|
||||
type: graphql.GraphQLString
|
||||
},
|
||||
color: {
|
||||
type: graphql.GraphQLString
|
||||
},
|
||||
members: {
|
||||
type: userRoleConnectionType
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let userGuildConnectionType = new graphql.GraphQLObjectType({
|
||||
name: 'UserGuildConnection',
|
||||
fields: {
|
||||
edges: {
|
||||
type: graphql.GraphQLList(guildMemberType)
|
||||
},
|
||||
nodes: {
|
||||
type: graphql.GraphQLList(userType)
|
||||
},
|
||||
pageInfoType: {
|
||||
type: graphql.assertNonNullType(pageInfoType),
|
||||
description: 'pagination information'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let guildType = new graphql.GraphQLObjectType({
|
||||
|
||||
name: 'Guild',
|
||||
fields: {
|
||||
id: {
|
||||
type: graphql.GraphQLID
|
||||
},
|
||||
discordId: {
|
||||
type: graphql.GraphQLID
|
||||
},
|
||||
name: {
|
||||
type: graphql.GraphQLString
|
||||
},
|
||||
owner: {
|
||||
type: guildMemberType
|
||||
},
|
||||
members: {
|
||||
type: userGuildConnectionType
|
||||
},
|
||||
memberCount: {
|
||||
type: graphql.GraphQLInt
|
||||
},
|
||||
roles: {
|
||||
type: graphql.GraphQLList(roleType),
|
||||
description: 'the roles of the guild'
|
||||
},
|
||||
icon: {
|
||||
type: graphql.GraphQLString
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let guildEdgeType = new graphql.GraphQLObjectType({
|
||||
name: 'GuildEdge',
|
||||
fields: {
|
||||
id: {
|
||||
type: graphql.GraphQLID,
|
||||
description: 'id of the connection'
|
||||
},
|
||||
node: {
|
||||
type: guildType
|
||||
},
|
||||
musicPlayer: {
|
||||
type: musicPlayerType,
|
||||
description: 'guilds music player'
|
||||
},
|
||||
savedMedia: {
|
||||
type: mediaEntryConnectionType,
|
||||
description: 'saved media entries'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let guildConnectionType = new graphql.GraphQLObjectType({
|
||||
name: 'GuildConnection',
|
||||
edges: {
|
||||
type: guildEdgeType
|
||||
},
|
||||
nodes: {
|
||||
type: graphql.GraphQLList(guildType)
|
||||
},
|
||||
pageInfo: {
|
||||
type: pageInfoType,
|
||||
description: 'pagination information'
|
||||
}
|
||||
});
|
||||
|
||||
let clientType = new graphql.GraphQLObjectType({
|
||||
name: 'Client',
|
||||
fields: {
|
||||
guilds: {
|
||||
type: [guildType]
|
||||
},
|
||||
guildCount: {
|
||||
type: graphql.GraphQLInt
|
||||
},
|
||||
voiceConnectionCount: {
|
||||
type: graphql.GraphQLInt
|
||||
},
|
||||
user: {
|
||||
type: userType
|
||||
},
|
||||
ping: {
|
||||
type: graphql.GraphQLFloat
|
||||
},
|
||||
status: {
|
||||
type: graphql.GraphQLInt
|
||||
},
|
||||
uptime: {
|
||||
type: graphql.GraphQLInt
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let logLevelEnum = new graphql.GraphQLEnumType({
|
||||
name: 'LogLevel',
|
||||
description: 'log levels of log entries',
|
||||
values: {
|
||||
SILLY: {
|
||||
value: 'silly'
|
||||
},
|
||||
DEBUG: {
|
||||
value: 'debug'
|
||||
},
|
||||
VERBOSE: {
|
||||
value: 'verbose'
|
||||
},
|
||||
INFO: {
|
||||
value: 'info'
|
||||
},
|
||||
WARN: {
|
||||
value: 'warn'
|
||||
},
|
||||
ERROR: {
|
||||
value: 'error'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let logEntryType = new graphql.GraphQLObjectType({
|
||||
name: 'LogEntry',
|
||||
fields: {
|
||||
id: {
|
||||
type: graphql.assertNonNullType(graphql.GraphQLID),
|
||||
description: 'id of the log entry'
|
||||
},
|
||||
message: {
|
||||
type: graphql.GraphQLString,
|
||||
description: 'log entry content'
|
||||
},
|
||||
level: {
|
||||
type: logLevelEnum,
|
||||
description: 'log level of the log entry'
|
||||
},
|
||||
timestamp: {
|
||||
type: graphql.GraphQLString,
|
||||
description: 'timestamp of the log entry'
|
||||
},
|
||||
module: {
|
||||
type: graphql.GraphQLString,
|
||||
description: 'module that logged the entry'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const queryType = new graphql.GraphQLObjectType({
|
||||
|
||||
name: 'Query',
|
||||
fields: {
|
||||
client: {
|
||||
type: clientType,
|
||||
description: 'client instance of the bot'
|
||||
},
|
||||
presences: {
|
||||
type: graphql.assertNonNullType(graphql.GraphQLList(presenceType)),
|
||||
description: 'presences of the bot'
|
||||
},
|
||||
prefix: {
|
||||
type: graphql.GraphQLString,
|
||||
description: 'prefix of the bot'
|
||||
},
|
||||
logs: {
|
||||
type: graphql.GraphQLList(logEntryType),
|
||||
description: 'log entries of the bot'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Object.assign(exports, {
|
||||
queryType: queryType
|
||||
});
|
@ -0,0 +1,429 @@
|
||||
enum LogLevel {
|
||||
SILLY
|
||||
DEBUG
|
||||
VERBOSE
|
||||
INFO
|
||||
WARN
|
||||
ERROR
|
||||
}
|
||||
|
||||
type PageInfo {
|
||||
|
||||
# the total number of entries on all pages
|
||||
total: Int
|
||||
|
||||
# the number of entries per page
|
||||
perPage: Int
|
||||
|
||||
# the current page
|
||||
currentPage: Int
|
||||
|
||||
# the last page
|
||||
lastPage: Int
|
||||
|
||||
# If there is a next page
|
||||
hasNextPage: Boolean
|
||||
}
|
||||
|
||||
type MediaEntry {
|
||||
|
||||
# the id of the media entry
|
||||
id: ID!
|
||||
|
||||
# the url to the YouTube video
|
||||
url: String!
|
||||
|
||||
# the title of the YouTube video
|
||||
name: String!
|
||||
|
||||
# the url of the YouTube video's thumbnail
|
||||
thumbnail: String!
|
||||
}
|
||||
|
||||
type MediaEntryEdge {
|
||||
|
||||
# the id of the edge
|
||||
id: ID!
|
||||
|
||||
node: MediaEntry
|
||||
|
||||
# the position of the entry in the queue
|
||||
position: Int
|
||||
}
|
||||
|
||||
type MediaEntryConnection {
|
||||
|
||||
edges: [MediaEntryEdge]
|
||||
|
||||
nodes: [MediaEntry]
|
||||
|
||||
# the pagination information
|
||||
pageInfo: PageInfo
|
||||
}
|
||||
|
||||
type MusicPlayer {
|
||||
|
||||
# the content of the music players queue
|
||||
#
|
||||
# Arguments
|
||||
# id: get the media entry by id
|
||||
# page: get the page by number
|
||||
# perPage: the number of entries per page
|
||||
queue(
|
||||
id: ID,
|
||||
page: Int,
|
||||
perPage: Int
|
||||
): MediaEntryConnection
|
||||
|
||||
# the current position in the song
|
||||
songPosition: Int
|
||||
|
||||
# if the music player is currently playing
|
||||
playing: Boolean!
|
||||
|
||||
# the volume of the music player
|
||||
volume: Float
|
||||
|
||||
# if the music player plays on repeat
|
||||
repeat: Boolean
|
||||
|
||||
# the currently playing song
|
||||
currentSong: MediaEntry
|
||||
|
||||
# the quality of the music that is played (YouTube quality)
|
||||
quality: String
|
||||
|
||||
# the name of the voice channel the music player is playing in
|
||||
voiceChannel: String
|
||||
|
||||
# if the music player is connected to a voice channel
|
||||
connected: Boolean!
|
||||
|
||||
# if the music player is paused
|
||||
paused: Boolean!
|
||||
}
|
||||
|
||||
type User {
|
||||
|
||||
# the id of the user
|
||||
id: ID!
|
||||
|
||||
# the discord id of the user
|
||||
discordId: String
|
||||
|
||||
# the name of the user
|
||||
name: String!
|
||||
|
||||
# the url of the users avatar
|
||||
avatar: String
|
||||
|
||||
# if the user is a bot
|
||||
bot: Boolean
|
||||
|
||||
# the discord tag of the user
|
||||
tag: String!
|
||||
|
||||
# the current presence of the user
|
||||
presence: Presence
|
||||
}
|
||||
|
||||
type Role {
|
||||
|
||||
# the id of the role
|
||||
id: ID!
|
||||
|
||||
# the discord id of the role
|
||||
discordId: String
|
||||
|
||||
# the name of the role
|
||||
name: String
|
||||
|
||||
# the color of the role
|
||||
color: String
|
||||
}
|
||||
|
||||
type GuildMemberRoleEdge {
|
||||
|
||||
# the id of the edge
|
||||
id: ID!
|
||||
|
||||
node: GuildMember
|
||||
|
||||
# if the role is the highest of the guild member
|
||||
isHighest: Boolean
|
||||
}
|
||||
|
||||
type GuildMemberRoleConnection {
|
||||
|
||||
edges: [GuildMemberRoleEdge]
|
||||
|
||||
nodes: [GuildMember]
|
||||
|
||||
# the pagination information
|
||||
pageInfo: PageInfo
|
||||
}
|
||||
|
||||
type GuildRoleEdge {
|
||||
|
||||
# the id of the edge
|
||||
id: ID!
|
||||
|
||||
node: Role
|
||||
|
||||
# the members in the role
|
||||
#
|
||||
# Arguments
|
||||
# id: get the member by id
|
||||
# page: get the page by number
|
||||
# perPage: the number of entries per page
|
||||
members(
|
||||
id: ID,
|
||||
page: Int,
|
||||
perPage: Int
|
||||
): GuildMemberRoleConnection
|
||||
}
|
||||
|
||||
type GuildRoleConnection{
|
||||
|
||||
edges: [GuildRoleEdge]
|
||||
|
||||
nodes: [Role]
|
||||
|
||||
# the pagination information
|
||||
pageInfo: PageInfo
|
||||
}
|
||||
|
||||
type GuildMember {
|
||||
|
||||
# the id of the guild member
|
||||
id: ID!
|
||||
|
||||
# the discord id of the guild member
|
||||
discordId: String
|
||||
|
||||
# the user associated with the guild member
|
||||
user: User
|
||||
|
||||
# the nickname of the guild member
|
||||
nickname: String
|
||||
|
||||
# the roles of the guild member
|
||||
roles(
|
||||
first: Int = 10,
|
||||
offset: Int = 0,
|
||||
id: String
|
||||
): [Role]
|
||||
|
||||
# the highest role of the guild member
|
||||
highestRole: Role
|
||||
}
|
||||
|
||||
type GuildMemberEdge {
|
||||
|
||||
# the id of the edge
|
||||
id: ID!
|
||||
|
||||
node: GuildMember
|
||||
|
||||
# if the guild member is the server owner
|
||||
isOwner: Boolean
|
||||
}
|
||||
|
||||
type GuildMemberConnection{
|
||||
|
||||
edges: [GuildMemberEdge]
|
||||
|
||||
nodes: [GuildMember]
|
||||
|
||||
# the pagination information
|
||||
pageInfo: PageInfo
|
||||
}
|
||||
|
||||
type Guild {
|
||||
|
||||
# the id of the guild
|
||||
id: ID!
|
||||
|
||||
# the discord id of the guild
|
||||
discordId: ID
|
||||
|
||||
# the guild's name
|
||||
name: String
|
||||
|
||||
# the owner of the guild
|
||||
owner: GuildMember
|
||||
|
||||
# the members in the guild
|
||||
#
|
||||
# Arguments
|
||||
# id: get the member by id
|
||||
# page: get the page by number
|
||||
# perPage: the number of entries per page
|
||||
members(
|
||||
id: ID,
|
||||
page: Int,
|
||||
perPage: Int
|
||||
): GuildMemberConnection
|
||||
|
||||
# the roles of the guild
|
||||
#
|
||||
# Arguments
|
||||
# id: get the role by id
|
||||
# page: get the page by number
|
||||
# perPage: the number of entries per page
|
||||
roles(
|
||||
id: ID,
|
||||
page: Int,
|
||||
perPage: Int
|
||||
): GuildRoleConnection
|
||||
|
||||
# the url of the guild icon
|
||||
icon: String
|
||||
}
|
||||
|
||||
type GuildEdge {
|
||||
|
||||
# the id of the edge
|
||||
id: ID!
|
||||
|
||||
node: Guild
|
||||
|
||||
# the music player associated with the guild
|
||||
musicPlayer: MusicPlayer
|
||||
|
||||
# the saved media of the guild
|
||||
savedMedia: mediaEntryConnection
|
||||
}
|
||||
|
||||
type GuildConnection {
|
||||
|
||||
edges: [GuildEdge]
|
||||
|
||||
nodes: [Guild]
|
||||
|
||||
# the pagination information
|
||||
pageInfo: PageInfo
|
||||
}
|
||||
|
||||
type Client {
|
||||
|
||||
# the guilds the client has joined
|
||||
#
|
||||
# Arguments
|
||||
# id: get the guild by id
|
||||
# page: get the page by number
|
||||
# perPage: the number of entries per page
|
||||
guilds (
|
||||
id: ID,
|
||||
page: Int,
|
||||
perPage: Int
|
||||
): GuildConnection
|
||||
|
||||
# the number of voice connections
|
||||
voiceConnectionCount: Int
|
||||
|
||||
# the bot user
|
||||
user: User
|
||||
|
||||
# the current average ping
|
||||
ping: Float
|
||||
|
||||
# the websocket status
|
||||
status: Int
|
||||
|
||||
# the total uptime
|
||||
uptime: Int
|
||||
}
|
||||
|
||||
type LogEntry {
|
||||
|
||||
# the id of the log entry
|
||||
id: ID!
|
||||
|
||||
# the message of the log entry
|
||||
message: String
|
||||
|
||||
# the level of the log entry
|
||||
level: Level
|
||||
|
||||
# the timestamp of the log entry
|
||||
timestamp: String
|
||||
|
||||
# the module that created the log entry
|
||||
module: String
|
||||
}
|
||||
|
||||
type Query {
|
||||
|
||||
# The bots client
|
||||
client: Client
|
||||
|
||||
# the presences in the presence rotation
|
||||
presences: [String]!
|
||||
|
||||
# the prefix for commands
|
||||
prefix: String
|
||||
|
||||
# The log entries generated in the current runtime.
|
||||
#
|
||||
# Arguments
|
||||
# first: the number of entries to get
|
||||
# offset: the offset of the entries
|
||||
# id: get the log entry by id
|
||||
# last: oposite of first - the latest entries
|
||||
# level: filter by loglevel
|
||||
logs(
|
||||
first: Int,
|
||||
offset: Int = 0,
|
||||
id: String,
|
||||
last: Int = 10,
|
||||
level: LogLevel
|
||||
): [LogEntry]
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
|
||||
# adds media to the queue
|
||||
#
|
||||
# Arguments
|
||||
# guildId: the id of the guild
|
||||
# url: the url to the media YouTube video
|
||||
addMediaToQueue(
|
||||
guildId: ID!,
|
||||
url: String!
|
||||
): MusicPlayer
|
||||
|
||||
# removes media from the queue
|
||||
#
|
||||
# Arguments
|
||||
# guildId: the id of the guild
|
||||
# entryId: the id of the media entry to remove
|
||||
removeMediaFromQueue(
|
||||
guildId: ID!,
|
||||
entryId: ID!
|
||||
): MusicPlayer
|
||||
|
||||
# skips to the next song
|
||||
#
|
||||
# Arguments
|
||||
# guildId: the id of the guild
|
||||
skipSong(guildId: ID!): MusicPlayer
|
||||
|
||||
# toggles between pause and play
|
||||
#
|
||||
# Arguments
|
||||
# guildId: the id of the guild
|
||||
togglePause(guildId: ID!): MusicPlayer
|
||||
|
||||
# toggles repeat
|
||||
#
|
||||
# Arguments
|
||||
# guildId: the id of the guild
|
||||
toggleRepeat(guildId: ID!): MusicPlayer
|
||||
|
||||
# stops the music
|
||||
#
|
||||
# Arguments
|
||||
# guildId: the id of the guild
|
||||
stopMusic(guildId: ID!): MusicPlayer
|
||||
}
|
Loading…
Reference in New Issue