v7 stuff lots of stuff

This commit is contained in:
Skillz
2020-08-05 14:31:08 -04:00
parent f46362114d
commit a7f9bf6b94
38 changed files with 8984 additions and 5059 deletions
+8931 -5071
View File
File diff suppressed because it is too large Load Diff
+40 -40
View File
@@ -5,52 +5,52 @@
"author": "Praveen <praveen@hasura.io> (@praveenweb)", "author": "Praveen <praveen@hasura.io> (@praveenweb)",
"version": "0.0.1", "version": "0.0.1",
"dependencies": { "dependencies": {
"@babel/plugin-proposal-export-default-from": "^7.7.4", "@babel/plugin-proposal-export-default-from": "^7.10.4",
"@emotion/core": "^10.0.22", "@emotion/core": "^10.0.28",
"@emotion/styled": "^10.0.23", "@emotion/styled": "^10.0.27",
"@emotion/styled-base": "^10.0.24", "@emotion/styled-base": "^10.0.31",
"@mdx-js/loader": "^1.5.1", "@mdx-js/loader": "^1.6.16",
"@mdx-js/mdx": "^1.5.1", "@mdx-js/mdx": "^1.6.16",
"@mdx-js/react": "^1.5.1", "@mdx-js/react": "^1.6.16",
"@philpl/buble": "^0.19.7", "@philpl/buble": "^0.19.7",
"@playlyfe/gql": "^2.6.2", "@playlyfe/gql": "^2.6.2",
"algoliasearch": "^3.35.1", "algoliasearch": "^3.35.1",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"emotion": "^10.0.23", "emotion": "^10.0.27",
"emotion-server": "^10.0.17", "emotion-server": "^10.0.27",
"emotion-theming": "^10.0.19", "emotion-theming": "^10.0.27",
"gatsby": "^2.18.10", "gatsby": "^2.24.27",
"gatsby-link": "^2.2.27", "gatsby-link": "^2.4.13",
"gatsby-plugin-algolia": "^0.5.0", "gatsby-plugin-algolia": "^0.5.0",
"gatsby-plugin-emotion": "^4.1.18", "gatsby-plugin-emotion": "^4.3.10",
"gatsby-plugin-gtag": "^1.0.12", "gatsby-plugin-gtag": "^1.0.13",
"gatsby-plugin-layout": "^1.1.18", "gatsby-plugin-layout": "^1.3.10",
"gatsby-plugin-manifest": "^2.2.33", "gatsby-plugin-manifest": "^2.4.21",
"gatsby-plugin-mdx": "^1.0.61", "gatsby-plugin-mdx": "^1.2.33",
"gatsby-plugin-offline": "^3.0.29", "gatsby-plugin-offline": "^3.2.21",
"gatsby-plugin-react-helmet": "^3.1.18", "gatsby-plugin-react-helmet": "^3.3.10",
"gatsby-plugin-remove-serviceworker": "^1.0.0", "gatsby-plugin-remove-serviceworker": "^1.0.0",
"gatsby-plugin-sharp": "^2.3.7", "gatsby-plugin-sharp": "^2.6.24",
"gatsby-plugin-sitemap": "^2.2.24", "gatsby-plugin-sitemap": "^2.4.11",
"gatsby-remark-copy-linked-files": "^2.1.33", "gatsby-remark-copy-linked-files": "^2.3.12",
"gatsby-remark-images": "^3.1.37", "gatsby-remark-images": "^3.3.24",
"gatsby-source-filesystem": "^2.1.42", "gatsby-source-filesystem": "^2.3.23",
"gatsby-transformer-remark": "^2.6.42", "gatsby-transformer-remark": "^2.8.27",
"graphql": "^14.5.8", "graphql": "^14.7.0",
"is-absolute-url": "^3.0.3", "is-absolute-url": "^3.0.3",
"lodash.flatten": "^4.4.0", "lodash.flatten": "^4.4.0",
"lodash.startcase": "^4.4.0", "lodash.startcase": "^4.4.0",
"react": "^16.12.0", "react": "^16.13.1",
"react-dom": "^16.12.0", "react-dom": "^16.13.1",
"react-feather": "^2.0.3", "react-feather": "^2.0.8",
"react-github-btn": "^1.1.1", "react-github-btn": "^1.2.0",
"react-helmet": "^5.2.1", "react-helmet": "^5.2.1",
"react-id-generator": "^3.0.0", "react-id-generator": "^3.0.1",
"react-instantsearch-dom": "^6.0.0", "react-instantsearch-dom": "^6.7.0",
"react-live": "^2.2.2", "react-live": "^2.2.2",
"react-loadable": "^5.5.0", "react-loadable": "^5.5.0",
"styled-components": "^4.4.1", "styled-components": "^4.4.1",
"styled-icons": "^9.0.1" "styled-icons": "^9.5.0"
}, },
"license": "MIT", "license": "MIT",
"main": "n/a", "main": "n/a",
@@ -63,13 +63,13 @@
"devDependencies": { "devDependencies": {
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",
"eslint": "^6.8.0", "eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.0", "eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "^2.20.1", "eslint-plugin-import": "^2.22.0",
"eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-jsx-a11y": "^6.3.1",
"eslint-plugin-prettier": "^3.1.2", "eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-react": "^7.19.0", "eslint-plugin-react": "^7.20.5",
"gatsby-plugin-remove-trailing-slashes": "^2.1.17", "gatsby-plugin-remove-trailing-slashes": "^2.3.11",
"prettier": "^1.19.1", "prettier": "^1.19.1",
"prism-react-renderer": "^1.0.2" "prism-react-renderer": "^1.1.1"
} }
} }
@@ -32,8 +32,8 @@ export function hasChannelPermission(
return permissions.every((perm) => { return permissions.every((perm) => {
if (overwrite) { if (overwrite) {
if (overwrite.deny & perm) return false; if (BigInt(overwrite.deny_new) & BigInt(perm)) return false;
if (overwrite.allow & perm) return true; if (BigInt(overwrite.allow_new) & BigInt(perm)) return true;
} }
if (channel.guildID) { if (channel.guildID) {
return botHasPermission(channel.guildID, [perm]); return botHasPermission(channel.guildID, [perm]);
@@ -122,7 +122,7 @@ export async function sendMessage(
if ( if (
content.tts && content.tts &&
!botHasChannelPermissions( !botHasChannelPermissions(
channel.guildID, channel.id,
[Permissions.SEND_TTS_MESSAGES], [Permissions.SEND_TTS_MESSAGES],
) )
) { ) {
@@ -130,7 +130,12 @@ export async function sendMessage(
} }
} }
if (content.content && content.content.length > 2000) { if (content.embed && !botHasChannelPermissions(channel.id, [Permissions.EMBED_LINKS])) {
throw new Error(Errors.MISSING_EMBED_LINKS)
}
// Use ... for content length due to unicode characters and js .length handling
if (content.content && [...content.content].length > 2000) {
throw new Error(Errors.MESSAGE_MAX_LENGTH); throw new Error(Errors.MESSAGE_MAX_LENGTH);
} }
@@ -315,12 +320,12 @@ export function editChannel(channel: Channel, options: ChannelEditOptions) {
return { return {
...overwrite, ...overwrite,
allow: overwrite.allow.reduce( allow: overwrite.allow.reduce(
(bits, perm) => bits |= Permissions[perm], (bits, perm) => bits |= BigInt(Permissions[perm]),
0, BigInt(0),
), ),
deny: overwrite.deny.reduce( deny: overwrite.deny.reduce(
(bits, perm) => bits |= Permissions[perm], (bits, perm) => bits |= BigInt(Permissions[perm]),
0, BigInt(0),
), ),
}; };
}, },
+21 -8
View File
@@ -105,8 +105,14 @@ export async function createGuildChannel(
name, name,
permission_overwrites: options?.permission_overwrites?.map((perm) => ({ permission_overwrites: options?.permission_overwrites?.map((perm) => ({
...perm, ...perm,
allow: perm.allow.map((p) => Permissions[p]), allow: perm.allow.reduce(
deny: perm.deny.map((p) => Permissions[p]), (bits, p) => bits & BigInt(Permissions[p]),
BigInt(0),
).toString(),
deny: perm.deny.reduce(
(bits, p) => bits & BigInt(Permissions[p]),
BigInt(0),
).toString(),
})), })),
type: options?.type || ChannelTypes.GUILD_TEXT, type: options?.type || ChannelTypes.GUILD_TEXT,
})) as ChannelCreatePayload; })) as ChannelCreatePayload;
@@ -117,12 +123,16 @@ export async function createGuildChannel(
} }
/** Delete a channel in your server. Bot needs MANAGE_CHANNEL permissions in the server. */ /** Delete a channel in your server. Bot needs MANAGE_CHANNEL permissions in the server. */
export function deleteChannel(guildID: string, channelID: string, reason?: string) { export function deleteChannel(
guildID: string,
channelID: string,
reason?: string,
) {
if (!botHasPermission(guildID, [Permissions.MANAGE_CHANNELS])) { if (!botHasPermission(guildID, [Permissions.MANAGE_CHANNELS])) {
throw new Error(Errors.MISSING_MANAGE_CHANNELS); throw new Error(Errors.MISSING_MANAGE_CHANNELS);
} }
return RequestManager.delete(endpoints.CHANNEL(channelID), { reason }) return RequestManager.delete(endpoints.CHANNEL(channelID), { reason });
} }
/** Returns a list of guild channel objects. /** Returns a list of guild channel objects.
@@ -500,15 +510,18 @@ export function channelHasPermissions(
const role = guild.roles.get(roleID); const role = guild.roles.get(roleID);
if (!role) return bits; if (!role) return bits;
bits |= role.permissions; bits |= role.permissions.reduce(
(bits, p) => bits & BigInt(Permissions[p]),
BigInt(0),
);
return bits; return bits;
}, 0); }, BigInt(0));
if (permissionBits & Permissions.ADMINISTRATOR) return true; if (permissionBits & BigInt(Permissions.ADMINISTRATOR)) return true;
return permissions.every((permission) => return permissions.every((permission) =>
permissionBits & Permissions[permission] permissionBits & BigInt(Permissions[permission])
); );
} }
@@ -148,8 +148,7 @@ export async function handleDiscordPayload(
// Triggered on each shard // Triggered on each shard
eventHandlers.shardReady?.(shardID); eventHandlers.shardReady?.(shardID);
if (payload.shard && shardID === payload.shard[1] - 1) { if (payload.shard && shardID === payload.shard[1] - 1) {
// Delay 10 seconds to let all the guilds on this last shard load before ready is sent cache.isReady = true;
await delay(10000);
eventHandlers.ready?.(); eventHandlers.ready?.();
} }
// Wait 5 seconds to spawn next shard // Wait 5 seconds to spawn next shard
@@ -181,6 +180,7 @@ export async function handleDiscordPayload(
cache.unavailableGuilds.delete(options.id); cache.unavailableGuilds.delete(options.id);
} }
if (!cache.isReady) return eventHandlers.guildLoaded?.(guild);
return eventHandlers.guildCreate?.(guild); return eventHandlers.guildCreate?.(guild);
} }
@@ -21,8 +21,8 @@ export function createChannel(data: ChannelCreatePayload, guildID?: string) {
permissions: data.permission_overwrites permissions: data.permission_overwrites
? data.permission_overwrites.map((perm) => ({ ? data.permission_overwrites.map((perm) => ({
...perm, ...perm,
allow: calculatePermissions(perm.allow), allow: calculatePermissions(BigInt(perm.allow_new)),
deny: calculatePermissions(perm.deny), deny: calculatePermissions(BigInt(perm.deny_new)),
})) }))
: [], : [],
/** Whether this channel is nsfw or not */ /** Whether this channel is nsfw or not */
@@ -1,7 +1,9 @@
import { RoleData } from "../types/role.ts"; import { RoleData } from "../types/role.ts";
import { calculatePermissions } from "../utils/permissions.ts";
export const createRole = (data: RoleData) => ({ export const createRole = (data: RoleData) => ({
...data, ...data,
permissions: calculatePermissions(BigInt(data.permissions_new)),
/** The @ mention of the role in a string. */ /** The @ mention of the role in a string. */
mention: `<@&${data.id}>`, mention: `<@&${data.id}>`,
}); });
+1 -1
View File
@@ -1,4 +1,4 @@
import { Timestamps } from "../types/discord.ts"; import { Timestamps } from "./discord.ts";
export interface ActivityPayload { export interface ActivityPayload {
name: string; name: string;
View File
+17 -3
View File
@@ -1,4 +1,4 @@
import { Raw_Overwrite, Overwrite } from "./guild.ts"; import { RawOverwrite, Overwrite } from "./guild.ts";
import { Embed } from "./message.ts"; import { Embed } from "./message.ts";
export interface ChannelEditOptions { export interface ChannelEditOptions {
@@ -71,14 +71,28 @@ export interface ChannelCreatePayload extends Base_Channel_Create {
/** The type of the channel */ /** The type of the channel */
type: Channel_Type; type: Channel_Type;
/** Explicit permission overwrites for members and roles */ /** Explicit permission overwrites for members and roles */
permission_overwrites?: Raw_Overwrite[]; permission_overwrites?: RawOverwrite[];
} }
export interface CreateChannelOptions extends Base_Channel_Create { export interface CreateChannelOptions {
/** The type of the channel */ /** The type of the channel */
type?: ChannelTypes; type?: ChannelTypes;
/** The channel topic (0-1024 characters) */
topic?: string;
/** The bitrate (in bits) of the voice channel */
bitrate?: number;
/** The user limit of the voice channel */
user_limit?: number;
/** Amount of seconds a user has to wait before sending another message (0-21600) Bots and users with the permission MANAGE_MESSAGES or MANAGE_CHANNEL are unaffected. */
rate_limit_per_user?: number;
/** Sorting position of the channel */
position?: number;
/** Explicit permission overwrites for members and roles */ /** Explicit permission overwrites for members and roles */
permission_overwrites?: Overwrite[]; permission_overwrites?: Overwrite[];
/** The parent category id */
parent_id?: string | null;
/** Whether the channel is nsfw */
nsfw?: boolean;
} }
export type Channel_Type = 0 | 1 | 2 | 4 | 5 | 6; export type Channel_Type = 0 | 1 | 2 | 4 | 5 | 6;
+1
View File
@@ -16,6 +16,7 @@ export enum Errors {
MISSING_BAN_MEMBERS = "MISSING_BAN_MEMBERS", MISSING_BAN_MEMBERS = "MISSING_BAN_MEMBERS",
MISSING_MANAGE_GUILD = "MISSING_MANAGE_GUILD", MISSING_MANAGE_GUILD = "MISSING_MANAGE_GUILD",
MISSING_VIEW_AUDIT_LOG = "MISSING_VIEW_AUDIT_LOG", MISSING_VIEW_AUDIT_LOG = "MISSING_VIEW_AUDIT_LOG",
MISSING_EMBED_LINKS = "MISSING_EMBED_LINKS",
DELETE_MESSAGES_MIN = "DELETE_MESSAGES_MIN", DELETE_MESSAGES_MIN = "DELETE_MESSAGES_MIN",
MESSAGE_MAX_LENGTH = "MESSAGE_MAX_LENGTH", MESSAGE_MAX_LENGTH = "MESSAGE_MAX_LENGTH",
NICKNAMES_MAX_LENGTH = "NICKNAMES_MAX_LENGTH", NICKNAMES_MAX_LENGTH = "NICKNAMES_MAX_LENGTH",
+5 -1
View File
@@ -465,7 +465,7 @@ export interface Overwrite {
deny: Permission[]; deny: Permission[];
} }
export interface Raw_Overwrite { export interface RawOverwrite {
/** The role or user id */ /** The role or user id */
id: string; id: string;
/** Whether this is a role or a member */ /** Whether this is a role or a member */
@@ -474,6 +474,10 @@ export interface Raw_Overwrite {
allow: number; allow: number;
/** The permissions that this id is NOT allowed to do. (This will mark it as a red x.) */ /** The permissions that this id is NOT allowed to do. (This will mark it as a red x.) */
deny: number; deny: number;
/** permission bit set for new perms until new api version released. */
allow_new: string;
/** permission bit set for new perms until new api version released. */
deny_new: string;
} }
export interface ChannelCreate_Options { export interface ChannelCreate_Options {
@@ -83,6 +83,7 @@ export interface EventHandlers {
guildBanAdd?: (guild: Guild, user: Member | UserPayload) => unknown; guildBanAdd?: (guild: Guild, user: Member | UserPayload) => unknown;
guildBanRemove?: (guild: Guild, user: Member | UserPayload) => unknown; guildBanRemove?: (guild: Guild, user: Member | UserPayload) => unknown;
guildCreate?: (guild: Guild) => unknown; guildCreate?: (guild: Guild) => unknown;
guildLoaded?: (guild: Guild) => unknown;
guildUpdate?: (guild: Guild, changes: GuildUpdateChange[]) => unknown; guildUpdate?: (guild: Guild, changes: GuildUpdateChange[]) => unknown;
guildDelete?: (guild: Guild) => unknown; guildDelete?: (guild: Guild) => unknown;
guildEmojisUpdate?: ( guildEmojisUpdate?: (
+1 -1
View File
@@ -1,4 +1,4 @@
import { StatusType } from "../types/discord.ts"; import { StatusType } from "./discord.ts";
export interface ClientStatusPayload { export interface ClientStatusPayload {
/** The user's status set for an active desktop (Windows, Linux, Mac) application session */ /** The user's status set for an active desktop (Windows, Linux, Mac) application session */
+2
View File
@@ -11,6 +11,8 @@ export interface RoleData {
position: number; position: number;
/** permission bit set */ /** permission bit set */
permissions: number; permissions: number;
/** permission bit set */
permissions_new: string;
/** whether this role is managed by an integration */ /** whether this role is managed by an integration */
managed: boolean; managed: boolean;
/** whether this role is mentionable */ /** whether this role is mentionable */
+2
View File
@@ -6,6 +6,7 @@ import { delay } from "https://deno.land/std@0.61.0/async/delay.ts";
import { PresenceUpdatePayload } from "../types/discord.ts"; import { PresenceUpdatePayload } from "../types/discord.ts";
export interface CacheData { export interface CacheData {
isReady: boolean;
guilds: Collection<string, Guild>; guilds: Collection<string, Guild>;
channels: Collection<string, Channel>; channels: Collection<string, Channel>;
messages: Collection<string, Message>; messages: Collection<string, Message>;
@@ -14,6 +15,7 @@ export interface CacheData {
} }
export const cache: CacheData = { export const cache: CacheData = {
isReady: false,
guilds: new Collection(), guilds: new Collection(),
channels: new Collection(), channels: new Collection(),
messages: new Collection(), messages: new Collection(),
View File
@@ -1,4 +1,7 @@
import { Permission, Permissions } from "../types/permission.ts"; import {
Permission,
Permissions,
} from "../types/permission.ts";
import { cache } from "./cache.ts"; import { cache } from "./cache.ts";
import { botID } from "../module/client.ts"; import { botID } from "../module/client.ts";
import { Role } from "../structures/role.ts"; import { Role } from "../structures/role.ts";
@@ -14,17 +17,20 @@ export function memberHasPermission(
if (memberID === guild.ownerID) return true; if (memberID === guild.ownerID) return true;
const permissionBits = memberRoleIDs.map((id) => const permissionBits = memberRoleIDs.map((id) =>
guild.roles.get(id)?.permissions || 0 guild.roles.get(id)?.permissions || []
) )
.reduce((bits, permissions) => { .reduce((bits, permissions) => {
bits |= permissions; bits |= permissions.reduce(
(b, p) => b & BigInt(Permissions[p]),
BigInt(0),
);
return bits; return bits;
}, 0); }, BigInt(0));
if (permissionBits & Permissions.ADMINISTRATOR) return true; if (permissionBits & BigInt(Permissions.ADMINISTRATOR)) return true;
return permissions.every((permission) => return permissions.every((permission) =>
permissionBits & Permissions[permission] permissionBits & BigInt(Permissions[permission])
); );
} }
@@ -38,14 +44,17 @@ export function botHasPermission(guildID: string, permissions: Permissions[]) {
const permissionBits = member.roles const permissionBits = member.roles
.map((id) => guild.roles.get(id)!) .map((id) => guild.roles.get(id)!)
.reduce((bits, data) => { .reduce((bits, data) => {
bits |= data.permissions; bits |= data.permissions.reduce(
(b, p) => b & BigInt(Permissions[p]),
BigInt(0),
);
return bits; return bits;
}, 0); }, BigInt(0));
if (permissionBits & Permissions.ADMINISTRATOR) return true; if (permissionBits & BigInt(Permissions.ADMINISTRATOR)) return true;
return permissions.every((permission) => permissionBits & permission); return permissions.every((permission) => permissionBits & BigInt(permission));
} }
/** Checks if the bot has the permissions in a channel */ /** Checks if the bot has the permissions in a channel */
@@ -90,14 +99,20 @@ export function hasChannelPermissions(
if (memberOverwrite) { if (memberOverwrite) {
// One of the necessary permissions is denied // One of the necessary permissions is denied
if (permissions.some((perm) => memberOverwrite.deny & perm)) { if (
permissions.some((perm) =>
BigInt(memberOverwrite.deny_new) & BigInt(perm)
)
) {
return false; return false;
} }
permissions.forEach((perm) => { permissions.forEach((perm) => {
// Already allowed perm // Already allowed perm
if (allowedPermissions.has(perm)) return; if (allowedPermissions.has(perm)) return;
// This perm is allowed so we save it // This perm is allowed so we save it
if (memberOverwrite.allow & perm) allowedPermissions.add(perm); if (BigInt(memberOverwrite.allow_new) & BigInt(perm)) {
allowedPermissions.add(perm);
}
}); });
} }
@@ -106,11 +121,11 @@ export function hasChannelPermissions(
if ( if (
rolesOverwrites.some((overwrite) => rolesOverwrites.some((overwrite) =>
permissions.some((perm) => permissions.some((perm) =>
(overwrite.deny & perm) && (BigInt(overwrite.deny_new) & BigInt(perm)) &&
// If another role allows these perms then they are not denied // If another role allows these perms then they are not denied
!rolesOverwrites.some((o) => o.allow & perm) && !rolesOverwrites.some((o) => BigInt(o.allow_new) & BigInt(perm)) &&
// Make sure the memberOverwrite does not allow this perm // Make sure the memberOverwrite does not allow this perm
!(memberOverwrite && memberOverwrite.allow & perm) !(memberOverwrite && BigInt(memberOverwrite.allow_new) & BigInt(perm))
) )
) )
) { ) {
@@ -122,7 +137,9 @@ export function hasChannelPermissions(
if (allowedPermissions.has(perm)) return; if (allowedPermissions.has(perm)) return;
rolesOverwrites.forEach((overwrite) => { rolesOverwrites.forEach((overwrite) => {
// This perm is allowed so we save it // This perm is allowed so we save it
if (overwrite.allow & perm) allowedPermissions.add(perm); if (BigInt(overwrite.allow_new) & BigInt(perm)) {
allowedPermissions.add(perm);
}
}); });
}); });
} }
@@ -133,14 +150,17 @@ export function hasChannelPermissions(
) { ) {
if ( if (
permissions.some((perm) => permissions.some((perm) =>
everyoneOverwrite.deny & perm && !allowedPermissions.has(perm) BigInt(everyoneOverwrite.deny_new) & BigInt(perm) &&
!allowedPermissions.has(perm)
) )
) { ) {
return false; return false;
} }
// If all permissions are granted // If all permissions are granted
if ( if (
permissions.every((perm) => everyoneOverwrite.allow & perm) permissions.every((perm) =>
BigInt(everyoneOverwrite.allow_new) & BigInt(perm)
)
) { ) {
return true; return true;
} }
@@ -149,9 +169,10 @@ export function hasChannelPermissions(
return botHasPermission(guild.id, permissions); return botHasPermission(guild.id, permissions);
} }
export function calculatePermissions(permissionBits: number) { export function calculatePermissions(permissionBits: bigint) {
return Object.keys(Permissions).filter((perm) => { return Object.keys(Permissions).filter((perm) => {
return permissionBits & Permissions[perm as Permission]; if (typeof perm !== "number") return false;
return permissionBits & BigInt(Permissions[perm as Permission]);
}) as Permission[]; }) as Permission[];
} }