Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(GuildPreview): implement support for "preview" endpoint #3965

Merged
merged 34 commits into from
Mar 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
75112a3
feat(GuildPreview): method — fetchGuildPreview
kernel-dev Mar 19, 2020
db1629e
feat(GuildPreview): structure — GuildPreview
kernel-dev Mar 19, 2020
0e9ef65
feat(GuildPreview): update typings
kernel-dev Mar 19, 2020
4cefd9a
fix(GuildPreview): remove typedef for Features — already exists
SouSinner Mar 19, 2020
8517b2d
refactor(GuildPreview): update JSDocs & method
SouSinner Mar 19, 2020
645b7fa
feat(GuildPreview): implement DiscoverySplash function
SouSinner Mar 19, 2020
6b14afa
fix(GuildPreview): description & error handling for id
SouSinner Mar 19, 2020
debfb86
fix(GuildPreview): misleading description, assign emojis correctly
SouSinner Mar 19, 2020
ab3822d
feat(GuildPreview): func DisplaySplash & GuildPreviewEmoji interface
SouSinner Mar 19, 2020
da110a0
fix(Typings): satisfy TSLint
SouSinner Mar 19, 2020
7656115
fix(GuildPreview): toJSON - returns a value now
SouSinner Mar 19, 2020
13ab20f
feat(GuildPreview): add fetchPreview method on instance of Guild
SouSinner Mar 19, 2020
8c24e09
feat(GuildPreview): update typings
SouSinner Mar 19, 2020
79ab522
fix: missing client constructor
SouSinner Mar 19, 2020
2d07c03
fix: typo in typings
SouSinner Mar 20, 2020
4639fa7
Merge branch 'master' into master
iCrawl Mar 21, 2020
b11b2be
feat(BaseEmoji): implement BaseEmoji — parent for emoji instances
SouSinner Mar 21, 2020
7381111
feat(BaseEmoji): refactor - GuildEmoji extends BaseEmoji now
SouSinner Mar 21, 2020
2dc9dc1
feat(BaseEmoji): refactor - adjust emojis prop to BaseEmoji instance
SouSinner Mar 21, 2020
f98b432
feat(BaseEmoji): not documented fully - GuildPreviewEmoji
SouSinner Mar 21, 2020
83194b4
feat(BaseEmoji): update typings
SouSinner Mar 21, 2020
3eedf6f
Merge branch 'master' of https://github.com/SouSinner/discord.js
SouSinner Mar 21, 2020
83b8f00
fix: remove duplicate typing properties - inherited
SouSinner Mar 21, 2020
702e613
fix: remove redundant methods & properties - inherited / already set
SouSinner Mar 21, 2020
9174bef
fix: let -> const
SouSinner Mar 21, 2020
2fbfeef
fix: typings - put BaseEmoji after BaseClient
SouSinner Mar 22, 2020
28c7c56
fix: remove _clone method - redundant
SouSinner Mar 22, 2020
ec27d04
Merge branch 'master' into master
iCrawl Mar 23, 2020
f88ed88
refactor(GuildPreview): emojis should be a collection
SpaceEEC Mar 24, 2020
094c21d
refactor: rename base class, move relevant props there and expose roles
SpaceEEC Mar 24, 2020
8ce72cd
fix(GuildPreview): update emojis in _patch
SpaceEEC Mar 27, 2020
24e8a1a
fix(Typings): remove empty line, add Client#fetchGuildPreview
SpaceEEC Mar 27, 2020
1071856
feat: export GuildPreview
SpaceEEC Mar 27, 2020
a47b90b
fix(Typings): add GuildPreview#discoverSplash, icon, and splash
SpaceEEC Mar 27, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/client/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const GuildManager = require('../managers/GuildManager');
const UserManager = require('../managers/UserManager');
const ShardClientUtil = require('../sharding/ShardClientUtil');
const ClientApplication = require('../structures/ClientApplication');
const GuildPreview = require('../structures/GuildPreview');
const Invite = require('../structures/Invite');
const VoiceRegion = require('../structures/VoiceRegion');
const Webhook = require('../structures/Webhook');
Expand Down Expand Up @@ -338,6 +339,20 @@ class Client extends BaseClient {
.then(app => new ClientApplication(this, app));
}

/**
* Obtains a guild preview from Discord, only available for public guilds.
* @param {GuildResolvable} guild The guild to fetch the preview for
* @returns {Promise<GuildPreview>}
*/
fetchGuildPreview(guild) {
const id = this.guilds.resolveID(guild);
iCrawl marked this conversation as resolved.
Show resolved Hide resolved
if (!id) throw new TypeError('INVALID_TYPE', 'guild', 'GuildResolvable');
return this.api
.guilds(id)
.preview.get()
.then(data => new GuildPreview(this, data));
}

/**
* Generates a link that can be used to invite the bot to a guild.
* @param {PermissionResolvable} [permissions] Permissions to request
Expand Down
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ module.exports = {
Base: require('./structures/Base'),
Activity: require('./structures/Presence').Activity,
APIMessage: require('./structures/APIMessage'),
BaseGuildEmoji: require('./structures/BaseGuildEmoji'),
CategoryChannel: require('./structures/CategoryChannel'),
Channel: require('./structures/Channel'),
ClientApplication: require('./structures/ClientApplication'),
Expand All @@ -72,6 +73,7 @@ module.exports = {
GuildChannel: require('./structures/GuildChannel'),
GuildEmoji: require('./structures/GuildEmoji'),
GuildMember: require('./structures/GuildMember'),
GuildPreview: require('./structures/GuildPreview'),
Integration: require('./structures/Integration'),
Invite: require('./structures/Invite'),
Message: require('./structures/Message'),
Expand Down
58 changes: 58 additions & 0 deletions src/structures/BaseGuildEmoji.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use strict';

const Emoji = require('./Emoji');

/**
* Parent class for {@link GuildEmoji} and {@link GuildPreviewEmoji}.
* @extends {Emoji}
*/
class BaseGuildEmoji extends Emoji {
constructor(client, data, guild) {
super(client, data);

/**
* The guild this emoji is a part of
* @type {Guild|GuildPreview}
*/
this.guild = guild;

/**
* Array of role ids this emoji is active for
* @name BaseGuildEmoji#_roles
* @type {Snowflake[]}
* @private
*/
Object.defineProperty(this, '_roles', { value: [], writable: true });

this._patch(data);
}

_patch(data) {
if (data.name) this.name = data.name;

/**
* Whether or not this emoji requires colons surrounding it
* @type {boolean}
* @name GuildEmoji#requiresColons
*/
if (typeof data.require_colons !== 'undefined') this.requiresColons = data.require_colons;

/**
* Whether this emoji is managed by an external service
* @type {boolean}
* @name GuildEmoji#managed
*/
if (typeof data.managed !== 'undefined') this.managed = data.managed;

/**
* Whether this emoji is available
* @type {boolean}
* @name GuildEmoji#available
*/
if (typeof data.available !== 'undefined') this.available = data.available;

if (data.roles) this._roles = data.roles;
}
}

module.exports = BaseGuildEmoji;
12 changes: 12 additions & 0 deletions src/structures/Guild.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const Base = require('./Base');
const GuildAuditLogs = require('./GuildAuditLogs');
const GuildPreview = require('./GuildPreview');
const Integration = require('./Integration');
const Invite = require('./Invite');
const VoiceRegion = require('./VoiceRegion');
Expand Down Expand Up @@ -709,6 +710,17 @@ class Guild extends Base {
});
}

/**
* Obtains a guild preview for this guild from Discord, only available for public guilds.
* @returns {Promise<GuildPreview>}
*/
fetchPreview() {
return this.client.api
.guilds(this.id)
.preview.get()
.then(data => new GuildPreview(this.client, data));
}

/**
* Fetches the vanity url invite code to this guild.
* Resolves with a string matching the vanity url invite code, not the full url.
Expand Down
58 changes: 11 additions & 47 deletions src/structures/GuildEmoji.js
Original file line number Diff line number Diff line change
@@ -1,65 +1,29 @@
'use strict';

const Emoji = require('./Emoji');
const BaseGuildEmoji = require('./BaseGuildEmoji');
const { Error } = require('../errors');
const GuildEmojiRoleManager = require('../managers/GuildEmojiRoleManager');
const Permissions = require('../util/Permissions');

/**
* Represents a custom emoji.
* @extends {Emoji}
* @extends {BaseGuildEmoji}
*/
class GuildEmoji extends Emoji {
class GuildEmoji extends BaseGuildEmoji {
/**
* @name GuildEmoji
* @kind constructor
* @memberof GuildEmoji
* @param {Client} client The instantiating client
* @param {Object} data The data for the guild emoji
* @param {Guild} guild The guild the guild emoji is part of
*/
constructor(client, data, guild) {
super(client, data);

/**
* The guild this emoji is part of
* @type {Guild}
*/
this.guild = guild;

/**
* The ID of this emoji
* @type {Snowflake}
* @name GuildEmoji#id
*/

this._roles = [];
this._patch(data);
}

_patch(data) {
if (data.name) this.name = data.name;

/**
* Whether or not this emoji requires colons surrounding it
* @type {boolean}
* @name GuildEmoji#requiresColons
*/
if (typeof data.require_colons !== 'undefined') this.requiresColons = data.require_colons;

/**
* Whether this emoji is managed by an external service
* @type {boolean}
* @name GuildEmoji#managed
*/
if (typeof data.managed !== 'undefined') this.managed = data.managed;

/**
* Whether this emoji is available
* @type {boolean}
* @name GuildEmoji#available
*/
if (typeof data.available !== 'undefined') this.available = data.available;

if (data.roles) this._roles = data.roles;
}
/**
* The guild this emoji is part of
* @type {Guild}
* @name GuildEmoji#guild
*/

_clone() {
const clone = super._clone();
Expand Down
157 changes: 157 additions & 0 deletions src/structures/GuildPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
'use strict';

const Base = require('./Base');
const GuildPreviewEmoji = require('./GuildPreviewEmoji');
const Collection = require('../util/Collection');

/**
* Represents the data about the guild any bot can preview, connected to the specified public guild.
* @extends {Base}
*/
iCrawl marked this conversation as resolved.
Show resolved Hide resolved
class GuildPreview extends Base {
constructor(client, data) {
super(client);

if (!data) return;

this._patch(data);
}

/**
* Builds the public guild with the provided data.
* @param {*} data The raw data of the public guild
* @private
*/
_patch(data) {
/**
* The id of this public guild
* @type {string}
*/
this.id = data.id;

/**
* The name of this public guild
* @type {string}
*/
this.name = data.name;

/**
* The icon of this public guild
* @type {?string}
*/
this.icon = data.icon;

/**
* The splash icon of this public guild
* @type {?string}
*/
this.splash = data.splash;

/**
* The discovery splash icon of this public guild
* @type {?string}
*/
this.discoverySplash = data.discovery_splash;

/**
* An array of enabled guild features
* @type {Features[]}
*/
this.features = data.features;

/**
* The approximate count of members in this public guild
* @type {number}
*/
this.approximateMemberCount = data.approximate_member_count;

/**
* The approximate count of online members in this public guild
* @type {number}
*/
this.approximatePresenceCount = data.approximate_presence_count;

/**
* The description for this public guild
* @type {?string}
*/
this.description = data.description;

if (!this.emojis) {
/**
* Collection of emojis belonging to this public guild
* @type {Collection<Snowflake, GuildPreviewEmoji>}
*/
this.emojis = new Collection();
} else {
this.emojis.clear();
}
for (const emoji of data.emojis) {
this.emojis.set(emoji.id, new GuildPreviewEmoji(this.client, emoji, this));
}
}

/**
* The URL to this public guild's splash.
* @param {ImageURLOptions} [options={}] Options for the Image URL
* @returns {?string}
*/
splashURL({ format, size } = {}) {
if (!this.splash) return null;
return this.client.rest.cdn.Splash(this.id, this.splash, format, size);
}

/**
* The URL to this public guild's discovery splash.
* @param {ImageURLOptions} [options={}] Options for the Image URL
* @returns {?string}
*/
discoverySplashURL({ format, size } = {}) {
if (!this.discoverySplash) return null;
return this.client.rest.cdn.DiscoverySplash(this.id, this.discoverySplash, format, size);
}

/**
* The URL to this public guild's icon.
* @param {ImageURLOptions} [options={}] Options for the Image URL
* @returns {?string}
*/
iconURL({ format, size, dynamic } = {}) {
if (!this.icon) return null;
return this.client.rest.cdn.Icon(this.id, this.icon, format, size, dynamic);
}

/**
* Fetches this public guild.
iCrawl marked this conversation as resolved.
Show resolved Hide resolved
* @returns {Promise<GuildPreview>}
*/
fetch() {
return this.client.api
.guilds(this.id)
.preview.get()
.then(data => {
this._patch(data);
return this;
});
}

/**
* When concatenated with a string, this automatically returns the guild's name instead of the Guild object.
* @returns {string}
* @example
* // Logs: Hello from My Guild!
* console.log(`Hello from ${previewGuild}!`);
*/
toString() {
return this.name;
}

toJSON() {
iCrawl marked this conversation as resolved.
Show resolved Hide resolved
const json = super.toJSON();
json.iconURL = this.iconURL();
json.splashURL = this.splashURL();
return json;
}
}

module.exports = GuildPreview;
26 changes: 26 additions & 0 deletions src/structures/GuildPreviewEmoji.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

const BaseGuildEmoji = require('./BaseGuildEmoji');

/**
* Represents an instance of an emoji belonging to a public guild obtained through Discord's preview endpoint.
* @extends {BaseGuildEmoji}
*/
class GuildPreviewEmoji extends BaseGuildEmoji {
/**
* The public guild this emoji is part of
* @type {GuildPreview}
* @name GuildPreviewEmoji#guild
*/

/**
* Set of roles this emoji is active for
* @type {Set<Snowflake>}
* @readonly
*/
get roles() {
return new Set(this._roles);
}
}

module.exports = GuildPreviewEmoji;
Loading