Merge pull request #107 from DjDeveloperr/permissions
fix: use bigint for bitfield (permissions)
This commit is contained in:
commit
4d93d66757
3 changed files with 75 additions and 70 deletions
|
@ -1,35 +1,36 @@
|
|||
// https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags
|
||||
|
||||
export const PermissionFlags: { [key: string]: number } = {
|
||||
CREATE_INSTANT_INVITE: 1 << 0,
|
||||
KICK_MEMBERS: 1 << 1,
|
||||
BAN_MEMBERS: 1 << 2,
|
||||
ADMINISTRATOR: 1 << 3,
|
||||
MANAGE_CHANNELS: 1 << 4,
|
||||
MANAGE_GUILD: 1 << 5,
|
||||
ADD_REACTIONS: 1 << 6,
|
||||
VIEW_AUDIT_LOG: 1 << 7,
|
||||
PRIORITY_SPEAKER: 1 << 8,
|
||||
STREAM: 1 << 9,
|
||||
VIEW_CHANNEL: 1 << 10,
|
||||
SEND_MESSAGES: 1 << 11,
|
||||
SEND_TTS_MESSAGES: 1 << 12,
|
||||
MANAGE_MESSAGES: 1 << 13,
|
||||
EMBED_LINKS: 1 << 14,
|
||||
ATTACH_FILES: 1 << 15,
|
||||
READ_MESSAGE_HISTORY: 1 << 16,
|
||||
MENTION_EVERYONE: 1 << 17,
|
||||
USE_EXTERNAL_EMOJIS: 1 << 18,
|
||||
VIEW_GUILD_INSIGHTS: 1 << 19,
|
||||
CONNECT: 1 << 20,
|
||||
SPEAK: 1 << 21,
|
||||
MUTE_MEMBERS: 1 << 22,
|
||||
DEAFEN_MEMBERS: 1 << 23,
|
||||
MOVE_MEMBERS: 1 << 24,
|
||||
USE_VAD: 1 << 25,
|
||||
CHANGE_NICKNAME: 1 << 26,
|
||||
MANAGE_NICKNAMES: 1 << 27,
|
||||
MANAGE_ROLES: 1 << 28,
|
||||
MANAGE_WEBHOOKS: 1 << 29,
|
||||
MANAGE_EMOJIS: 1 << 30
|
||||
export const PermissionFlags: { [key: string]: bigint } = {
|
||||
CREATE_INSTANT_INVITE: 1n << 0n,
|
||||
KICK_MEMBERS: 1n << 1n,
|
||||
BAN_MEMBERS: 1n << 2n,
|
||||
ADMINISTRATOR: 1n << 3n,
|
||||
MANAGE_CHANNELS: 1n << 4n,
|
||||
MANAGE_GUILD: 1n << 5n,
|
||||
ADD_REACTIONS: 1n << 6n,
|
||||
VIEW_AUDIT_LOG: 1n << 7n,
|
||||
PRIORITY_SPEAKER: 1n << 8n,
|
||||
STREAM: 1n << 9n,
|
||||
VIEW_CHANNEL: 1n << 10n,
|
||||
SEND_MESSAGES: 1n << 11n,
|
||||
SEND_TTS_MESSAGES: 1n << 12n,
|
||||
MANAGE_MESSAGES: 1n << 13n,
|
||||
EMBED_LINKS: 1n << 14n,
|
||||
ATTACH_FILES: 1n << 15n,
|
||||
READ_MESSAGE_HISTORY: 1n << 16n,
|
||||
MENTION_EVERYONE: 1n << 17n,
|
||||
USE_EXTERNAL_EMOJIS: 1n << 18n,
|
||||
VIEW_GUILD_INSIGHTS: 1n << 19n,
|
||||
CONNECT: 1n << 20n,
|
||||
SPEAK: 1n << 21n,
|
||||
MUTE_MEMBERS: 1n << 22n,
|
||||
DEAFEN_MEMBERS: 1n << 23n,
|
||||
MOVE_MEMBERS: 1n << 24n,
|
||||
USE_VAD: 1n << 25n,
|
||||
CHANGE_NICKNAME: 1n << 26n,
|
||||
MANAGE_NICKNAMES: 1n << 27n,
|
||||
MANAGE_ROLES: 1n << 28n,
|
||||
MANAGE_WEBHOOKS: 1n << 29n,
|
||||
MANAGE_EMOJIS: 1n << 30n,
|
||||
USE_SLASH_COMMANDS: 1n << 31n
|
||||
}
|
||||
|
|
|
@ -6,34 +6,36 @@ export type BitFieldResolvable =
|
|||
| string
|
||||
| string[]
|
||||
| BitField[]
|
||||
| bigint
|
||||
| Array<bigint>
|
||||
|
||||
/** Bit Field utility to work with Bits and Flags */
|
||||
export class BitField {
|
||||
flags: { [name: string]: number } = {}
|
||||
bitfield: number
|
||||
#flags: { [name: string]: number | bigint } = {}
|
||||
bitfield: bigint
|
||||
|
||||
constructor(flags: { [name: string]: number }, bits: any) {
|
||||
this.flags = flags
|
||||
this.bitfield = BitField.resolve(this.flags, bits)
|
||||
constructor(flags: { [name: string]: number | bigint }, bits: any) {
|
||||
this.#flags = flags
|
||||
this.bitfield = BitField.resolve(this.#flags, bits)
|
||||
}
|
||||
|
||||
any(bit: BitFieldResolvable): boolean {
|
||||
return (this.bitfield & BitField.resolve(this.flags, bit)) !== 0
|
||||
return (this.bitfield & BitField.resolve(this.#flags, bit)) !== 0n
|
||||
}
|
||||
|
||||
equals(bit: BitFieldResolvable): boolean {
|
||||
return this.bitfield === BitField.resolve(this.flags, bit)
|
||||
return this.bitfield === BitField.resolve(this.#flags, bit)
|
||||
}
|
||||
|
||||
has(bit: BitFieldResolvable, ...args: any[]): boolean {
|
||||
if (Array.isArray(bit)) return (bit.every as any)((p: any) => this.has(p))
|
||||
bit = BitField.resolve(this.flags, bit)
|
||||
bit = BitField.resolve(this.#flags, bit)
|
||||
return (this.bitfield & bit) === bit
|
||||
}
|
||||
|
||||
missing(bits: any, ...hasParams: any[]): string[] {
|
||||
if (!Array.isArray(bits))
|
||||
bits = new BitField(this.flags, bits).toArray(false)
|
||||
bits = new BitField(this.#flags, bits).toArray(false)
|
||||
return bits.filter((p: any) => !this.has(p, ...hasParams))
|
||||
}
|
||||
|
||||
|
@ -42,48 +44,52 @@ export class BitField {
|
|||
}
|
||||
|
||||
add(...bits: BitFieldResolvable[]): BitField {
|
||||
let total = 0
|
||||
let total = 0n
|
||||
for (const bit of bits) {
|
||||
total |= BitField.resolve(this.flags, bit)
|
||||
total |= BitField.resolve(this.#flags, bit)
|
||||
}
|
||||
if (Object.isFrozen(this))
|
||||
return new BitField(this.flags, this.bitfield | total)
|
||||
return new BitField(this.#flags, this.bitfield | total)
|
||||
this.bitfield |= total
|
||||
return this
|
||||
}
|
||||
|
||||
remove(...bits: BitFieldResolvable[]): BitField {
|
||||
let total = 0
|
||||
let total = 0n
|
||||
for (const bit of bits) {
|
||||
total |= BitField.resolve(this.flags, bit)
|
||||
total |= BitField.resolve(this.#flags, bit)
|
||||
}
|
||||
if (Object.isFrozen(this))
|
||||
return new BitField(this.flags, this.bitfield & ~total)
|
||||
return new BitField(this.#flags, this.bitfield & ~total)
|
||||
this.bitfield &= ~total
|
||||
return this
|
||||
}
|
||||
|
||||
serialize(...hasParams: any[]): { [key: string]: any } {
|
||||
const serialized: { [key: string]: any } = {}
|
||||
for (const [flag, bit] of Object.entries(this.flags))
|
||||
flags(): { [name: string]: bigint | number } {
|
||||
return this.#flags
|
||||
}
|
||||
|
||||
serialize(...hasParams: any[]): { [key: string]: boolean } {
|
||||
const serialized: { [key: string]: boolean } = {}
|
||||
for (const [flag, bit] of Object.entries(this.#flags))
|
||||
serialized[flag] = this.has(
|
||||
BitField.resolve(this.flags, bit),
|
||||
BitField.resolve(this.#flags, bit),
|
||||
...hasParams
|
||||
)
|
||||
return serialized
|
||||
}
|
||||
|
||||
toArray(...hasParams: any[]): string[] {
|
||||
return Object.keys(this.flags).filter((bit) =>
|
||||
this.has(BitField.resolve(this.flags, bit), ...hasParams)
|
||||
return Object.keys(this.#flags).filter((bit) =>
|
||||
this.has(BitField.resolve(this.#flags, bit), ...hasParams)
|
||||
)
|
||||
}
|
||||
|
||||
toJSON(): number {
|
||||
return this.bitfield
|
||||
toJSON(): string {
|
||||
return this.bitfield.toString()
|
||||
}
|
||||
|
||||
valueOf(): number {
|
||||
valueOf(): bigint {
|
||||
return this.bitfield
|
||||
}
|
||||
|
||||
|
@ -91,9 +97,10 @@ export class BitField {
|
|||
yield* this.toArray()
|
||||
}
|
||||
|
||||
static resolve(flags: any, bit: BitFieldResolvable = 0): number {
|
||||
if (typeof bit === 'string' && !isNaN(parseInt(bit))) return parseInt(bit)
|
||||
if (typeof bit === 'number' && bit >= 0) return bit
|
||||
static resolve(flags: any, bit: BitFieldResolvable = 0n): bigint {
|
||||
if (typeof bit === 'bigint') return bit
|
||||
if (typeof bit === 'string' && !isNaN(parseInt(bit))) return BigInt(bit)
|
||||
if (typeof bit === 'number' && bit >= 0) return BigInt(bit)
|
||||
if (bit instanceof BitField) return this.resolve(flags, bit.bitfield)
|
||||
if (Array.isArray(bit))
|
||||
return (bit.map as any)((p: any) => this.resolve(flags, p)).reduce(
|
||||
|
|
|
@ -2,18 +2,15 @@
|
|||
import { PermissionFlags } from '../types/permissionFlags.ts'
|
||||
import { BitField, BitFieldResolvable } from './bitfield.ts'
|
||||
|
||||
export type PermissionResolvable =
|
||||
| string
|
||||
| string[]
|
||||
| number
|
||||
| number[]
|
||||
| Permissions
|
||||
| PermissionResolvable[]
|
||||
export type PermissionResolvable = BitFieldResolvable
|
||||
|
||||
/** Manages Discord's Bit-based Permissions */
|
||||
export class Permissions extends BitField {
|
||||
static DEFAULT = 104324673
|
||||
static ALL = Object.values(PermissionFlags).reduce((all, p) => all | p, 0)
|
||||
static DEFAULT = 104324673n
|
||||
static ALL = Object.values(PermissionFlags).reduce(
|
||||
(all, p) => BigInt(all) | BigInt(p),
|
||||
0n
|
||||
)
|
||||
|
||||
constructor(bits: BitFieldResolvable) {
|
||||
super(PermissionFlags, bits)
|
||||
|
@ -21,14 +18,14 @@ export class Permissions extends BitField {
|
|||
|
||||
any(permission: PermissionResolvable, checkAdmin = true): boolean {
|
||||
return (
|
||||
(checkAdmin && super.has(this.flags.ADMINISTRATOR)) ||
|
||||
(checkAdmin && super.has(this.flags().ADMINISTRATOR)) ||
|
||||
super.any(permission as any)
|
||||
)
|
||||
}
|
||||
|
||||
has(permission: PermissionResolvable, checkAdmin = true): boolean {
|
||||
return (
|
||||
(checkAdmin && super.has(this.flags.ADMINISTRATOR)) ||
|
||||
(checkAdmin && super.has(this.flags().ADMINISTRATOR)) ||
|
||||
super.has(permission as any)
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue