chore: run format

This commit is contained in:
Vlad Frangu
2025-10-05 16:13:56 +03:00
parent 2a712d4909
commit 8dc1692d87
189 changed files with 3172 additions and 916 deletions

View File

@@ -10,7 +10,9 @@ export default function Layout({ children }: { readonly children: ReactNode }) {
tabs: { tabs: {
transform(option, node) { transform(option, node) {
const meta = source.getNodeMeta(node); const meta = source.getNodeMeta(node);
if (!meta || !node.icon) return option; if (!meta || !node.icon) {
return option;
}
// category selection color based on path src/styles/base.css // category selection color based on path src/styles/base.css
const color = `var(--${meta.file.path.split('/')[0]}-color, var(--color-fd-foreground))`; const color = `var(--${meta.file.path.split('/')[0]}-color, var(--color-fd-foreground))`;

View File

@@ -11,7 +11,10 @@ export function Mermaid({ chart }: { readonly chart: string }) {
const { resolvedTheme } = useTheme(); const { resolvedTheme } = useTheme();
useEffect(() => { useEffect(() => {
if (currentChartRef.current === chart || !containerRef.current) return; if (currentChartRef.current === chart || !containerRef.current) {
return;
}
const container = containerRef.current; const container = containerRef.current;
currentChartRef.current = chart; currentChartRef.current = chart;

View File

@@ -29,7 +29,10 @@ export interface ReleaseEntry {
async function fetchDevVersion(pkg: string) { async function fetchDevVersion(pkg: string) {
try { try {
const res = await fetch(`https://registry.npmjs.org/${pkg}/dev`); const res = await fetch(`https://registry.npmjs.org/${pkg}/dev`);
if (!res.ok) return null; if (!res.ok) {
return null;
}
const packument = (await res.json()) as PackumentVersion; const packument = (await res.json()) as PackumentVersion;
return packument.version; return packument.version;
} catch { } catch {
@@ -47,10 +50,18 @@ async function getReleaseEntries(dev: boolean, dry: boolean) {
for (const pkg of packageList) { for (const pkg of packageList) {
// Don't release private packages ever (npm will error anyways) // Don't release private packages ever (npm will error anyways)
if (pkg.private) continue; if (pkg.private) {
continue;
}
// Just in case // Just in case
if (!pkg.version || !pkg.name) continue; if (!pkg.version || !pkg.name) {
if (nonNodePackages.has(pkg.name)) continue; continue;
}
if (nonNodePackages.has(pkg.name)) {
continue;
}
const release: ReleaseEntry = { const release: ReleaseEntry = {
name: pkg.name, name: pkg.name,
@@ -198,7 +209,9 @@ export async function generateReleaseTree(dev: boolean, dry: boolean, packageNam
} }
} }
if (newThisBranch.length) excludedReleaseTree.unshift(newThisBranch); if (newThisBranch.length) {
excludedReleaseTree.unshift(newThisBranch);
}
} }
return excludedReleaseTree; return excludedReleaseTree;
@@ -224,7 +237,9 @@ export async function generateReleaseTree(dev: boolean, dry: boolean, packageNam
} }
} }
if (newThisBranch.length) packageReleaseTree.unshift(newThisBranch); if (newThisBranch.length) {
packageReleaseTree.unshift(newThisBranch);
}
} }
return packageReleaseTree; return packageReleaseTree;

View File

@@ -54,9 +54,13 @@ export async function releasePackage(release: ReleaseEntry, dev: boolean, dry: b
await $`pnpm --filter=${release.name} publish --provenance --no-git-checks ${dev ? '--tag=dev' : ''}`; await $`pnpm --filter=${release.name} publish --provenance --no-git-checks ${dev ? '--tag=dev' : ''}`;
} }
if (!dev) await gitTagAndRelease(release, dry); if (!dev) {
await gitTagAndRelease(release, dry);
}
if (dry) return; if (dry) {
return;
}
const before = performance.now(); const before = performance.now();

View File

@@ -413,7 +413,9 @@ export function ApiItemContainerMixin<TBaseClass extends IApiItemConstructor>(
default: default:
for (const child of node.getChildNodes()) { for (const child of node.getChildNodes()) {
const result = findPlainTextNode(child); const result = findPlainTextNode(child);
if (result) return result; if (result) {
return result;
}
} }
} }
@@ -540,13 +542,14 @@ export function ApiItemContainerMixin<TBaseClass extends IApiItemConstructor>(
) { ) {
for (const [index, key] of (apiItem as ApiClass | ApiInterface).typeParameters.entries() ?? []) { for (const [index, key] of (apiItem as ApiClass | ApiInterface).typeParameters.entries() ?? []) {
const typeParameter = extendsType.typeParameters?.[index]; const typeParameter = extendsType.typeParameters?.[index];
if (typeParameter) if (typeParameter) {
mappedTypeParameters.set(key.name, { item: next.item as ApiDeclaredItem, range: typeParameter }); mappedTypeParameters.set(key.name, { item: next.item as ApiDeclaredItem, range: typeParameter });
else if (key.defaultTypeExcerpt) } else if (key.defaultTypeExcerpt) {
mappedTypeParameters.set(key.name, { mappedTypeParameters.set(key.name, {
item: apiItem as ApiDeclaredItem, item: apiItem as ApiDeclaredItem,
range: key.defaultTypeExcerpt.tokenRange, range: key.defaultTypeExcerpt.tokenRange,
}); });
}
} }
} }

View File

@@ -245,7 +245,10 @@ export class ApiPackage extends ApiItemContainerMixin(ApiNameMixin(ApiDocumented
public static loadFromJson(rawJson: any, apiJsonFilename: string = ''): ApiPackage { public static loadFromJson(rawJson: any, apiJsonFilename: string = ''): ApiPackage {
const jsonObject = const jsonObject =
MinifyJSONMapping.metadata in rawJson ? this._mapFromMinified(rawJson) : (rawJson as IApiPackageJson); MinifyJSONMapping.metadata in rawJson ? this._mapFromMinified(rawJson) : (rawJson as IApiPackageJson);
if (!jsonObject?.metadata) throw new Error(util.inspect(rawJson, { depth: 2 })); if (!jsonObject?.metadata) {
throw new Error(util.inspect(rawJson, { depth: 2 }));
}
if (!jsonObject?.metadata || typeof jsonObject.metadata.schemaVersion !== 'number') { if (!jsonObject?.metadata || typeof jsonObject.metadata.schemaVersion !== 'number') {
throw new Error( throw new Error(
`Error loading ${apiJsonFilename}:` + `Error loading ${apiJsonFilename}:` +
@@ -419,17 +422,19 @@ export class ApiPackage extends ApiItemContainerMixin(ApiNameMixin(ApiDocumented
private _mapToMinified(jsonObject: IApiPackageJson) { private _mapToMinified(jsonObject: IApiPackageJson) {
const mapper = (item: any): any => { const mapper = (item: any): any => {
if (Array.isArray(item)) return item.map(mapper); if (Array.isArray(item)) {
else { return item.map(mapper);
} else {
const result: any = {}; const result: any = {};
for (const key of Object.keys(item)) { for (const key of Object.keys(item)) {
if (key === 'dependencies') { if (key === 'dependencies') {
result[MinifyJSONMapping.dependencies] = item.dependencies; result[MinifyJSONMapping.dependencies] = item.dependencies;
} else if (key === 'tsdocConfig') { } else if (key === 'tsdocConfig') {
result[MinifyJSONMapping.tsdocConfig] = item.tsdocConfig; result[MinifyJSONMapping.tsdocConfig] = item.tsdocConfig;
} else } else {
result[MinifyJSONMapping[key as keyof typeof MinifyJSONMapping]] = result[MinifyJSONMapping[key as keyof typeof MinifyJSONMapping]] =
typeof item[key] === 'object' ? mapper(item[key]) : item[key]; typeof item[key] === 'object' ? mapper(item[key]) : item[key];
}
} }
return result; return result;
@@ -441,20 +446,22 @@ export class ApiPackage extends ApiItemContainerMixin(ApiNameMixin(ApiDocumented
private static _mapFromMinified(jsonObject: any): IApiPackageJson { private static _mapFromMinified(jsonObject: any): IApiPackageJson {
const mapper = (item: any): any => { const mapper = (item: any): any => {
if (Array.isArray(item)) return item.map(mapper); if (Array.isArray(item)) {
else { return item.map(mapper);
} else {
const result: any = {}; const result: any = {};
for (const key of Object.keys(item)) { for (const key of Object.keys(item)) {
if (key === MinifyJSONMapping.dependencies) { if (key === MinifyJSONMapping.dependencies) {
result.dependencies = item[MinifyJSONMapping.dependencies]; result.dependencies = item[MinifyJSONMapping.dependencies];
} else if (key === MinifyJSONMapping.tsdocConfig) { } else if (key === MinifyJSONMapping.tsdocConfig) {
result.tsdocConfig = item[MinifyJSONMapping.tsdocConfig]; result.tsdocConfig = item[MinifyJSONMapping.tsdocConfig];
} else } else {
result[ result[
Object.keys(MinifyJSONMapping).find( Object.keys(MinifyJSONMapping).find(
(look) => MinifyJSONMapping[look as keyof typeof MinifyJSONMapping] === key, (look) => MinifyJSONMapping[look as keyof typeof MinifyJSONMapping] === key,
)! )!
] = typeof item[key] === 'object' ? mapper(item[key]) : item[key]; ] = typeof item[key] === 'object' ? mapper(item[key]) : item[key];
}
} }
return result; return result;

View File

@@ -489,22 +489,25 @@ export class Deserializer {
}, },
]; ];
if (_class.extends) if (_class.extends) {
excerptTokens.push({ excerptTokens.push({
kind: ExcerptTokenKind.Reference, kind: ExcerptTokenKind.Reference,
text: formatVarType(_class.extends) ?? '', text: formatVarType(_class.extends) ?? '',
canonicalReference: `${_package}!${getFirstType(_class.extends) ?? ''}:class`, canonicalReference: `${_package}!${getFirstType(_class.extends) ?? ''}:class`,
}); });
}
if (_class.extends && _class.implements) if (_class.extends && _class.implements) {
excerptTokens.push({ kind: ExcerptTokenKind.Content, text: ' implements ' }); excerptTokens.push({ kind: ExcerptTokenKind.Content, text: ' implements ' });
}
if (_class.implements) if (_class.implements) {
excerptTokens.push({ excerptTokens.push({
kind: ExcerptTokenKind.Reference, kind: ExcerptTokenKind.Reference,
text: formatVarType(_class.implements) ?? '', text: formatVarType(_class.implements) ?? '',
canonicalReference: `${_package}!${getFirstType(_class.implements) ?? ''}:class`, canonicalReference: `${_package}!${getFirstType(_class.implements) ?? ''}:class`,
}); });
}
members.push({ members.push({
members: classMembers, members: classMembers,

View File

@@ -441,7 +441,9 @@ export class Collector {
* The star is used as a delimiter because it is not a legal identifier character. * The star is used as a delimiter because it is not a legal identifier character.
*/ */
public static getSortKeyIgnoringUnderscore(identifier: string | undefined): string { public static getSortKeyIgnoringUnderscore(identifier: string | undefined): string {
if (!identifier) return ''; if (!identifier) {
return '';
}
let parts: string[]; let parts: string[];
@@ -532,7 +534,10 @@ export class Collector {
entryPoint: IWorkingPackageEntryPoint, entryPoint: IWorkingPackageEntryPoint,
alreadySeenAstEntities: Set<AstEntity>, alreadySeenAstEntities: Set<AstEntity>,
): void { ): void {
if (alreadySeenAstEntities.has(astEntity)) return; if (alreadySeenAstEntities.has(astEntity)) {
return;
}
alreadySeenAstEntities.add(astEntity); alreadySeenAstEntities.add(astEntity);
if (astEntity instanceof AstSymbol) { if (astEntity instanceof AstSymbol) {

View File

@@ -122,7 +122,9 @@ export class CollectorEntity {
*/ */
public get exported(): boolean { public get exported(): boolean {
// Exported from top-level? // Exported from top-level?
if (this.exportedFromEntryPoint) return true; if (this.exportedFromEntryPoint) {
return true;
}
// Exported from parent? // Exported from parent?
for (const localExportNames of this._localExportNamesByParent.values()) { for (const localExportNames of this._localExportNamesByParent.values()) {
@@ -162,7 +164,9 @@ export class CollectorEntity {
*/ */
public get consumable(): boolean { public get consumable(): boolean {
// Exported from top-level? // Exported from top-level?
if (this.exportedFromEntryPoint) return true; if (this.exportedFromEntryPoint) {
return true;
}
// Exported from consumable parent? // Exported from consumable parent?
for (const [parent, localExportNames] of this._localExportNamesByParent) { for (const [parent, localExportNames] of this._localExportNamesByParent) {

View File

@@ -99,14 +99,18 @@ export class SourceMapper {
} }
const sourceMap: ISourceMap | null = this._getSourceMap(sourceFilePath); const sourceMap: ISourceMap | null = this._getSourceMap(sourceFilePath);
if (!sourceMap) return; if (!sourceMap) {
return;
}
const nearestMappingItem: MappingItem | undefined = SourceMapper._findNearestMappingItem(sourceMap.mappingItems, { const nearestMappingItem: MappingItem | undefined = SourceMapper._findNearestMappingItem(sourceMap.mappingItems, {
line: sourceFileLine, line: sourceFileLine,
column: sourceFileColumn, column: sourceFileColumn,
}); });
if (!nearestMappingItem) return; if (!nearestMappingItem) {
return;
}
const mappedFilePath: string = path.resolve(path.dirname(sourceFilePath), nearestMappingItem.source); const mappedFilePath: string = path.resolve(path.dirname(sourceFilePath), nearestMappingItem.source);
@@ -132,7 +136,9 @@ export class SourceMapper {
} }
// Don't translate coordinates to a file that doesn't exist // Don't translate coordinates to a file that doesn't exist
if (!originalFileInfo.fileExists) return; if (!originalFileInfo.fileExists) {
return;
}
// The nearestMappingItem anchor may be above/left of the real position, due to gaps in the mapping. Calculate // The nearestMappingItem anchor may be above/left of the real position, due to gaps in the mapping. Calculate
// the delta and apply it to the original position. // the delta and apply it to the original position.

View File

@@ -233,10 +233,14 @@ export abstract class BaseRedisBroker<
for (const [id, packet] of messages) { for (const [id, packet] of messages) {
const idx = packet.findIndex((value, idx) => value.toString('utf8') === 'data' && idx % 2 === 0); const idx = packet.findIndex((value, idx) => value.toString('utf8') === 'data' && idx % 2 === 0);
if (idx < 0) continue; if (idx < 0) {
continue;
}
const payload = packet[idx + 1]; const payload = packet[idx + 1];
if (!payload) continue; if (!payload) {
continue;
}
this.emitEvent(id, this.group, eventName, this.options.decode(payload)); this.emitEvent(id, this.group, eventName, this.options.decode(payload));
} }

View File

@@ -5,7 +5,10 @@
* @param arr - The (possibly variadic) data to normalize * @param arr - The (possibly variadic) data to normalize
*/ */
export function normalizeArray<ItemType>(arr: RestOrArray<ItemType>): ItemType[] { export function normalizeArray<ItemType>(arr: RestOrArray<ItemType>): ItemType[] {
if (Array.isArray(arr[0])) return [...arr[0]]; if (Array.isArray(arr[0])) {
return [...arr[0]];
}
return arr as ItemType[]; return arr as ItemType[];
} }

View File

@@ -672,7 +672,9 @@ describe('random() tests', () => {
const chars = 'abcdefghijklmnopqrstuvwxyz'; const chars = 'abcdefghijklmnopqrstuvwxyz';
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]; const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26];
for (let i = 0; i < chars.length; i++) coll.set(chars[i]!, numbers[i]!); for (let i = 0; i < chars.length; i++) {
coll.set(chars[i]!, numbers[i]!);
}
const random = coll.random(5); const random = coll.random(5);
expect(random.length).toBe(5); expect(random.length).toBe(5);

View File

@@ -38,8 +38,14 @@ export class Collection<Key, Value> extends Map<Key, Value> {
* ``` * ```
*/ */
public ensure(key: Key, defaultValueGenerator: (key: Key, collection: this) => Value): Value { public ensure(key: Key, defaultValueGenerator: (key: Key, collection: this) => Value): Value {
if (this.has(key)) return this.get(key)!; if (this.has(key)) {
if (typeof defaultValueGenerator !== 'function') throw new TypeError(`${defaultValueGenerator} is not a function`); return this.get(key)!;
}
if (typeof defaultValueGenerator !== 'function') {
throw new TypeError(`${defaultValueGenerator} is not a function`);
}
const defaultValue = defaultValueGenerator(key, this); const defaultValue = defaultValueGenerator(key, this);
this.set(key, defaultValue); this.set(key, defaultValue);
return defaultValue; return defaultValue;
@@ -74,9 +80,17 @@ export class Collection<Key, Value> extends Map<Key, Value> {
public first(): Value | undefined; public first(): Value | undefined;
public first(amount: number): Value[]; public first(amount: number): Value[];
public first(amount?: number): Value | Value[] | undefined { public first(amount?: number): Value | Value[] | undefined {
if (amount === undefined) return this.values().next().value; if (amount === undefined) {
if (amount < 0) return this.last(amount * -1); return this.values().next().value;
if (amount >= this.size) return [...this.values()]; }
if (amount < 0) {
return this.last(amount * -1);
}
if (amount >= this.size) {
return [...this.values()];
}
const iter = this.values(); const iter = this.values();
// eslint-disable-next-line unicorn/no-new-array // eslint-disable-next-line unicorn/no-new-array
@@ -98,9 +112,17 @@ export class Collection<Key, Value> extends Map<Key, Value> {
public firstKey(): Key | undefined; public firstKey(): Key | undefined;
public firstKey(amount: number): Key[]; public firstKey(amount: number): Key[];
public firstKey(amount?: number): Key | Key[] | undefined { public firstKey(amount?: number): Key | Key[] | undefined {
if (amount === undefined) return this.keys().next().value; if (amount === undefined) {
if (amount < 0) return this.lastKey(amount * -1); return this.keys().next().value;
if (amount >= this.size) return [...this.keys()]; }
if (amount < 0) {
return this.lastKey(amount * -1);
}
if (amount >= this.size) {
return [...this.keys()];
}
const iter = this.keys(); const iter = this.keys();
// eslint-disable-next-line unicorn/no-new-array // eslint-disable-next-line unicorn/no-new-array
@@ -122,9 +144,17 @@ export class Collection<Key, Value> extends Map<Key, Value> {
public last(): Value | undefined; public last(): Value | undefined;
public last(amount: number): Value[]; public last(amount: number): Value[];
public last(amount?: number): Value | Value[] | undefined { public last(amount?: number): Value | Value[] | undefined {
if (amount === undefined) return this.at(-1); if (amount === undefined) {
if (!amount) return []; return this.at(-1);
if (amount < 0) return this.first(amount * -1); }
if (!amount) {
return [];
}
if (amount < 0) {
return this.first(amount * -1);
}
const arr = [...this.values()]; const arr = [...this.values()];
return arr.slice(amount * -1); return arr.slice(amount * -1);
@@ -140,9 +170,17 @@ export class Collection<Key, Value> extends Map<Key, Value> {
public lastKey(): Key | undefined; public lastKey(): Key | undefined;
public lastKey(amount: number): Key[]; public lastKey(amount: number): Key[];
public lastKey(amount?: number): Key | Key[] | undefined { public lastKey(amount?: number): Key | Key[] | undefined {
if (amount === undefined) return this.keyAt(-1); if (amount === undefined) {
if (!amount) return []; return this.keyAt(-1);
if (amount < 0) return this.firstKey(amount * -1); }
if (!amount) {
return [];
}
if (amount < 0) {
return this.firstKey(amount * -1);
}
const arr = [...this.keys()]; const arr = [...this.keys()];
return arr.slice(amount * -1); return arr.slice(amount * -1);
@@ -158,10 +196,14 @@ export class Collection<Key, Value> extends Map<Key, Value> {
public at(index: number): Value | undefined { public at(index: number): Value | undefined {
index = Math.trunc(index); index = Math.trunc(index);
if (index >= 0) { if (index >= 0) {
if (index >= this.size) return undefined; if (index >= this.size) {
return undefined;
}
} else { } else {
index += this.size; index += this.size;
if (index < 0) return undefined; if (index < 0) {
return undefined;
}
} }
const iter = this.values(); const iter = this.values();
@@ -182,10 +224,14 @@ export class Collection<Key, Value> extends Map<Key, Value> {
public keyAt(index: number): Key | undefined { public keyAt(index: number): Key | undefined {
index = Math.trunc(index); index = Math.trunc(index);
if (index >= 0) { if (index >= 0) {
if (index >= this.size) return undefined; if (index >= this.size) {
return undefined;
}
} else { } else {
index += this.size; index += this.size;
if (index < 0) return undefined; if (index < 0) {
return undefined;
}
} }
const iter = this.keys(); const iter = this.keys();
@@ -205,9 +251,14 @@ export class Collection<Key, Value> extends Map<Key, Value> {
public random(): Value | undefined; public random(): Value | undefined;
public random(amount: number): Value[]; public random(amount: number): Value[];
public random(amount?: number): Value | Value[] | undefined { public random(amount?: number): Value | Value[] | undefined {
if (amount === undefined) return this.at(Math.floor(Math.random() * this.size)); if (amount === undefined) {
return this.at(Math.floor(Math.random() * this.size));
}
amount = Math.min(this.size, amount); amount = Math.min(this.size, amount);
if (!amount) return []; if (!amount) {
return [];
}
const values = [...this.values()]; const values = [...this.values()];
for (let sourceIndex = 0; sourceIndex < amount; sourceIndex++) { for (let sourceIndex = 0; sourceIndex < amount; sourceIndex++) {
@@ -227,9 +278,14 @@ export class Collection<Key, Value> extends Map<Key, Value> {
public randomKey(): Key | undefined; public randomKey(): Key | undefined;
public randomKey(amount: number): Key[]; public randomKey(amount: number): Key[];
public randomKey(amount?: number): Key | Key[] | undefined { public randomKey(amount?: number): Key | Key[] | undefined {
if (amount === undefined) return this.keyAt(Math.floor(Math.random() * this.size)); if (amount === undefined) {
return this.keyAt(Math.floor(Math.random() * this.size));
}
amount = Math.min(this.size, amount); amount = Math.min(this.size, amount);
if (!amount) return []; if (!amount) {
return [];
}
const keys = [...this.keys()]; const keys = [...this.keys()];
for (let sourceIndex = 0; sourceIndex < amount; sourceIndex++) { for (let sourceIndex = 0; sourceIndex < amount; sourceIndex++) {
@@ -247,7 +303,10 @@ export class Collection<Key, Value> extends Map<Key, Value> {
public reverse() { public reverse() {
const entries = [...this.entries()].reverse(); const entries = [...this.entries()].reverse();
this.clear(); this.clear();
for (const [key, value] of entries) this.set(key, value); for (const [key, value] of entries) {
this.set(key, value);
}
return this; return this;
} }
@@ -278,10 +337,18 @@ export class Collection<Key, Value> extends Map<Key, Value> {
thisArg: This, thisArg: This,
): Value | undefined; ): Value | undefined;
public find(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): Value | undefined { public find(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): Value | undefined {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`); if (typeof fn !== 'function') {
if (thisArg !== undefined) fn = fn.bind(thisArg); throw new TypeError(`${fn} is not a function`);
}
if (thisArg !== undefined) {
fn = fn.bind(thisArg);
}
for (const [key, val] of this) { for (const [key, val] of this) {
if (fn(val, key, this)) return val; if (fn(val, key, this)) {
return val;
}
} }
return undefined; return undefined;
@@ -312,10 +379,18 @@ export class Collection<Key, Value> extends Map<Key, Value> {
thisArg: This, thisArg: This,
): Key | undefined; ): Key | undefined;
public findKey(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): Key | undefined { public findKey(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): Key | undefined {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`); if (typeof fn !== 'function') {
if (thisArg !== undefined) fn = fn.bind(thisArg); throw new TypeError(`${fn} is not a function`);
}
if (thisArg !== undefined) {
fn = fn.bind(thisArg);
}
for (const [key, val] of this) { for (const [key, val] of this) {
if (fn(val, key, this)) return key; if (fn(val, key, this)) {
return key;
}
} }
return undefined; return undefined;
@@ -341,13 +416,21 @@ export class Collection<Key, Value> extends Map<Key, Value> {
thisArg: This, thisArg: This,
): Value | undefined; ): Value | undefined;
public findLast(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): Value | undefined { public findLast(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): Value | undefined {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`); if (typeof fn !== 'function') {
if (thisArg !== undefined) fn = fn.bind(thisArg); throw new TypeError(`${fn} is not a function`);
}
if (thisArg !== undefined) {
fn = fn.bind(thisArg);
}
const entries = [...this.entries()]; const entries = [...this.entries()];
for (let index = entries.length - 1; index >= 0; index--) { for (let index = entries.length - 1; index >= 0; index--) {
const val = entries[index]![1]; const val = entries[index]![1];
const key = entries[index]![0]; const key = entries[index]![0];
if (fn(val, key, this)) return val; if (fn(val, key, this)) {
return val;
}
} }
return undefined; return undefined;
@@ -374,13 +457,21 @@ export class Collection<Key, Value> extends Map<Key, Value> {
thisArg: This, thisArg: This,
): Key | undefined; ): Key | undefined;
public findLastKey(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): Key | undefined { public findLastKey(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): Key | undefined {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`); if (typeof fn !== 'function') {
if (thisArg !== undefined) fn = fn.bind(thisArg); throw new TypeError(`${fn} is not a function`);
}
if (thisArg !== undefined) {
fn = fn.bind(thisArg);
}
const entries = [...this.entries()]; const entries = [...this.entries()];
for (let index = entries.length - 1; index >= 0; index--) { for (let index = entries.length - 1; index >= 0; index--) {
const key = entries[index]![0]; const key = entries[index]![0];
const val = entries[index]![1]; const val = entries[index]![1];
if (fn(val, key, this)) return key; if (fn(val, key, this)) {
return key;
}
} }
return undefined; return undefined;
@@ -396,11 +487,19 @@ export class Collection<Key, Value> extends Map<Key, Value> {
public sweep(fn: (value: Value, key: Key, collection: this) => unknown): number; public sweep(fn: (value: Value, key: Key, collection: this) => unknown): number;
public sweep<This>(fn: (this: This, value: Value, key: Key, collection: this) => unknown, thisArg: This): number; public sweep<This>(fn: (this: This, value: Value, key: Key, collection: this) => unknown, thisArg: This): number;
public sweep(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): number { public sweep(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): number {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`); if (typeof fn !== 'function') {
if (thisArg !== undefined) fn = fn.bind(thisArg); throw new TypeError(`${fn} is not a function`);
}
if (thisArg !== undefined) {
fn = fn.bind(thisArg);
}
const previousSize = this.size; const previousSize = this.size;
for (const [key, val] of this) { for (const [key, val] of this) {
if (fn(val, key, this)) this.delete(key); if (fn(val, key, this)) {
this.delete(key);
}
} }
return previousSize - this.size; return previousSize - this.size;
@@ -438,11 +537,19 @@ export class Collection<Key, Value> extends Map<Key, Value> {
thisArg: This, thisArg: This,
): Collection<Key, Value>; ): Collection<Key, Value>;
public filter(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): Collection<Key, Value> { public filter(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): Collection<Key, Value> {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`); if (typeof fn !== 'function') {
if (thisArg !== undefined) fn = fn.bind(thisArg); throw new TypeError(`${fn} is not a function`);
}
if (thisArg !== undefined) {
fn = fn.bind(thisArg);
}
const results = new this.constructor[Symbol.species]<Key, Value>(); const results = new this.constructor[Symbol.species]<Key, Value>();
for (const [key, val] of this) { for (const [key, val] of this) {
if (fn(val, key, this)) results.set(key, val); if (fn(val, key, this)) {
results.set(key, val);
}
} }
return results; return results;
@@ -484,8 +591,14 @@ export class Collection<Key, Value> extends Map<Key, Value> {
fn: (value: Value, key: Key, collection: this) => unknown, fn: (value: Value, key: Key, collection: this) => unknown,
thisArg?: unknown, thisArg?: unknown,
): [Collection<Key, Value>, Collection<Key, Value>] { ): [Collection<Key, Value>, Collection<Key, Value>] {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`); if (typeof fn !== 'function') {
if (thisArg !== undefined) fn = fn.bind(thisArg); throw new TypeError(`${fn} is not a function`);
}
if (thisArg !== undefined) {
fn = fn.bind(thisArg);
}
const results: [Collection<Key, Value>, Collection<Key, Value>] = [ const results: [Collection<Key, Value>, Collection<Key, Value>] = [
new this.constructor[Symbol.species]<Key, Value>(), new this.constructor[Symbol.species]<Key, Value>(),
new this.constructor[Symbol.species]<Key, Value>(), new this.constructor[Symbol.species]<Key, Value>(),
@@ -545,8 +658,14 @@ export class Collection<Key, Value> extends Map<Key, Value> {
thisArg: This, thisArg: This,
): NewValue[]; ): NewValue[];
public map<NewValue>(fn: (value: Value, key: Key, collection: this) => NewValue, thisArg?: unknown): NewValue[] { public map<NewValue>(fn: (value: Value, key: Key, collection: this) => NewValue, thisArg?: unknown): NewValue[] {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`); if (typeof fn !== 'function') {
if (thisArg !== undefined) fn = fn.bind(thisArg); throw new TypeError(`${fn} is not a function`);
}
if (thisArg !== undefined) {
fn = fn.bind(thisArg);
}
const iter = this.entries(); const iter = this.entries();
// eslint-disable-next-line unicorn/no-new-array // eslint-disable-next-line unicorn/no-new-array
const results: NewValue[] = new Array(this.size); const results: NewValue[] = new Array(this.size);
@@ -578,10 +697,19 @@ export class Collection<Key, Value> extends Map<Key, Value> {
fn: (value: Value, key: Key, collection: this) => NewValue, fn: (value: Value, key: Key, collection: this) => NewValue,
thisArg?: unknown, thisArg?: unknown,
): Collection<Key, NewValue> { ): Collection<Key, NewValue> {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`); if (typeof fn !== 'function') {
if (thisArg !== undefined) fn = fn.bind(thisArg); throw new TypeError(`${fn} is not a function`);
}
if (thisArg !== undefined) {
fn = fn.bind(thisArg);
}
const coll = new this.constructor[Symbol.species]<Key, NewValue>(); const coll = new this.constructor[Symbol.species]<Key, NewValue>();
for (const [key, val] of this) coll.set(key, fn(val, key, this)); for (const [key, val] of this) {
coll.set(key, fn(val, key, this));
}
return coll; return coll;
} }
@@ -599,10 +727,18 @@ export class Collection<Key, Value> extends Map<Key, Value> {
public some(fn: (value: Value, key: Key, collection: this) => unknown): boolean; public some(fn: (value: Value, key: Key, collection: this) => unknown): boolean;
public some<This>(fn: (this: This, value: Value, key: Key, collection: this) => unknown, thisArg: This): boolean; public some<This>(fn: (this: This, value: Value, key: Key, collection: this) => unknown, thisArg: This): boolean;
public some(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): boolean { public some(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): boolean {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`); if (typeof fn !== 'function') {
if (thisArg !== undefined) fn = fn.bind(thisArg); throw new TypeError(`${fn} is not a function`);
}
if (thisArg !== undefined) {
fn = fn.bind(thisArg);
}
for (const [key, val] of this) { for (const [key, val] of this) {
if (fn(val, key, this)) return true; if (fn(val, key, this)) {
return true;
}
} }
return false; return false;
@@ -636,10 +772,18 @@ export class Collection<Key, Value> extends Map<Key, Value> {
): this is Collection<Key, NewValue>; ): this is Collection<Key, NewValue>;
public every<This>(fn: (this: This, value: Value, key: Key, collection: this) => unknown, thisArg: This): boolean; public every<This>(fn: (this: This, value: Value, key: Key, collection: this) => unknown, thisArg: This): boolean;
public every(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): boolean { public every(fn: (value: Value, key: Key, collection: this) => unknown, thisArg?: unknown): boolean {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`); if (typeof fn !== 'function') {
if (thisArg !== undefined) fn = fn.bind(thisArg); throw new TypeError(`${fn} is not a function`);
}
if (thisArg !== undefined) {
fn = fn.bind(thisArg);
}
for (const [key, val] of this) { for (const [key, val] of this) {
if (!fn(val, key, this)) return false; if (!fn(val, key, this)) {
return false;
}
} }
return true; return true;
@@ -669,12 +813,18 @@ export class Collection<Key, Value> extends Map<Key, Value> {
fn: (accumulator: InitialValue, value: Value, key: Key, collection: this) => InitialValue, fn: (accumulator: InitialValue, value: Value, key: Key, collection: this) => InitialValue,
initialValue?: InitialValue, initialValue?: InitialValue,
): InitialValue { ): InitialValue {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`); if (typeof fn !== 'function') {
throw new TypeError(`${fn} is not a function`);
}
let accumulator!: InitialValue; let accumulator!: InitialValue;
const iterator = this.entries(); const iterator = this.entries();
if (initialValue === undefined) { if (initialValue === undefined) {
if (this.size === 0) throw new TypeError('Reduce of empty collection with no initial value'); if (this.size === 0) {
throw new TypeError('Reduce of empty collection with no initial value');
}
accumulator = iterator.next().value![1] as unknown as InitialValue; accumulator = iterator.next().value![1] as unknown as InitialValue;
} else { } else {
accumulator = initialValue; accumulator = initialValue;
@@ -706,13 +856,19 @@ export class Collection<Key, Value> extends Map<Key, Value> {
fn: (accumulator: InitialValue, value: Value, key: Key, collection: this) => InitialValue, fn: (accumulator: InitialValue, value: Value, key: Key, collection: this) => InitialValue,
initialValue?: InitialValue, initialValue?: InitialValue,
): InitialValue { ): InitialValue {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`); if (typeof fn !== 'function') {
throw new TypeError(`${fn} is not a function`);
}
const entries = [...this.entries()]; const entries = [...this.entries()];
let accumulator!: InitialValue; let accumulator!: InitialValue;
let index: number; let index: number;
if (initialValue === undefined) { if (initialValue === undefined) {
if (entries.length === 0) throw new TypeError('Reduce of empty collection with no initial value'); if (entries.length === 0) {
throw new TypeError('Reduce of empty collection with no initial value');
}
accumulator = entries[entries.length - 1]![1] as unknown as InitialValue; accumulator = entries[entries.length - 1]![1] as unknown as InitialValue;
index = entries.length - 1; index = entries.length - 1;
} else { } else {
@@ -747,8 +903,13 @@ export class Collection<Key, Value> extends Map<Key, Value> {
public each(fn: (value: Value, key: Key, collection: this) => void): this; public each(fn: (value: Value, key: Key, collection: this) => void): this;
public each<This>(fn: (this: This, value: Value, key: Key, collection: this) => void, thisArg: This): this; public each<This>(fn: (this: This, value: Value, key: Key, collection: this) => void, thisArg: This): this;
public each(fn: (value: Value, key: Key, collection: this) => void, thisArg?: unknown): this { public each(fn: (value: Value, key: Key, collection: this) => void, thisArg?: unknown): this {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`); if (typeof fn !== 'function') {
if (thisArg !== undefined) fn = fn.bind(thisArg); throw new TypeError(`${fn} is not a function`);
}
if (thisArg !== undefined) {
fn = fn.bind(thisArg);
}
for (const [key, value] of this) { for (const [key, value] of this) {
fn(value, key, this); fn(value, key, this);
@@ -773,8 +934,14 @@ export class Collection<Key, Value> extends Map<Key, Value> {
public tap(fn: (collection: this) => void): this; public tap(fn: (collection: this) => void): this;
public tap<This>(fn: (this: This, collection: this) => void, thisArg: This): this; public tap<This>(fn: (this: This, collection: this) => void, thisArg: This): this;
public tap(fn: (collection: this) => void, thisArg?: unknown): this { public tap(fn: (collection: this) => void, thisArg?: unknown): this {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`); if (typeof fn !== 'function') {
if (thisArg !== undefined) fn = fn.bind(thisArg); throw new TypeError(`${fn} is not a function`);
}
if (thisArg !== undefined) {
fn = fn.bind(thisArg);
}
fn(this); fn(this);
return this; return this;
} }
@@ -803,7 +970,9 @@ export class Collection<Key, Value> extends Map<Key, Value> {
public concat(...collections: ReadonlyCollection<Key, Value>[]) { public concat(...collections: ReadonlyCollection<Key, Value>[]) {
const newColl = this.clone(); const newColl = this.clone();
for (const coll of collections) { for (const coll of collections) {
for (const [key, val] of coll) newColl.set(key, val); for (const [key, val] of coll) {
newColl.set(key, val);
}
} }
return newColl; return newColl;
@@ -818,9 +987,18 @@ export class Collection<Key, Value> extends Map<Key, Value> {
* @returns Whether the collections have identical contents * @returns Whether the collections have identical contents
*/ */
public equals(collection: ReadonlyCollection<Key, Value>) { public equals(collection: ReadonlyCollection<Key, Value>) {
if (!collection) return false; // runtime check if (!collection) {
if (this === collection) return true; return false;
if (this.size !== collection.size) return false; } // runtime check
if (this === collection) {
return true;
}
if (this.size !== collection.size) {
return false;
}
for (const [key, value] of this) { for (const [key, value] of this) {
if (!collection.has(key) || value !== collection.get(key)) { if (!collection.has(key) || value !== collection.get(key)) {
return false; return false;
@@ -874,7 +1052,9 @@ export class Collection<Key, Value> extends Map<Key, Value> {
const coll = new this.constructor[Symbol.species]<Key, Value>(); const coll = new this.constructor[Symbol.species]<Key, Value>();
for (const [key, value] of this) { for (const [key, value] of this) {
if (other.has(key)) coll.set(key, value); if (other.has(key)) {
coll.set(key, value);
}
} }
return coll; return coll;
@@ -900,7 +1080,9 @@ export class Collection<Key, Value> extends Map<Key, Value> {
const coll = new this.constructor[Symbol.species]<Key, OtherValue | Value>(this); const coll = new this.constructor[Symbol.species]<Key, OtherValue | Value>(this);
for (const [key, value] of other) { for (const [key, value] of other) {
if (!coll.has(key)) coll.set(key, value); if (!coll.has(key)) {
coll.set(key, value);
}
} }
return coll; return coll;
@@ -924,7 +1106,9 @@ export class Collection<Key, Value> extends Map<Key, Value> {
const coll = new this.constructor[Symbol.species]<Key, Value>(); const coll = new this.constructor[Symbol.species]<Key, Value>();
for (const [key, value] of this) { for (const [key, value] of this) {
if (!other.has(key)) coll.set(key, value); if (!other.has(key)) {
coll.set(key, value);
}
} }
return coll; return coll;
@@ -949,11 +1133,15 @@ export class Collection<Key, Value> extends Map<Key, Value> {
const coll = new this.constructor[Symbol.species]<Key, OtherValue | Value>(); const coll = new this.constructor[Symbol.species]<Key, OtherValue | Value>();
for (const [key, value] of this) { for (const [key, value] of this) {
if (!other.has(key)) coll.set(key, value); if (!other.has(key)) {
coll.set(key, value);
}
} }
for (const [key, value] of other) { for (const [key, value] of other) {
if (!this.has(key)) coll.set(key, value); if (!this.has(key)) {
coll.set(key, value);
}
} }
return coll; return coll;
@@ -1003,14 +1191,20 @@ export class Collection<Key, Value> extends Map<Key, Value> {
if (hasInSelf) { if (hasInSelf) {
if (hasInOther) { if (hasInOther) {
const result = whenInBoth(this.get(key)!, other.get(key)!, key); const result = whenInBoth(this.get(key)!, other.get(key)!, key);
if (result.keep) coll.set(key, result.value); if (result.keep) {
coll.set(key, result.value);
}
} else { } else {
const result = whenInSelf(this.get(key)!, key); const result = whenInSelf(this.get(key)!, key);
if (result.keep) coll.set(key, result.value); if (result.keep) {
coll.set(key, result.value);
}
} }
} else if (hasInOther) { } else if (hasInOther) {
const result = whenInOther(other.get(key)!, key); const result = whenInOther(other.get(key)!, key);
if (result.keep) coll.set(key, result.value); if (result.keep) {
coll.set(key, result.value);
}
} }
} }
@@ -1052,13 +1246,24 @@ export class Collection<Key, Value> extends Map<Key, Value> {
* operation with arguments `firstValue`, `secondValue` and `undefined`. * operation with arguments `firstValue`, `secondValue` and `undefined`.
*/ */
private static defaultSort<Value>(firstValue: Value, secondValue: Value): number { private static defaultSort<Value>(firstValue: Value, secondValue: Value): number {
if (firstValue === undefined) return secondValue === undefined ? 0 : 1; if (firstValue === undefined) {
if (secondValue === undefined) return -1; return secondValue === undefined ? 0 : 1;
}
if (secondValue === undefined) {
return -1;
}
const x = String(firstValue); const x = String(firstValue);
const y = String(secondValue); const y = String(secondValue);
if (x < y) return -1; if (x < y) {
if (y < x) return 1; return -1;
}
if (y < x) {
return 1;
}
return 0; return 0;
} }

View File

@@ -259,7 +259,9 @@ export class Client extends AsyncEventEmitter<MappedEvents> {
}); });
for await (const [{ data }] of iterator) { for await (const [{ data }] of iterator) {
if (data.nonce !== nonce) continue; if (data.nonce !== nonce) {
continue;
}
clearTimeout(timer); clearTimeout(timer);
timer = undefined; timer = undefined;
@@ -273,7 +275,9 @@ export class Client extends AsyncEventEmitter<MappedEvents> {
chunkCount: data.chunk_count, chunkCount: data.chunk_count,
}; };
if (data.chunk_index >= data.chunk_count - 1) break; if (data.chunk_index >= data.chunk_count - 1) {
break;
}
timer = createTimer(controller, timeout); timer = createTimer(controller, timeout);
} }
@@ -310,8 +314,13 @@ export class Client extends AsyncEventEmitter<MappedEvents> {
for await (const data of this.requestGuildMembersIterator({ ...options, nonce }, timeout)) { for await (const data of this.requestGuildMembersIterator({ ...options, nonce }, timeout)) {
members.push(...data.members); members.push(...data.members);
if (data.presences) presences.push(...data.presences); if (data.presences) {
if (data.notFound) notFound.push(...data.notFound); presences.push(...data.presences);
}
if (data.notFound) {
notFound.push(...data.notFound);
}
} }
return { members, nonce, notFound, presences }; return { members, nonce, notFound, presences };
@@ -360,7 +369,9 @@ export class Client extends AsyncEventEmitter<MappedEvents> {
const guildIds = new Set(options.guild_ids); const guildIds = new Set(options.guild_ids);
for await (const [{ data }] of iterator) { for await (const [{ data }] of iterator) {
if (!guildIds.has(data.guild_id)) continue; if (!guildIds.has(data.guild_id)) {
continue;
}
clearTimeout(timer); clearTimeout(timer);
timer = undefined; timer = undefined;
@@ -372,7 +383,9 @@ export class Client extends AsyncEventEmitter<MappedEvents> {
guildIds.delete(data.guild_id); guildIds.delete(data.guild_id);
if (guildIds.size === 0) break; if (guildIds.size === 0) {
break;
}
timer = createTimer(controller, timeout); timer = createTimer(controller, timeout);
} }

View File

@@ -7,7 +7,9 @@ async function writeWebsocketHandlerImports() {
const handlersDirectory = new URL('../src/client/websocket/handlers', import.meta.url); const handlersDirectory = new URL('../src/client/websocket/handlers', import.meta.url);
for (const file of (await readdir(handlersDirectory)).sort()) { for (const file of (await readdir(handlersDirectory)).sort()) {
if (file === 'index.js') continue; if (file === 'index.js') {
continue;
}
lines.push(` ['${file.slice(0, -3)}', require('./${file}')],`); lines.push(` ['${file.slice(0, -3)}', require('./${file}')],`);
} }
@@ -35,7 +37,9 @@ async function writeClientActionImports() {
const actionsDirectory = new URL('../src/client/actions', import.meta.url); const actionsDirectory = new URL('../src/client/actions', import.meta.url);
for (const file of (await readdir(actionsDirectory)).sort()) { for (const file of (await readdir(actionsDirectory)).sort()) {
if (file === 'Action.js' || file === 'ActionsManager.js') continue; if (file === 'Action.js' || file === 'ActionsManager.js') {
continue;
}
const actionName = file.slice(0, -3); const actionName = file.slice(0, -3);

View File

@@ -268,7 +268,10 @@ class Client extends BaseClient {
* client.login('my token'); * client.login('my token');
*/ */
async login(token = this.token) { async login(token = this.token) {
if (!token || typeof token !== 'string') throw new DiscordjsError(ErrorCodes.TokenInvalid); if (!token || typeof token !== 'string') {
throw new DiscordjsError(ErrorCodes.TokenInvalid);
}
this.token = token.replace(/^bot\s*/i, ''); this.token = token.replace(/^bot\s*/i, '');
this.rest.setToken(this.token); this.rest.setToken(this.token);
@@ -531,7 +534,10 @@ class Client extends BaseClient {
async fetchVoiceRegions() { async fetchVoiceRegions() {
const apiRegions = await this.rest.get(Routes.voiceRegions()); const apiRegions = await this.rest.get(Routes.voiceRegions());
const regions = new Collection(); const regions = new Collection();
for (const region of apiRegions) regions.set(region.id, new VoiceRegion(region)); for (const region of apiRegions) {
regions.set(region.id, new VoiceRegion(region));
}
return regions; return regions;
} }
@@ -604,7 +610,10 @@ class Client extends BaseClient {
*/ */
async fetchGuildPreview(guild) { async fetchGuildPreview(guild) {
const id = this.guilds.resolveId(guild); const id = this.guilds.resolveId(guild);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'guild', 'GuildResolvable'); if (!id) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'guild', 'GuildResolvable');
}
const data = await this.rest.get(Routes.guildPreview(id)); const data = await this.rest.get(Routes.guildPreview(id));
return new GuildPreview(this, data); return new GuildPreview(this, data);
} }
@@ -617,7 +626,10 @@ class Client extends BaseClient {
*/ */
async fetchGuildWidget(guild) { async fetchGuildWidget(guild) {
const id = this.guilds.resolveId(guild); const id = this.guilds.resolveId(guild);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'guild', 'GuildResolvable'); if (!id) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'guild', 'GuildResolvable');
}
const data = await this.rest.get(Routes.guildWidgetJSON(id)); const data = await this.rest.get(Routes.guildWidgetJSON(id));
return new Widget(this, data); return new Widget(this, data);
} }
@@ -654,8 +666,13 @@ class Client extends BaseClient {
* console.log(`Generated bot invite link: ${link}`); * console.log(`Generated bot invite link: ${link}`);
*/ */
generateInvite(options = {}) { generateInvite(options = {}) {
if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true); if (typeof options !== 'object') {
if (!this.application) throw new DiscordjsError(ErrorCodes.ClientNotReady, 'generate an invite link'); throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
}
if (!this.application) {
throw new DiscordjsError(ErrorCodes.ClientNotReady, 'generate an invite link');
}
const { scopes } = options; const { scopes } = options;
if (scopes === undefined) { if (scopes === undefined) {
@@ -688,12 +705,17 @@ class Client extends BaseClient {
if (options.permissions) { if (options.permissions) {
const permissions = PermissionsBitField.resolve(options.permissions); const permissions = PermissionsBitField.resolve(options.permissions);
if (permissions) query.set('permissions', permissions.toString()); if (permissions) {
query.set('permissions', permissions.toString());
}
} }
if (options.guild) { if (options.guild) {
const guildId = this.guilds.resolveId(options.guild); const guildId = this.guilds.resolveId(options.guild);
if (!guildId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options.guild', 'GuildResolvable'); if (!guildId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options.guild', 'GuildResolvable');
}
query.set('guild_id', guildId); query.set('guild_id', guildId);
} }
@@ -715,7 +737,9 @@ class Client extends BaseClient {
* @private * @private
*/ */
get _censoredToken() { get _censoredToken() {
if (!this.token) return null; if (!this.token) {
return null;
}
return this.token return this.token
.split('.') .split('.')

View File

@@ -36,10 +36,14 @@ class Action {
if (!('recipients' in data)) { if (!('recipients' in data)) {
// Try to resolve the recipient, but do not add the client user. // Try to resolve the recipient, but do not add the client user.
const recipient = data.author ?? data.user ?? { id: data.user_id }; const recipient = data.author ?? data.user ?? { id: data.user_id };
if (recipient.id !== this.client.user.id) payloadData.recipients = [recipient]; if (recipient.id !== this.client.user.id) {
payloadData.recipients = [recipient];
}
} }
if (id !== undefined) payloadData.id = id; if (id !== undefined) {
payloadData.id = id;
}
return ( return (
data[this.client.actions.injectedChannel] ?? data[this.client.actions.injectedChannel] ??
@@ -68,7 +72,9 @@ class Action {
getPoll(data, message, channel) { getPoll(data, message, channel) {
const includePollPartial = this.client.options.partials.includes(Partials.Poll); const includePollPartial = this.client.options.partials.includes(Partials.Poll);
const includePollAnswerPartial = this.client.options.partials.includes(Partials.PollAnswer); const includePollAnswerPartial = this.client.options.partials.includes(Partials.PollAnswer);
if (message.partial && (!includePollPartial || !includePollAnswerPartial)) return null; if (message.partial && (!includePollPartial || !includePollAnswerPartial)) {
return null;
}
if (!message.poll && includePollPartial) { if (!message.poll && includePollPartial) {
message.poll = new Poll(this.client, data, message, channel); message.poll = new Poll(this.client, data, message, channel);

View File

@@ -20,7 +20,9 @@ class ChannelUpdateAction extends Action {
} }
if (channel.isTextBased() && newChannel.isTextBased()) { if (channel.isTextBased() && newChannel.isTextBased()) {
for (const [id, message] of channel.messages.cache) newChannel.messages.cache.set(id, message); for (const [id, message] of channel.messages.cache) {
newChannel.messages.cache.set(id, message);
}
} }
channel = newChannel; channel = newChannel;

View File

@@ -10,7 +10,9 @@ class GuildChannelsPositionUpdateAction extends Action {
if (guild) { if (guild) {
for (const partialChannel of data.channels) { for (const partialChannel of data.channels) {
const channel = guild.channels.cache.get(partialChannel.id); const channel = guild.channels.cache.get(partialChannel.id);
if (channel) channel.rawPosition = partialChannel.position; if (channel) {
channel.rawPosition = partialChannel.position;
}
} }
} }

View File

@@ -13,7 +13,10 @@ class GuildEmojiCreateAction extends Action {
* @event Client#emojiCreate * @event Client#emojiCreate
* @param {GuildEmoji} emoji The emoji that was created * @param {GuildEmoji} emoji The emoji that was created
*/ */
if (!already) this.client.emit(Events.GuildEmojiCreate, emoji); if (!already) {
this.client.emit(Events.GuildEmojiCreate, emoji);
}
return { emoji }; return { emoji };
} }
} }

View File

@@ -5,7 +5,9 @@ const { Action } = require('./Action.js');
class GuildEmojisUpdateAction extends Action { class GuildEmojisUpdateAction extends Action {
handle(data) { handle(data) {
const guild = this.client.guilds.cache.get(data.guild_id); const guild = this.client.guilds.cache.get(data.guild_id);
if (!guild?.emojis) return; if (!guild?.emojis) {
return;
}
const deletions = new Map(guild.emojis.cache); const deletions = new Map(guild.emojis.cache);

View File

@@ -27,7 +27,9 @@ class GuildMemberUpdateAction extends Action {
* @param {GuildMember} oldMember The member before the update * @param {GuildMember} oldMember The member before the update
* @param {GuildMember} newMember The member after the update * @param {GuildMember} newMember The member after the update
*/ */
if (!member.equals(old)) client.emit(Events.GuildMemberUpdate, old, member); if (!member.equals(old)) {
client.emit(Events.GuildMemberUpdate, old, member);
}
} else { } else {
const newMember = guild.members._add(data); const newMember = guild.members._add(data);
/** /**

View File

@@ -17,7 +17,9 @@ class GuildRoleCreateAction extends Action {
* @event Client#roleCreate * @event Client#roleCreate
* @param {Role} role The role that was created * @param {Role} role The role that was created
*/ */
if (!already) client.emit(Events.GuildRoleCreate, role); if (!already) {
client.emit(Events.GuildRoleCreate, role);
}
} }
return { role }; return { role };

View File

@@ -10,7 +10,9 @@ class GuildRolesPositionUpdateAction extends Action {
if (guild) { if (guild) {
for (const partialRole of data.roles) { for (const partialRole of data.roles) {
const role = guild.roles.cache.get(partialRole.id); const role = guild.roles.cache.get(partialRole.id);
if (role) role.rawPosition = partialRole.position; if (role) {
role.rawPosition = partialRole.position;
}
} }
} }

View File

@@ -7,7 +7,9 @@ class GuildSoundboardSoundDeleteAction extends Action {
handle(data) { handle(data) {
const guild = this.client.guilds.cache.get(data.guild_id); const guild = this.client.guilds.cache.get(data.guild_id);
if (!guild) return {}; if (!guild) {
return {};
}
const soundboardSound = this.getSoundboardSound(data, guild); const soundboardSound = this.getSoundboardSound(data, guild);

View File

@@ -13,7 +13,10 @@ class GuildStickerCreateAction extends Action {
* @event Client#stickerCreate * @event Client#stickerCreate
* @param {Sticker} sticker The sticker that was created * @param {Sticker} sticker The sticker that was created
*/ */
if (!already) this.client.emit(Events.GuildStickerCreate, sticker); if (!already) {
this.client.emit(Events.GuildStickerCreate, sticker);
}
return { sticker }; return { sticker };
} }
} }

View File

@@ -5,7 +5,9 @@ const { Action } = require('./Action.js');
class GuildStickersUpdateAction extends Action { class GuildStickersUpdateAction extends Action {
handle(data) { handle(data) {
const guild = this.client.guilds.cache.get(data.guild_id); const guild = this.client.guilds.cache.get(data.guild_id);
if (!guild?.stickers) return; if (!guild?.stickers) {
return;
}
const deletions = new Map(guild.stickers.cache); const deletions = new Map(guild.stickers.cache);

View File

@@ -36,7 +36,10 @@ class InteractionCreateAction extends Action {
InteractionClass = UserContextMenuCommandInteraction; InteractionClass = UserContextMenuCommandInteraction;
break; break;
case ApplicationCommandType.Message: case ApplicationCommandType.Message:
if (channel && !channel.isTextBased()) return; if (channel && !channel.isTextBased()) {
return;
}
InteractionClass = MessageContextMenuCommandInteraction; InteractionClass = MessageContextMenuCommandInteraction;
break; break;
case ApplicationCommandType.PrimaryEntryPoint: case ApplicationCommandType.PrimaryEntryPoint:
@@ -52,7 +55,9 @@ class InteractionCreateAction extends Action {
break; break;
case InteractionType.MessageComponent: case InteractionType.MessageComponent:
if (channel && !channel.isTextBased()) return; if (channel && !channel.isTextBased()) {
return;
}
switch (data.data.component_type) { switch (data.data.component_type) {
case ComponentType.Button: case ComponentType.Button:

View File

@@ -12,7 +12,9 @@ class MessageCreateAction extends Action {
...('guild_id' in data && { guild_id: data.guild_id }), ...('guild_id' in data && { guild_id: data.guild_id }),
}); });
if (channel) { if (channel) {
if (!channel.isTextBased()) return {}; if (!channel.isTextBased()) {
return {};
}
if (channel.isThread()) { if (channel.isThread()) {
channel.messageCount++; channel.messageCount++;
@@ -20,7 +22,10 @@ class MessageCreateAction extends Action {
} }
const existing = channel.messages.cache.get(data.id); const existing = channel.messages.cache.get(data.id);
if (existing && existing.author?.id !== this.client.user.id) return { message: existing }; if (existing && existing.author?.id !== this.client.user.id) {
return { message: existing };
}
const message = existing ?? channel.messages._add(data); const message = existing ?? channel.messages._add(data);
channel.lastMessageId = data.id; channel.lastMessageId = data.id;

View File

@@ -9,9 +9,13 @@ class MessageDeleteAction extends Action {
const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) }); const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) });
let message; let message;
if (channel) { if (channel) {
if (!channel.isTextBased()) return {}; if (!channel.isTextBased()) {
return {};
}
if (channel.isThread()) channel.messageCount--; if (channel.isThread()) {
channel.messageCount--;
}
message = this.getMessage(data, channel); message = this.getMessage(data, channel);
if (message) { if (message) {

View File

@@ -10,9 +10,13 @@ class MessageDeleteBulkAction extends Action {
const channel = client.channels.cache.get(data.channel_id); const channel = client.channels.cache.get(data.channel_id);
if (channel) { if (channel) {
if (!channel.isTextBased()) return {}; if (!channel.isTextBased()) {
return {};
}
if (channel.isThread()) channel.messageCount -= data.ids.length; if (channel.isThread()) {
channel.messageCount -= data.ids.length;
}
const ids = data.ids; const ids = data.ids;
const messages = new Collection(); const messages = new Collection();
@@ -38,7 +42,10 @@ class MessageDeleteBulkAction extends Action {
* @param {Collection<Snowflake, Message>} messages The deleted messages, mapped by their id * @param {Collection<Snowflake, Message>} messages The deleted messages, mapped by their id
* @param {GuildTextBasedChannel} channel The channel that the messages were deleted in * @param {GuildTextBasedChannel} channel The channel that the messages were deleted in
*/ */
if (messages.size > 0) client.emit(Events.MessageBulkDelete, messages, channel); if (messages.size > 0) {
client.emit(Events.MessageBulkDelete, messages, channel);
}
return { messages }; return { messages };
} }

View File

@@ -6,16 +6,24 @@ const { Action } = require('./Action.js');
class MessagePollVoteAddAction extends Action { class MessagePollVoteAddAction extends Action {
handle(data) { handle(data) {
const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) }); const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) });
if (!channel?.isTextBased()) return false; if (!channel?.isTextBased()) {
return false;
}
const message = this.getMessage(data, channel); const message = this.getMessage(data, channel);
if (!message) return false; if (!message) {
return false;
}
const poll = this.getPoll(data, message, channel); const poll = this.getPoll(data, message, channel);
if (!poll) return false; if (!poll) {
return false;
}
const answer = poll.answers.get(data.answer_id); const answer = poll.answers.get(data.answer_id);
if (!answer) return false; if (!answer) {
return false;
}
const user = this.getUser(data); const user = this.getUser(data);

View File

@@ -6,16 +6,24 @@ const { Action } = require('./Action.js');
class MessagePollVoteRemoveAction extends Action { class MessagePollVoteRemoveAction extends Action {
handle(data) { handle(data) {
const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) }); const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) });
if (!channel?.isTextBased()) return false; if (!channel?.isTextBased()) {
return false;
}
const message = this.getMessage(data, channel); const message = this.getMessage(data, channel);
if (!message) return false; if (!message) {
return false;
}
const poll = this.getPoll(data, message, channel); const poll = this.getPoll(data, message, channel);
if (!poll) return false; if (!poll) {
return false;
}
const answer = poll.answers.get(data.answer_id); const answer = poll.answers.get(data.answer_id);
if (!answer) return false; if (!answer) {
return false;
}
answer.voters.cache.delete(data.user_id); answer.voters.cache.delete(data.user_id);

View File

@@ -17,10 +17,14 @@ const { Action } = require('./Action.js');
class MessageReactionAddAction extends Action { class MessageReactionAddAction extends Action {
handle(data, fromStructure = false) { handle(data, fromStructure = false) {
if (!data.emoji) return false; if (!data.emoji) {
return false;
}
const user = this.getUserFromMember(data); const user = this.getUserFromMember(data);
if (!user) return false; if (!user) {
return false;
}
// Verify channel // Verify channel
const channel = this.getChannel({ const channel = this.getChannel({
@@ -30,24 +34,37 @@ class MessageReactionAddAction extends Action {
...this.spreadInjectedData(data), ...this.spreadInjectedData(data),
}); });
if (!channel?.isTextBased()) return false; if (!channel?.isTextBased()) {
return false;
}
// Verify message // Verify message
const message = this.getMessage(data, channel); const message = this.getMessage(data, channel);
if (!message) return false; if (!message) {
return false;
}
// Verify reaction // Verify reaction
const includePartial = this.client.options.partials.includes(Partials.Reaction); const includePartial = this.client.options.partials.includes(Partials.Reaction);
if (message.partial && !includePartial) return false; if (message.partial && !includePartial) {
return false;
}
const reaction = message.reactions._add({ const reaction = message.reactions._add({
emoji: data.emoji, emoji: data.emoji,
count: message.partial ? null : 0, count: message.partial ? null : 0,
me: user.id === this.client.user.id, me: user.id === this.client.user.id,
burst_colors: data.burst_colors, burst_colors: data.burst_colors,
}); });
if (!reaction) return false; if (!reaction) {
return false;
}
reaction._add(user, data.burst); reaction._add(user, data.burst);
if (fromStructure) return { message, reaction, user }; if (fromStructure) {
return { message, reaction, user };
}
/** /**
* Provides additional information about altered reaction * Provides additional information about altered reaction
* *

View File

@@ -13,10 +13,14 @@ const { Action } = require('./Action.js');
class MessageReactionRemoveAction extends Action { class MessageReactionRemoveAction extends Action {
handle(data) { handle(data) {
if (!data.emoji) return false; if (!data.emoji) {
return false;
}
const user = this.getUser(data); const user = this.getUser(data);
if (!user) return false; if (!user) {
return false;
}
// Verify channel // Verify channel
const channel = this.getChannel({ const channel = this.getChannel({
@@ -24,15 +28,22 @@ class MessageReactionRemoveAction extends Action {
...('guild_id' in data && { guild_id: data.guild_id }), ...('guild_id' in data && { guild_id: data.guild_id }),
user_id: data.user_id, user_id: data.user_id,
}); });
if (!channel?.isTextBased()) return false; if (!channel?.isTextBased()) {
return false;
}
// Verify message // Verify message
const message = this.getMessage(data, channel); const message = this.getMessage(data, channel);
if (!message) return false; if (!message) {
return false;
}
// Verify reaction // Verify reaction
const reaction = this.getReaction(data, message, user); const reaction = this.getReaction(data, message, user);
if (!reaction) return false; if (!reaction) {
return false;
}
reaction._remove(user, data.burst); reaction._remove(user, data.burst);
/** /**
* Emitted whenever a reaction is removed from a cached message. * Emitted whenever a reaction is removed from a cached message.

View File

@@ -7,11 +7,15 @@ class MessageReactionRemoveAllAction extends Action {
handle(data) { handle(data) {
// Verify channel // Verify channel
const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) }); const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) });
if (!channel?.isTextBased()) return false; if (!channel?.isTextBased()) {
return false;
}
// Verify message // Verify message
const message = this.getMessage(data, channel); const message = this.getMessage(data, channel);
if (!message) return false; if (!message) {
return false;
}
// Copy removed reactions to emit for the event. // Copy removed reactions to emit for the event.
const removed = message.reactions.cache.clone(); const removed = message.reactions.cache.clone();

View File

@@ -6,14 +6,23 @@ const { Action } = require('./Action.js');
class MessageReactionRemoveEmojiAction extends Action { class MessageReactionRemoveEmojiAction extends Action {
handle(data) { handle(data) {
const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) }); const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) });
if (!channel?.isTextBased()) return false; if (!channel?.isTextBased()) {
return false;
}
const message = this.getMessage(data, channel); const message = this.getMessage(data, channel);
if (!message) return false; if (!message) {
return false;
}
const reaction = this.getReaction(data, message); const reaction = this.getReaction(data, message);
if (!reaction) return false; if (!reaction) {
if (!message.partial) message.reactions.cache.delete(reaction.emoji.id ?? reaction.emoji.name); return false;
}
if (!message.partial) {
message.reactions.cache.delete(reaction.emoji.id ?? reaction.emoji.name);
}
/** /**
* Emitted when a bot removes an emoji reaction from a cached message. * Emitted when a bot removes an emoji reaction from a cached message.

View File

@@ -6,7 +6,9 @@ class MessageUpdateAction extends Action {
handle(data) { handle(data) {
const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) }); const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) });
if (channel) { if (channel) {
if (!channel.isTextBased()) return {}; if (!channel.isTextBased()) {
return {};
}
const { id, channel_id, guild_id, author, timestamp, type } = data; const { id, channel_id, guild_id, author, timestamp, type } = data;
const message = this.getMessage({ id, channel_id, guild_id, author, timestamp, type }, channel); const message = this.getMessage({ id, channel_id, guild_id, author, timestamp, type }, channel);

View File

@@ -20,7 +20,10 @@ class ThreadMembersUpdateAction extends Action {
data.removed_member_ids?.reduce((removedMembersIds, removedMembersId) => { data.removed_member_ids?.reduce((removedMembersIds, removedMembersId) => {
const threadMember = this.getThreadMember(removedMembersId, thread.members); const threadMember = this.getThreadMember(removedMembersId, thread.members);
if (threadMember) removedMembersIds.set(threadMember.id, threadMember); if (threadMember) {
removedMembersIds.set(threadMember.id, threadMember);
}
thread.members.cache.delete(removedMembersId); thread.members.cache.delete(removedMembersId);
return removedMembersIds; return removedMembersIds;
}, removedMembers); }, removedMembers);

View File

@@ -7,7 +7,9 @@ const { Action } = require('./Action.js');
class TypingStartAction extends Action { class TypingStartAction extends Action {
handle(data) { handle(data) {
const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) }); const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) });
if (!channel) return; if (!channel) {
return;
}
if (!channel.isTextBased()) { if (!channel.isTextBased()) {
this.client.emit(Events.Warn, `Discord sent a typing packet to a ${channel.type} channel ${channel.id}`); this.client.emit(Events.Warn, `Discord sent a typing packet to a ${channel.type} channel ${channel.id}`);

View File

@@ -5,7 +5,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
/** /**
* Emitted whenever an auto moderation rule is triggered. * Emitted whenever an auto moderation rule is triggered.

View File

@@ -4,7 +4,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
const autoModerationRule = guild.autoModerationRules._add(data); const autoModerationRule = guild.autoModerationRules._add(data);

View File

@@ -4,10 +4,14 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
const autoModerationRule = guild.autoModerationRules.cache.get(data.id); const autoModerationRule = guild.autoModerationRules.cache.get(data.id);
if (!autoModerationRule) return; if (!autoModerationRule) {
return;
}
guild.autoModerationRules.cache.delete(autoModerationRule.id); guild.autoModerationRules.cache.delete(autoModerationRule.id);

View File

@@ -4,7 +4,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
const oldAutoModerationRule = guild.autoModerationRules.cache.get(data.id)?._clone() ?? null; const oldAutoModerationRule = guild.autoModerationRules.cache.get(data.id)?._clone() ?? null;
const newAutoModerationRule = guild.autoModerationRules._add(data); const newAutoModerationRule = guild.autoModerationRules._add(data);

View File

@@ -5,7 +5,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
const auditLogEntry = new GuildAuditLogsEntry(guild, data); const auditLogEntry = new GuildAuditLogsEntry(guild, data);

View File

@@ -4,7 +4,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
/** /**
* Emitted whenever a member is banned from a guild. * Emitted whenever a member is banned from a guild.

View File

@@ -5,7 +5,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
const ban = guild.bans.cache.get(data.user.id) ?? new GuildBan(client, data, guild); const ban = guild.bans.cache.get(data.user.id) ?? new GuildBan(client, data, guild);

View File

@@ -4,7 +4,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.id); const guild = client.guilds.cache.get(data.id);
if (!guild) return; if (!guild) {
return;
}
if (data.unavailable) { if (data.unavailable) {
guild.available = false; guild.available = false;
@@ -22,7 +24,10 @@ module.exports = (client, { d: data }) => {
return; return;
} }
for (const channel of guild.channels.cache.values()) client.channels._remove(channel.id); for (const channel of guild.channels.cache.values()) {
client.channels._remove(channel.id);
}
client.voice.adapters.get(data.id)?.destroy(); client.voice.adapters.get(data.id)?.destroy();
client.guilds.cache.delete(guild.id); client.guilds.cache.delete(guild.id);

View File

@@ -4,7 +4,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
/** /**
* Emitted whenever a guild integration is updated * Emitted whenever a guild integration is updated

View File

@@ -5,12 +5,20 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
const members = new Collection(); const members = new Collection();
for (const member of data.members) members.set(member.user.id, guild.members._add(member)); for (const member of data.members) {
members.set(member.user.id, guild.members._add(member));
}
if (data.presences) { if (data.presences) {
for (const presence of data.presences) guild.presences._add(Object.assign(presence, { guild })); for (const presence of data.presences) {
guild.presences._add(Object.assign(presence, { guild }));
}
} }
/** /**

View File

@@ -4,10 +4,14 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
const role = guild.roles.cache.get(data.role.id); const role = guild.roles.cache.get(data.role.id);
if (!role) return; if (!role) {
return;
}
const old = role._update(data.role); const old = role._update(data.role);

View File

@@ -4,7 +4,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
const guildScheduledEvent = guild.scheduledEvents._add(data); const guildScheduledEvent = guild.scheduledEvents._add(data);

View File

@@ -4,7 +4,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
const oldGuildScheduledEvent = guild.scheduledEvents.cache.get(data.id)?._clone() ?? null; const oldGuildScheduledEvent = guild.scheduledEvents.cache.get(data.id)?._clone() ?? null;
const newGuildScheduledEvent = guild.scheduledEvents._add(data); const newGuildScheduledEvent = guild.scheduledEvents._add(data);

View File

@@ -6,7 +6,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
const soundboardSounds = new Collection(); const soundboardSounds = new Collection();

View File

@@ -5,7 +5,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
const soundboardSound = guild.soundboardSounds._add(data); const soundboardSound = guild.soundboardSounds._add(data);

View File

@@ -5,7 +5,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
const oldGuildSoundboardSound = guild.soundboardSounds.cache.get(data.sound_id)?._clone() ?? null; const oldGuildSoundboardSound = guild.soundboardSounds.cache.get(data.sound_id)?._clone() ?? null;
const newGuildSoundboardSound = guild.soundboardSounds._add(data); const newGuildSoundboardSound = guild.soundboardSounds._add(data);

View File

@@ -5,7 +5,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const channel = client.channels.cache.get(data.channel_id); const channel = client.channels.cache.get(data.channel_id);
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!channel) return; if (!channel) {
return;
}
const inviteData = Object.assign(data, { channel, guild }); const inviteData = Object.assign(data, { channel, guild });
const invite = guild.invites._add(inviteData); const invite = guild.invites._add(inviteData);

View File

@@ -6,7 +6,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const channel = client.channels.cache.get(data.channel_id); const channel = client.channels.cache.get(data.channel_id);
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!channel) return; if (!channel) {
return;
}
const inviteData = Object.assign(data, { channel, guild }); const inviteData = Object.assign(data, { channel, guild });
const invite = new GuildInvite(client, inviteData); const invite = new GuildInvite(client, inviteData);

View File

@@ -9,12 +9,18 @@ module.exports = (client, { d: data }) => {
user = client.users._add(data.user); user = client.users._add(data.user);
} }
if (!user) return; if (!user) {
return;
}
if (data.user.username && !user._equals(data.user)) client.actions.UserUpdate.handle(data.user); if (data.user.username && !user._equals(data.user)) {
client.actions.UserUpdate.handle(data.user);
}
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
const oldPresence = guild.presences.cache.get(user.id)?._clone() ?? null; const oldPresence = guild.presences.cache.get(user.id)?._clone() ?? null;

View File

@@ -6,7 +6,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
const soundboardSounds = new Collection(); const soundboardSounds = new Collection();

View File

@@ -4,7 +4,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const thread = client.channels.cache.get(data.id); const thread = client.channels.cache.get(data.id);
if (!thread) return; if (!thread) {
return;
}
client.channels._remove(thread.id); client.channels._remove(thread.id);

View File

@@ -5,12 +5,16 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
if (data.channel_ids) { if (data.channel_ids) {
for (const id of data.channel_ids) { for (const id of data.channel_ids) {
const channel = client.channels.cache.get(id); const channel = client.channels.cache.get(id);
if (channel) removeStaleThreads(client, channel); if (channel) {
removeStaleThreads(client, channel);
}
} }
} else { } else {
for (const channel of guild.channels.cache.values()) { for (const channel of guild.channels.cache.values()) {
@@ -42,7 +46,9 @@ module.exports = (client, { d: data }) => {
}; };
function removeStaleThreads(client, channel) { function removeStaleThreads(client, channel) {
if (!channel.threads) return; if (!channel.threads) {
return;
}
for (const thread of channel.threads.cache.values()) { for (const thread of channel.threads.cache.values()) {
if (!thread.archived) { if (!thread.archived) {

View File

@@ -5,7 +5,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
// Discord sends the thread id as id in this object // Discord sends the thread id as id in this object
const thread = client.channels.cache.get(data.id); const thread = client.channels.cache.get(data.id);
if (!thread) return; if (!thread) {
return;
}
const member = thread.members.cache.get(data.user_id); const member = thread.members.cache.get(data.user_id);
if (!member) { if (!member) {

View File

@@ -5,7 +5,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
/** /**
* Emitted when someone sends an effect, such as an emoji reaction, in a voice channel the client is connected to. * Emitted when someone sends an effect, such as an emoji reaction, in a voice channel the client is connected to.

View File

@@ -5,7 +5,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id); const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return; if (!guild) {
return;
}
// Update the state // Update the state
const oldState = const oldState =

View File

@@ -4,7 +4,9 @@ const { Events } = require('../../../util/Events.js');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const channel = client.channels.cache.get(data.channel_id); const channel = client.channels.cache.get(data.channel_id);
if (!channel) return; if (!channel) {
return;
}
/** /**
* Emitted whenever a channel has its webhooks changed. * Emitted whenever a channel has its webhooks changed.

View File

@@ -34,11 +34,23 @@ function makeDiscordjsError(Base) {
* @ignore * @ignore
*/ */
function message(code, args) { function message(code, args) {
if (!(code in ErrorCodes)) throw new Error('Error code must be a valid DiscordjsErrorCodes'); if (!(code in ErrorCodes)) {
throw new Error('Error code must be a valid DiscordjsErrorCodes');
}
const msg = Messages[code]; const msg = Messages[code];
if (!msg) throw new Error(`No message associated with error code: ${code}.`); if (!msg) {
if (typeof msg === 'function') return msg(...args); throw new Error(`No message associated with error code: ${code}.`);
if (!args?.length) return msg; }
if (typeof msg === 'function') {
return msg(...args);
}
if (!args?.length) {
return msg;
}
args.unshift(msg); args.unshift(msg);
return String(...args); return String(...args);
} }

View File

@@ -123,13 +123,19 @@ class ApplicationCommandManager extends CachedManager {
* .catch(console.error) * .catch(console.error)
*/ */
async fetch(options) { async fetch(options) {
if (!options) return this._fetchMany(); if (!options) {
return this._fetchMany();
}
if (typeof options === 'string') return this._fetchSingle({ id: options }); if (typeof options === 'string') {
return this._fetchSingle({ id: options });
}
const { cache, force, guildId, id, locale, withLocalizations } = options; const { cache, force, guildId, id, locale, withLocalizations } = options;
if (id) return this._fetchSingle({ cache, force, guildId, id }); if (id) {
return this._fetchSingle({ cache, force, guildId, id });
}
return this._fetchMany({ cache, guildId, locale, withLocalizations }); return this._fetchMany({ cache, guildId, locale, withLocalizations });
} }
@@ -137,7 +143,9 @@ class ApplicationCommandManager extends CachedManager {
async _fetchSingle({ cache, force = false, guildId, id }) { async _fetchSingle({ cache, force = false, guildId, id }) {
if (!force) { if (!force) {
const existing = this.cache.get(id); const existing = this.cache.get(id);
if (existing) return existing; if (existing) {
return existing;
}
} }
const command = await this.client.rest.get(this.commandPath({ id, guildId })); const command = await this.client.rest.get(this.commandPath({ id, guildId }));
@@ -229,7 +237,9 @@ class ApplicationCommandManager extends CachedManager {
*/ */
async edit(command, data, guildId) { async edit(command, data, guildId) {
const id = this.resolveId(command); const id = this.resolveId(command);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable'); if (!id) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable');
}
const patched = await this.client.rest.patch(this.commandPath({ id, guildId }), { const patched = await this.client.rest.patch(this.commandPath({ id, guildId }), {
body: this.constructor.transformCommand(data), body: this.constructor.transformCommand(data),
@@ -252,7 +262,9 @@ class ApplicationCommandManager extends CachedManager {
*/ */
async delete(command, guildId) { async delete(command, guildId) {
const id = this.resolveId(command); const id = this.resolveId(command);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable'); if (!id) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable');
}
await this.client.rest.delete(this.commandPath({ id, guildId })); await this.client.rest.delete(this.commandPath({ id, guildId }));
@@ -269,7 +281,9 @@ class ApplicationCommandManager extends CachedManager {
* @private * @private
*/ */
static transformCommand(command) { static transformCommand(command) {
if (isJSONEncodable(command)) return command.toJSON(); if (isJSONEncodable(command)) {
return command.toJSON();
}
let default_member_permissions; let default_member_permissions;

View File

@@ -226,7 +226,9 @@ class ApplicationCommandPermissionsManager extends BaseManager {
try { try {
existingPermissions = await this.fetch({ guild: options.guildId, command: commandId }); existingPermissions = await this.fetch({ guild: options.guildId, command: commandId });
} catch (error) { } catch (error) {
if (error.code !== RESTJSONErrorCodes.UnknownApplicationCommandPermissions) throw error; if (error.code !== RESTJSONErrorCodes.UnknownApplicationCommandPermissions) {
throw error;
}
} }
const newPermissions = permissions.slice(); const newPermissions = permissions.slice();
@@ -303,7 +305,10 @@ class ApplicationCommandPermissionsManager extends BaseManager {
if (Array.isArray(users)) { if (Array.isArray(users)) {
for (const user of users) { for (const user of users) {
const userId = this.client.users.resolveId(user); const userId = this.client.users.resolveId(user);
if (!userId) throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'users', user); if (!userId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'users', user);
}
resolvedUserIds.push(userId); resolvedUserIds.push(userId);
} }
} }
@@ -316,9 +321,15 @@ class ApplicationCommandPermissionsManager extends BaseManager {
continue; continue;
} }
if (!this.guild) throw new DiscordjsError(ErrorCodes.GuildUncachedEntityResolve, 'roles'); if (!this.guild) {
throw new DiscordjsError(ErrorCodes.GuildUncachedEntityResolve, 'roles');
}
const roleId = this.guild.roles.resolveId(role); const roleId = this.guild.roles.resolveId(role);
if (!roleId) throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'users', role); if (!roleId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'users', role);
}
resolvedRoleIds.push(roleId); resolvedRoleIds.push(roleId);
} }
} }
@@ -331,9 +342,15 @@ class ApplicationCommandPermissionsManager extends BaseManager {
continue; continue;
} }
if (!this.guild) throw new DiscordjsError(ErrorCodes.GuildUncachedEntityResolve, 'channels'); if (!this.guild) {
throw new DiscordjsError(ErrorCodes.GuildUncachedEntityResolve, 'channels');
}
const channelId = this.guild.channels.resolveId(channel); const channelId = this.guild.channels.resolveId(channel);
if (!channelId) throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'channels', channel); if (!channelId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'channels', channel);
}
resolvedChannelIds.push(channelId); resolvedChannelIds.push(channelId);
} }
} }
@@ -342,7 +359,9 @@ class ApplicationCommandPermissionsManager extends BaseManager {
try { try {
existing = await this.fetch({ guild: options.guildId, command: commandId }); existing = await this.fetch({ guild: options.guildId, command: commandId });
} catch (error) { } catch (error) {
if (error.code !== RESTJSONErrorCodes.UnknownApplicationCommandPermissions) throw error; if (error.code !== RESTJSONErrorCodes.UnknownApplicationCommandPermissions) {
throw error;
}
} }
const permissions = existing.filter(perm => { const permissions = existing.filter(perm => {
@@ -383,7 +402,9 @@ class ApplicationCommandPermissionsManager extends BaseManager {
*/ */
async has({ guild, command, permissionId, permissionType }) { async has({ guild, command, permissionId, permissionType }) {
const { guildId, commandId } = this._validateOptions(guild, command); const { guildId, commandId } = this._validateOptions(guild, command);
if (!commandId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable'); if (!commandId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable');
}
if (!permissionId) { if (!permissionId) {
throw new DiscordjsTypeError( throw new DiscordjsTypeError(
@@ -397,7 +418,10 @@ class ApplicationCommandPermissionsManager extends BaseManager {
if (typeof permissionId !== 'string') { if (typeof permissionId !== 'string') {
resolvedId = this.client.users.resolveId(permissionId); resolvedId = this.client.users.resolveId(permissionId);
if (!resolvedId) { if (!resolvedId) {
if (!this.guild) throw new DiscordjsError(ErrorCodes.GuildUncachedEntityResolve, 'roles'); if (!this.guild) {
throw new DiscordjsError(ErrorCodes.GuildUncachedEntityResolve, 'roles');
}
resolvedId = this.guild.roles.resolveId(permissionId); resolvedId = this.guild.roles.resolveId(permissionId);
} }
@@ -416,7 +440,9 @@ class ApplicationCommandPermissionsManager extends BaseManager {
try { try {
existing = await this.fetch({ guild: guildId, command: commandId }); existing = await this.fetch({ guild: guildId, command: commandId });
} catch (error) { } catch (error) {
if (error.code !== RESTJSONErrorCodes.UnknownApplicationCommandPermissions) throw error; if (error.code !== RESTJSONErrorCodes.UnknownApplicationCommandPermissions) {
throw error;
}
} }
// Check permission type if provided for the single edge case where a channel id is the same as the everyone role id // Check permission type if provided for the single edge case where a channel id is the same as the everyone role id
@@ -425,7 +451,10 @@ class ApplicationCommandPermissionsManager extends BaseManager {
_validateOptions(guild, command) { _validateOptions(guild, command) {
const guildId = this.guildId ?? this.client.guilds.resolveId(guild); const guildId = this.guildId ?? this.client.guilds.resolveId(guild);
if (!guildId) throw new DiscordjsError(ErrorCodes.GlobalCommandPermissions); if (!guildId) {
throw new DiscordjsError(ErrorCodes.GlobalCommandPermissions);
}
let commandId = this.commandId; let commandId = this.commandId;
if (command && !commandId) { if (command && !commandId) {
commandId = this.manager.resolveId?.(command); commandId = this.manager.resolveId?.(command);

View File

@@ -54,7 +54,9 @@ class ApplicationEmojiManager extends CachedManager {
*/ */
async create({ attachment, name }) { async create({ attachment, name }) {
const image = await resolveImage(attachment); const image = await resolveImage(attachment);
if (!image) throw new DiscordjsTypeError(ErrorCodes.ReqResourceType); if (!image) {
throw new DiscordjsTypeError(ErrorCodes.ReqResourceType);
}
const body = { image, name }; const body = { image, name };
@@ -83,7 +85,9 @@ class ApplicationEmojiManager extends CachedManager {
if (id) { if (id) {
if (!force) { if (!force) {
const existing = this.cache.get(id); const existing = this.cache.get(id);
if (existing) return existing; if (existing) {
return existing;
}
} }
const emoji = await this.client.rest.get(Routes.applicationEmoji(this.application.id, id)); const emoji = await this.client.rest.get(Routes.applicationEmoji(this.application.id, id));
@@ -92,7 +96,10 @@ class ApplicationEmojiManager extends CachedManager {
const { items: data } = await this.client.rest.get(Routes.applicationEmojis(this.application.id)); const { items: data } = await this.client.rest.get(Routes.applicationEmojis(this.application.id));
const emojis = new Collection(); const emojis = new Collection();
for (const emoji of data) emojis.set(emoji.id, this._add(emoji, cache)); for (const emoji of data) {
emojis.set(emoji.id, this._add(emoji, cache));
}
return emojis; return emojis;
} }
@@ -104,7 +111,10 @@ class ApplicationEmojiManager extends CachedManager {
*/ */
async delete(emoji) { async delete(emoji) {
const id = this.resolveId(emoji); const id = this.resolveId(emoji);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true); if (!id) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true);
}
await this.client.rest.delete(Routes.applicationEmoji(this.application.id, id)); await this.client.rest.delete(Routes.applicationEmoji(this.application.id, id));
} }
@@ -117,7 +127,9 @@ class ApplicationEmojiManager extends CachedManager {
*/ */
async edit(emoji, options) { async edit(emoji, options) {
const id = this.resolveId(emoji); const id = this.resolveId(emoji);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true); if (!id) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true);
}
const newData = await this.client.rest.patch(Routes.applicationEmoji(this.application.id, id), { const newData = await this.client.rest.patch(Routes.applicationEmoji(this.application.id, id), {
body: { body: {
@@ -141,7 +153,9 @@ class ApplicationEmojiManager extends CachedManager {
*/ */
async fetchAuthor(emoji) { async fetchAuthor(emoji) {
const id = this.resolveId(emoji); const id = this.resolveId(emoji);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true); if (!id) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true);
}
const data = await this.client.rest.get(Routes.applicationEmoji(this.application.id, id)); const data = await this.client.rest.get(Routes.applicationEmoji(this.application.id, id));

View File

@@ -265,7 +265,10 @@ class AutoModerationRuleManager extends CachedManager {
* .catch(console.error) * .catch(console.error)
*/ */
async fetch(options) { async fetch(options) {
if (!options) return this._fetchMany(); if (!options) {
return this._fetchMany();
}
const { autoModerationRule, cache, force } = options; const { autoModerationRule, cache, force } = options;
const resolvedAutoModerationRule = this.resolveId(autoModerationRule ?? options); const resolvedAutoModerationRule = this.resolveId(autoModerationRule ?? options);
if (resolvedAutoModerationRule) { if (resolvedAutoModerationRule) {
@@ -278,7 +281,9 @@ class AutoModerationRuleManager extends CachedManager {
async _fetchSingle({ autoModerationRule, cache, force = false }) { async _fetchSingle({ autoModerationRule, cache, force = false }) {
if (!force) { if (!force) {
const existing = this.cache.get(autoModerationRule); const existing = this.cache.get(autoModerationRule);
if (existing) return existing; if (existing) {
return existing;
}
} }
const data = await this.client.rest.get(Routes.guildAutoModerationRule(this.guild.id, autoModerationRule)); const data = await this.client.rest.get(Routes.guildAutoModerationRule(this.guild.id, autoModerationRule));

View File

@@ -60,7 +60,10 @@ class CachedManager extends DataManager {
} }
const entry = this.holds ? new this.holds(this.client, data, ...extras) : data; const entry = this.holds ? new this.holds(this.client, data, ...extras) : data;
if (cache) this.cache.set(id ?? entry.id, entry); if (cache) {
this.cache.set(id ?? entry.id, entry);
}
return entry; return entry;
} }
} }

View File

@@ -45,7 +45,10 @@ class ChannelManager extends CachedManager {
_add(data, guild, { cache = true, allowUnknownGuild = false } = {}) { _add(data, guild, { cache = true, allowUnknownGuild = false } = {}) {
const existing = this.cache.get(data.id); const existing = this.cache.get(data.id);
if (existing) { if (existing) {
if (cache) existing._patch(data); if (cache) {
existing._patch(data);
}
guild?.channels?._add(existing); guild?.channels?._add(existing);
if (ThreadChannelTypes.includes(existing.type)) { if (ThreadChannelTypes.includes(existing.type)) {
existing.parent?.threads?._add(existing); existing.parent?.threads?._add(existing);
@@ -61,7 +64,9 @@ class ChannelManager extends CachedManager {
return null; return null;
} }
if (cache && !allowUnknownGuild) this.cache.set(channel.id, channel); if (cache && !allowUnknownGuild) {
this.cache.set(channel.id, channel);
}
return channel; return channel;
} }
@@ -71,7 +76,9 @@ class ChannelManager extends CachedManager {
channel?.guild?.channels.cache.delete(id); channel?.guild?.channels.cache.delete(id);
for (const [code, invite] of channel?.guild?.invites.cache ?? []) { for (const [code, invite] of channel?.guild?.invites.cache ?? []) {
if (invite.channelId === id) channel.guild.invites.cache.delete(code); if (invite.channelId === id) {
channel.guild.invites.cache.delete(code);
}
} }
channel?.parent?.threads?.cache.delete(id); channel?.parent?.threads?.cache.delete(id);
@@ -136,7 +143,9 @@ class ChannelManager extends CachedManager {
async fetch(id, { allowUnknownGuild = false, cache = true, force = false } = {}) { async fetch(id, { allowUnknownGuild = false, cache = true, force = false } = {}) {
if (!force) { if (!force) {
const existing = this.cache.get(id); const existing = this.cache.get(id);
if (existing && !existing.partial) return existing; if (existing && !existing.partial) {
return existing;
}
} }
const data = await this.client.rest.get(Routes.channel(id)); const data = await this.client.rest.get(Routes.channel(id));

View File

@@ -41,8 +41,14 @@ class DataManager extends BaseManager {
* @returns {?Object} An instance from this Manager * @returns {?Object} An instance from this Manager
*/ */
resolve(idOrInstance) { resolve(idOrInstance) {
if (idOrInstance instanceof this.holds) return idOrInstance; if (idOrInstance instanceof this.holds) {
if (typeof idOrInstance === 'string') return this.cache.get(idOrInstance) ?? null; return idOrInstance;
}
if (typeof idOrInstance === 'string') {
return this.cache.get(idOrInstance) ?? null;
}
return null; return null;
} }
@@ -53,8 +59,14 @@ class DataManager extends BaseManager {
* @returns {?Snowflake} * @returns {?Snowflake}
*/ */
resolveId(idOrInstance) { resolveId(idOrInstance) {
if (idOrInstance instanceof this.holds) return idOrInstance.id; if (idOrInstance instanceof this.holds) {
if (typeof idOrInstance === 'string') return idOrInstance; return idOrInstance.id;
}
if (typeof idOrInstance === 'string') {
return idOrInstance;
}
return null; return null;
} }

View File

@@ -72,7 +72,10 @@ class EntitlementManager extends CachedManager {
* @returns {Promise<Entitlement|Collection<Snowflake, Entitlement>>} * @returns {Promise<Entitlement|Collection<Snowflake, Entitlement>>}
*/ */
async fetch(options) { async fetch(options) {
if (!options) return this._fetchMany(options); if (!options) {
return this._fetchMany(options);
}
const { entitlement, cache, force } = options; const { entitlement, cache, force } = options;
const resolvedEntitlement = this.resolveId(entitlement ?? options); const resolvedEntitlement = this.resolveId(entitlement ?? options);
@@ -134,7 +137,9 @@ class EntitlementManager extends CachedManager {
*/ */
async createTest({ sku, guild, user }) { async createTest({ sku, guild, user }) {
const skuId = resolveSKUId(sku); const skuId = resolveSKUId(sku);
if (!skuId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sku', 'SKUResolvable'); if (!skuId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sku', 'SKUResolvable');
}
if ((guild && user) || (!guild && !user)) { if ((guild && user) || (!guild && !user)) {
throw new DiscordjsTypeError(ErrorCodes.EntitlementCreateInvalidOwner); throw new DiscordjsTypeError(ErrorCodes.EntitlementCreateInvalidOwner);
@@ -165,7 +170,9 @@ class EntitlementManager extends CachedManager {
*/ */
async deleteTest(entitlement) { async deleteTest(entitlement) {
const resolved = this.resolveId(entitlement); const resolved = this.resolveId(entitlement);
if (!resolved) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'entitlement', 'EntitlementResolvable'); if (!resolved) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'entitlement', 'EntitlementResolvable');
}
await this.client.rest.delete(Routes.entitlement(this.client.application.id, resolved)); await this.client.rest.delete(Routes.entitlement(this.client.application.id, resolved));
} }

View File

@@ -102,10 +102,15 @@ class GuildBanManager extends CachedManager {
* .catch(console.error); * .catch(console.error);
*/ */
async fetch(options) { async fetch(options) {
if (!options) return this._fetchMany(); if (!options) {
return this._fetchMany();
}
const { user, cache, force, limit, before, after } = options; const { user, cache, force, limit, before, after } = options;
const resolvedUser = this.client.users.resolveId(user ?? options); const resolvedUser = this.client.users.resolveId(user ?? options);
if (resolvedUser) return this._fetchSingle({ user: resolvedUser, cache, force }); if (resolvedUser) {
return this._fetchSingle({ user: resolvedUser, cache, force });
}
if (!before && !after && !limit && cache === undefined) { if (!before && !after && !limit && cache === undefined) {
throw new DiscordjsError(ErrorCodes.FetchBanResolveId); throw new DiscordjsError(ErrorCodes.FetchBanResolveId);
@@ -117,7 +122,9 @@ class GuildBanManager extends CachedManager {
async _fetchSingle({ user, cache, force = false }) { async _fetchSingle({ user, cache, force = false }) {
if (!force) { if (!force) {
const existing = this.cache.get(user); const existing = this.cache.get(user);
if (existing && !existing.partial) return existing; if (existing && !existing.partial) {
return existing;
}
} }
const data = await this.client.rest.get(Routes.guildBan(this.guild.id, user)); const data = await this.client.rest.get(Routes.guildBan(this.guild.id, user));
@@ -152,9 +159,14 @@ class GuildBanManager extends CachedManager {
* await guild.bans.create('84484653687267328'); * await guild.bans.create('84484653687267328');
*/ */
async create(user, options = {}) { async create(user, options = {}) {
if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true); if (typeof options !== 'object') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
}
const id = this.client.users.resolveId(user); const id = this.client.users.resolveId(user);
if (!id) throw new DiscordjsError(ErrorCodes.BanResolveId, true); if (!id) {
throw new DiscordjsError(ErrorCodes.BanResolveId, true);
}
await this.client.rest.put(Routes.guildBan(this.guild.id, id), { await this.client.rest.put(Routes.guildBan(this.guild.id, id), {
body: { body: {
@@ -176,7 +188,10 @@ class GuildBanManager extends CachedManager {
*/ */
async remove(user, reason) { async remove(user, reason) {
const id = this.client.users.resolveId(user); const id = this.client.users.resolveId(user);
if (!id) throw new DiscordjsError(ErrorCodes.BanResolveId); if (!id) {
throw new DiscordjsError(ErrorCodes.BanResolveId);
}
await this.client.rest.delete(Routes.guildBan(this.guild.id, id), { reason }); await this.client.rest.delete(Routes.guildBan(this.guild.id, id), { reason });
} }
@@ -208,10 +223,14 @@ class GuildBanManager extends CachedManager {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'users', 'Array or Collection of UserResolvable', true); throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'users', 'Array or Collection of UserResolvable', true);
} }
if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true); if (typeof options !== 'object') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
}
const userIds = users.map(user => this.client.users.resolveId(user)); const userIds = users.map(user => this.client.users.resolveId(user));
if (userIds.length === 0) throw new DiscordjsError(ErrorCodes.BulkBanUsersOptionEmpty); if (userIds.length === 0) {
throw new DiscordjsError(ErrorCodes.BulkBanUsersOptionEmpty);
}
const result = await this.client.rest.post(Routes.guildBulkBan(this.guild.id), { const result = await this.client.rest.post(Routes.guildBulkBan(this.guild.id), {
body: { delete_message_seconds: options.deleteMessageSeconds, user_ids: userIds }, body: { delete_message_seconds: options.deleteMessageSeconds, user_ids: userIds },

View File

@@ -55,7 +55,10 @@ class GuildChannelManager extends CachedManager {
*/ */
get channelCountWithoutThreads() { get channelCountWithoutThreads() {
return this.cache.reduce((acc, channel) => { return this.cache.reduce((acc, channel) => {
if (ThreadChannelTypes.includes(channel.type)) return acc; if (ThreadChannelTypes.includes(channel.type)) {
return acc;
}
return acc + 1; return acc + 1;
}, 0); }, 0);
} }
@@ -69,7 +72,10 @@ class GuildChannelManager extends CachedManager {
_add(channel) { _add(channel) {
const existing = this.cache.get(channel.id); const existing = this.cache.get(channel.id);
if (existing) return existing; if (existing) {
return existing;
}
this.cache.set(channel.id, channel); this.cache.set(channel.id, channel);
return channel; return channel;
} }
@@ -90,7 +96,10 @@ class GuildChannelManager extends CachedManager {
* @returns {?(GuildChannel|ThreadChannel)} * @returns {?(GuildChannel|ThreadChannel)}
*/ */
resolve(channel) { resolve(channel) {
if (channel instanceof ThreadChannel) return super.cache.get(channel.id) ?? null; if (channel instanceof ThreadChannel) {
return super.cache.get(channel.id) ?? null;
}
return super.resolve(channel); return super.resolve(channel);
} }
@@ -101,7 +110,10 @@ class GuildChannelManager extends CachedManager {
* @returns {?Snowflake} * @returns {?Snowflake}
*/ */
resolveId(channel) { resolveId(channel) {
if (channel instanceof ThreadChannel) return super.resolveId(channel.id); if (channel instanceof ThreadChannel) {
return super.resolveId(channel.id);
}
return super.resolveId(channel); return super.resolveId(channel);
} }
@@ -250,7 +262,9 @@ class GuildChannelManager extends CachedManager {
*/ */
async createWebhook({ channel, name, avatar, reason }) { async createWebhook({ channel, name, avatar, reason }) {
const channelId = this.resolveId(channel); const channelId = this.resolveId(channel);
if (!channelId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable'); if (!channelId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
}
const resolvedAvatar = await resolveImage(avatar); const resolvedAvatar = await resolveImage(avatar);
@@ -309,7 +323,9 @@ class GuildChannelManager extends CachedManager {
*/ */
async edit(channel, options) { async edit(channel, options) {
const resolvedChannel = this.resolve(channel); const resolvedChannel = this.resolve(channel);
if (!resolvedChannel) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable'); if (!resolvedChannel) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
}
const parentId = options.parent && this.client.channels.resolveId(options.parent); const parentId = options.parent && this.client.channels.resolveId(options.parent);
@@ -380,7 +396,9 @@ class GuildChannelManager extends CachedManager {
*/ */
async setPosition(channel, position, { relative, reason } = {}) { async setPosition(channel, position, { relative, reason } = {}) {
const resolvedChannel = this.resolve(channel); const resolvedChannel = this.resolve(channel);
if (!resolvedChannel) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable'); if (!resolvedChannel) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
}
const updatedChannels = await setPosition( const updatedChannels = await setPosition(
resolvedChannel, resolvedChannel,
@@ -420,19 +438,27 @@ class GuildChannelManager extends CachedManager {
async fetch(id, { cache = true, force = false } = {}) { async fetch(id, { cache = true, force = false } = {}) {
if (id && !force) { if (id && !force) {
const existing = this.cache.get(id); const existing = this.cache.get(id);
if (existing) return existing; if (existing) {
return existing;
}
} }
if (id) { if (id) {
const innerData = await this.client.rest.get(Routes.channel(id)); const innerData = await this.client.rest.get(Routes.channel(id));
// Since this is the guild manager, throw if on a different guild // Since this is the guild manager, throw if on a different guild
if (this.guild.id !== innerData.guild_id) throw new DiscordjsError(ErrorCodes.GuildChannelUnowned); if (this.guild.id !== innerData.guild_id) {
throw new DiscordjsError(ErrorCodes.GuildChannelUnowned);
}
return this.client.channels._add(innerData, this.guild, { cache }); return this.client.channels._add(innerData, this.guild, { cache });
} }
const data = await this.client.rest.get(Routes.guildChannels(this.guild.id)); const data = await this.client.rest.get(Routes.guildChannels(this.guild.id));
const channels = new Collection(); const channels = new Collection();
for (const channel of data) channels.set(channel.id, this.client.channels._add(channel, this.guild, { cache })); for (const channel of data) {
channels.set(channel.id, this.client.channels._add(channel, this.guild, { cache }));
}
return channels; return channels;
} }
@@ -449,7 +475,10 @@ class GuildChannelManager extends CachedManager {
*/ */
async fetchWebhooks(channel) { async fetchWebhooks(channel) {
const id = this.resolveId(channel); const id = this.resolveId(channel);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable'); if (!id) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
}
const data = await this.client.rest.get(Routes.channelWebhooks(id)); const data = await this.client.rest.get(Routes.channelWebhooks(id));
return data.reduce((hooks, hook) => hooks.set(hook.id, new Webhook(this.client, hook)), new Collection()); return data.reduce((hooks, hook) => hooks.set(hook.id, new Webhook(this.client, hook)), new Collection());
} }
@@ -547,7 +576,10 @@ class GuildChannelManager extends CachedManager {
*/ */
async delete(channel, reason) { async delete(channel, reason) {
const id = this.resolveId(channel); const id = this.resolveId(channel);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable'); if (!id) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
}
await this.client.rest.delete(Routes.channel(id), { reason }); await this.client.rest.delete(Routes.channel(id), { reason });
this.client.actions.ChannelDelete.handle({ id }); this.client.actions.ChannelDelete.handle({ id });
} }

View File

@@ -54,8 +54,14 @@ class GuildEmojiManager extends CachedManager {
* @returns {?GuildEmoji} * @returns {?GuildEmoji}
*/ */
resolve(emoji) { resolve(emoji) {
if (emoji instanceof ReactionEmoji) return super.cache.get(emoji.id) ?? null; if (emoji instanceof ReactionEmoji) {
if (emoji instanceof ApplicationEmoji) return super.cache.get(emoji.id) ?? null; return super.cache.get(emoji.id) ?? null;
}
if (emoji instanceof ApplicationEmoji) {
return super.cache.get(emoji.id) ?? null;
}
return super.resolve(emoji); return super.resolve(emoji);
} }
@@ -66,8 +72,14 @@ class GuildEmojiManager extends CachedManager {
* @returns {?Snowflake} * @returns {?Snowflake}
*/ */
resolveId(emoji) { resolveId(emoji) {
if (emoji instanceof ReactionEmoji) return emoji.id; if (emoji instanceof ReactionEmoji) {
if (emoji instanceof ApplicationEmoji) return emoji.id; return emoji.id;
}
if (emoji instanceof ApplicationEmoji) {
return emoji.id;
}
return super.resolveId(emoji); return super.resolveId(emoji);
} }
@@ -88,9 +100,18 @@ class GuildEmojiManager extends CachedManager {
*/ */
resolveIdentifier(emoji) { resolveIdentifier(emoji) {
const emojiResolvable = this.resolve(emoji); const emojiResolvable = this.resolve(emoji);
if (emojiResolvable) return emojiResolvable.identifier; if (emojiResolvable) {
if (emoji instanceof ReactionEmoji) return emoji.identifier; return emojiResolvable.identifier;
if (emoji instanceof ApplicationEmoji) return emoji.identifier; }
if (emoji instanceof ReactionEmoji) {
return emoji.identifier;
}
if (emoji instanceof ApplicationEmoji) {
return emoji.identifier;
}
if (typeof emoji === 'string') { if (typeof emoji === 'string') {
const res = parseEmoji(emoji); const res = parseEmoji(emoji);
let identifier = emoji; let identifier = emoji;
@@ -98,7 +119,10 @@ class GuildEmojiManager extends CachedManager {
identifier = `${res.animated ? 'a:' : ''}${res.name}${res.id ? `:${res.id}` : ''}`; identifier = `${res.animated ? 'a:' : ''}${res.name}${res.id ? `:${res.id}` : ''}`;
} }
if (!identifier.includes('%')) return encodeURIComponent(identifier); if (!identifier.includes('%')) {
return encodeURIComponent(identifier);
}
return identifier; return identifier;
} }
@@ -133,7 +157,9 @@ class GuildEmojiManager extends CachedManager {
*/ */
async create({ attachment, name, roles, reason }) { async create({ attachment, name, roles, reason }) {
const image = await resolveImage(attachment); const image = await resolveImage(attachment);
if (!image) throw new DiscordjsTypeError(ErrorCodes.ReqResourceType); if (!image) {
throw new DiscordjsTypeError(ErrorCodes.ReqResourceType);
}
const body = { image, name }; const body = { image, name };
if (roles) { if (roles) {
@@ -182,7 +208,9 @@ class GuildEmojiManager extends CachedManager {
if (id) { if (id) {
if (!force) { if (!force) {
const existing = this.cache.get(id); const existing = this.cache.get(id);
if (existing) return existing; if (existing) {
return existing;
}
} }
const emoji = await this.client.rest.get(Routes.guildEmoji(this.guild.id, id)); const emoji = await this.client.rest.get(Routes.guildEmoji(this.guild.id, id));
@@ -191,7 +219,10 @@ class GuildEmojiManager extends CachedManager {
const data = await this.client.rest.get(Routes.guildEmojis(this.guild.id)); const data = await this.client.rest.get(Routes.guildEmojis(this.guild.id));
const emojis = new Collection(); const emojis = new Collection();
for (const emoji of data) emojis.set(emoji.id, this._add(emoji, cache)); for (const emoji of data) {
emojis.set(emoji.id, this._add(emoji, cache));
}
return emojis; return emojis;
} }
@@ -204,7 +235,10 @@ class GuildEmojiManager extends CachedManager {
*/ */
async delete(emoji, reason) { async delete(emoji, reason) {
const id = this.resolveId(emoji); const id = this.resolveId(emoji);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true); if (!id) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true);
}
await this.client.rest.delete(Routes.guildEmoji(this.guild.id, id), { reason }); await this.client.rest.delete(Routes.guildEmoji(this.guild.id, id), { reason });
} }
@@ -217,7 +251,10 @@ class GuildEmojiManager extends CachedManager {
*/ */
async edit(emoji, options) { async edit(emoji, options) {
const id = this.resolveId(emoji); const id = this.resolveId(emoji);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true); if (!id) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true);
}
const roles = options.roles?.map(role => this.guild.roles.resolveId(role)); const roles = options.roles?.map(role => this.guild.roles.resolveId(role));
const newData = await this.client.rest.patch(Routes.guildEmoji(this.guild.id, id), { const newData = await this.client.rest.patch(Routes.guildEmoji(this.guild.id, id), {
body: { body: {
@@ -244,13 +281,19 @@ class GuildEmojiManager extends CachedManager {
*/ */
async fetchAuthor(emoji) { async fetchAuthor(emoji) {
const resolvedEmoji = this.resolve(emoji); const resolvedEmoji = this.resolve(emoji);
if (!resolvedEmoji) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true); if (!resolvedEmoji) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true);
}
if (resolvedEmoji.managed) { if (resolvedEmoji.managed) {
throw new DiscordjsError(ErrorCodes.EmojiManaged); throw new DiscordjsError(ErrorCodes.EmojiManaged);
} }
const { me } = this.guild.members; const { me } = this.guild.members;
if (!me) throw new DiscordjsError(ErrorCodes.GuildUncachedMe); if (!me) {
throw new DiscordjsError(ErrorCodes.GuildUncachedMe);
}
if (!me.permissions.has(PermissionFlagsBits.ManageGuildExpressions)) { if (!me.permissions.has(PermissionFlagsBits.ManageGuildExpressions)) {
throw new DiscordjsError(ErrorCodes.MissingManageGuildExpressionsPermission, this.guild); throw new DiscordjsError(ErrorCodes.MissingManageGuildExpressionsPermission, this.guild);
} }

View File

@@ -142,21 +142,33 @@ class GuildInviteManager extends CachedManager {
* .catch(console.error); * .catch(console.error);
*/ */
async fetch(options) { async fetch(options) {
if (!options) return this._fetchMany(); if (!options) {
return this._fetchMany();
}
if (typeof options === 'string') { if (typeof options === 'string') {
const code = resolveInviteCode(options); const code = resolveInviteCode(options);
if (!code) throw new DiscordjsError(ErrorCodes.InviteResolveCode); if (!code) {
throw new DiscordjsError(ErrorCodes.InviteResolveCode);
}
return this._fetchSingle({ code, cache: true }); return this._fetchSingle({ code, cache: true });
} }
if (!options.code) { if (!options.code) {
if (options.channelId) { if (options.channelId) {
const id = this.guild.channels.resolveId(options.channelId); const id = this.guild.channels.resolveId(options.channelId);
if (!id) throw new DiscordjsError(ErrorCodes.GuildChannelResolve); if (!id) {
throw new DiscordjsError(ErrorCodes.GuildChannelResolve);
}
return this._fetchChannelMany(id, options.cache); return this._fetchChannelMany(id, options.cache);
} }
if ('cache' in options) return this._fetchMany(options.cache); if ('cache' in options) {
return this._fetchMany(options.cache);
}
throw new DiscordjsError(ErrorCodes.InviteResolveCode); throw new DiscordjsError(ErrorCodes.InviteResolveCode);
} }
@@ -169,12 +181,17 @@ class GuildInviteManager extends CachedManager {
async _fetchSingle({ code, cache, force = false }) { async _fetchSingle({ code, cache, force = false }) {
if (!force) { if (!force) {
const existing = this.cache.get(code); const existing = this.cache.get(code);
if (existing) return existing; if (existing) {
return existing;
}
} }
const invites = await this._fetchMany(cache); const invites = await this._fetchMany(cache);
const invite = invites.get(code); const invite = invites.get(code);
if (!invite) throw new DiscordjsError(ErrorCodes.InviteNotFound); if (!invite) {
throw new DiscordjsError(ErrorCodes.InviteNotFound);
}
return invite; return invite;
} }
@@ -205,7 +222,9 @@ class GuildInviteManager extends CachedManager {
{ temporary, maxAge, maxUses, unique, targetUser, targetApplication, targetType, reason } = {}, { temporary, maxAge, maxUses, unique, targetUser, targetApplication, targetType, reason } = {},
) { ) {
const id = this.guild.channels.resolveId(channel); const id = this.guild.channels.resolveId(channel);
if (!id) throw new DiscordjsError(ErrorCodes.GuildChannelResolve); if (!id) {
throw new DiscordjsError(ErrorCodes.GuildChannelResolve);
}
const invite = await this.client.rest.post(Routes.channelInvites(id), { const invite = await this.client.rest.post(Routes.channelInvites(id), {
body: { body: {

View File

@@ -131,7 +131,9 @@ class GuildManager extends CachedManager {
if (id) { if (id) {
if (!options.force) { if (!options.force) {
const existing = this.cache.get(id); const existing = this.cache.get(id);
if (existing) return existing; if (existing) {
return existing;
}
} }
const innerData = await this.client.rest.get(Routes.guild(id), { const innerData = await this.client.rest.get(Routes.guild(id), {
@@ -187,7 +189,9 @@ class GuildManager extends CachedManager {
// eslint-disable-next-line no-use-before-define // eslint-disable-next-line no-use-before-define
timeout.refresh(); timeout.refresh();
if (!remainingGuildIds.has(guild.id)) return; if (!remainingGuildIds.has(guild.id)) {
return;
}
fetchedSoundboardSounds.set(guild.id, soundboardSounds); fetchedSoundboardSounds.set(guild.id, soundboardSounds);

View File

@@ -51,9 +51,15 @@ class GuildMemberManager extends CachedManager {
*/ */
resolve(member) { resolve(member) {
const memberResolvable = super.resolve(member); const memberResolvable = super.resolve(member);
if (memberResolvable) return memberResolvable; if (memberResolvable) {
return memberResolvable;
}
const userResolvable = this.client.users.resolveId(member); const userResolvable = this.client.users.resolveId(member);
if (userResolvable) return super.cache.get(userResolvable) ?? null; if (userResolvable) {
return super.cache.get(userResolvable) ?? null;
}
return null; return null;
} }
@@ -65,7 +71,10 @@ class GuildMemberManager extends CachedManager {
*/ */
resolveId(member) { resolveId(member) {
const memberResolvable = super.resolveId(member); const memberResolvable = super.resolveId(member);
if (memberResolvable) return memberResolvable; if (memberResolvable) {
return memberResolvable;
}
const userResolvable = this.client.users.resolveId(member); const userResolvable = this.client.users.resolveId(member);
return this.cache.has(userResolvable) ? userResolvable : null; return this.cache.has(userResolvable) ? userResolvable : null;
} }
@@ -98,10 +107,15 @@ class GuildMemberManager extends CachedManager {
*/ */
async add(user, options) { async add(user, options) {
const userId = this.client.users.resolveId(user); const userId = this.client.users.resolveId(user);
if (!userId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable'); if (!userId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable');
}
if (!options.force) { if (!options.force) {
const cachedUser = this.cache.get(userId); const cachedUser = this.cache.get(userId);
if (cachedUser) return cachedUser; if (cachedUser) {
return cachedUser;
}
} }
const resolvedOptions = { const resolvedOptions = {
@@ -215,10 +229,16 @@ class GuildMemberManager extends CachedManager {
* .catch(console.error); * .catch(console.error);
*/ */
async fetch(options) { async fetch(options) {
if (!options) return this._fetchMany(); if (!options) {
return this._fetchMany();
}
const { user: users, limit, withPresences, cache, force } = options; const { user: users, limit, withPresences, cache, force } = options;
const resolvedUser = this.client.users.resolveId(users ?? options); const resolvedUser = this.client.users.resolveId(users ?? options);
if (resolvedUser && !limit && !withPresences) return this._fetchSingle({ user: resolvedUser, cache, force }); if (resolvedUser && !limit && !withPresences) {
return this._fetchSingle({ user: resolvedUser, cache, force });
}
const resolvedUsers = users?.map?.(user => this.client.users.resolveId(user)) ?? resolvedUser ?? undefined; const resolvedUsers = users?.map?.(user => this.client.users.resolveId(user)) ?? resolvedUser ?? undefined;
return this._fetchMany({ ...options, users: resolvedUsers }); return this._fetchMany({ ...options, users: resolvedUsers });
} }
@@ -226,7 +246,9 @@ class GuildMemberManager extends CachedManager {
async _fetchSingle({ user, cache, force = false }) { async _fetchSingle({ user, cache, force = false }) {
if (!force) { if (!force) {
const existing = this.cache.get(user); const existing = this.cache.get(user);
if (existing && !existing.partial) return existing; if (existing && !existing.partial) {
return existing;
}
} }
const data = await this.client.rest.get(Routes.guildMember(this.guild.id, user)); const data = await this.client.rest.get(Routes.guildMember(this.guild.id, user));
@@ -241,7 +263,9 @@ class GuildMemberManager extends CachedManager {
time = 120e3, time = 120e3,
nonce = DiscordSnowflake.generate().toString(), nonce = DiscordSnowflake.generate().toString(),
} = {}) { } = {}) {
if (nonce.length > 32) throw new DiscordjsRangeError(ErrorCodes.MemberFetchNonceLength); if (nonce.length > 32) {
throw new DiscordjsRangeError(ErrorCodes.MemberFetchNonceLength);
}
const query = initialQuery ?? (users ? undefined : ''); const query = initialQuery ?? (users ? undefined : '');
@@ -261,7 +285,9 @@ class GuildMemberManager extends CachedManager {
const fetchedMembers = new Collection(); const fetchedMembers = new Collection();
let index = 0; let index = 0;
const handler = (members, _, chunk) => { const handler = (members, _, chunk) => {
if (chunk.nonce !== nonce) return; if (chunk.nonce !== nonce) {
return;
}
// eslint-disable-next-line no-use-before-define // eslint-disable-next-line no-use-before-define
timeout.refresh(); timeout.refresh();
@@ -367,7 +393,9 @@ class GuildMemberManager extends CachedManager {
*/ */
async edit(user, { reason, ...options }) { async edit(user, { reason, ...options }) {
const id = this.client.users.resolveId(user); const id = this.client.users.resolveId(user);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable'); if (!id) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable');
}
if (options.channel) { if (options.channel) {
options.channel = this.guild.channels.resolve(options.channel); options.channel = this.guild.channels.resolve(options.channel);
@@ -469,7 +497,9 @@ class GuildMemberManager extends CachedManager {
* .catch(console.error); * .catch(console.error);
*/ */
async prune({ days, dry = false, count: compute_prune_count, roles = [], reason } = {}) { async prune({ days, dry = false, count: compute_prune_count, roles = [], reason } = {}) {
if (typeof days !== 'number') throw new DiscordjsTypeError(ErrorCodes.PruneDaysType); if (typeof days !== 'number') {
throw new DiscordjsTypeError(ErrorCodes.PruneDaysType);
}
const query = { days }; const query = { days };
const resolvedRoles = []; const resolvedRoles = [];
@@ -509,7 +539,9 @@ class GuildMemberManager extends CachedManager {
*/ */
async kick(user, reason) { async kick(user, reason) {
const id = this.client.users.resolveId(user); const id = this.client.users.resolveId(user);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable'); if (!id) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable');
}
await this.client.rest.delete(Routes.guildMember(this.guild.id, id), { reason }); await this.client.rest.delete(Routes.guildMember(this.guild.id, id), { reason });
} }

View File

@@ -49,7 +49,10 @@ class GuildMemberRoleManager extends DataManager {
*/ */
get hoist() { get hoist() {
const hoistedRoles = this.cache.filter(role => role.hoist); const hoistedRoles = this.cache.filter(role => role.hoist);
if (!hoistedRoles.size) return null; if (!hoistedRoles.size) {
return null;
}
return hoistedRoles.reduce((prev, role) => (role.comparePositionTo(prev) > 0 ? role : prev)); return hoistedRoles.reduce((prev, role) => (role.comparePositionTo(prev) > 0 ? role : prev));
} }
@@ -61,7 +64,10 @@ class GuildMemberRoleManager extends DataManager {
*/ */
get icon() { get icon() {
const iconRoles = this.cache.filter(role => role.icon ?? role.unicodeEmoji); const iconRoles = this.cache.filter(role => role.icon ?? role.unicodeEmoji);
if (!iconRoles.size) return null; if (!iconRoles.size) {
return null;
}
return iconRoles.reduce((prev, role) => (role.comparePositionTo(prev) > 0 ? role : prev)); return iconRoles.reduce((prev, role) => (role.comparePositionTo(prev) > 0 ? role : prev));
} }
@@ -73,7 +79,10 @@ class GuildMemberRoleManager extends DataManager {
*/ */
get color() { get color() {
const coloredRoles = this.cache.filter(role => role.colors.primaryColor); const coloredRoles = this.cache.filter(role => role.colors.primaryColor);
if (!coloredRoles.size) return null; if (!coloredRoles.size) {
return null;
}
return coloredRoles.reduce((prev, role) => (role.comparePositionTo(prev) > 0 ? role : prev)); return coloredRoles.reduce((prev, role) => (role.comparePositionTo(prev) > 0 ? role : prev));
} }
@@ -105,7 +114,10 @@ class GuildMemberRoleManager extends DataManager {
* @readonly * @readonly
*/ */
get botRole() { get botRole() {
if (!this.member.user.bot) return null; if (!this.member.user.bot) {
return null;
}
return this.cache.find(role => role.tags?.botId === this.member.user.id) ?? null; return this.cache.find(role => role.tags?.botId === this.member.user.id) ?? null;
} }

View File

@@ -25,7 +25,9 @@ class GuildMessageManager extends MessageManager {
*/ */
async crosspost(message) { async crosspost(message) {
const messageId = this.resolveId(message); const messageId = this.resolveId(message);
if (!messageId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable'); if (!messageId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
}
const data = await this.client.rest.post(Routes.channelMessageCrosspost(this.channel.id, messageId)); const data = await this.client.rest.post(Routes.channelMessageCrosspost(this.channel.id, messageId));
return this.cache.get(data.id) ?? this._add(data); return this.cache.get(data.id) ?? this._add(data);

View File

@@ -92,7 +92,10 @@ class GuildScheduledEventManager extends CachedManager {
* @returns {Promise<GuildScheduledEvent>} * @returns {Promise<GuildScheduledEvent>}
*/ */
async create(options) { async create(options) {
if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true); if (typeof options !== 'object') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
}
const { const {
privacyLevel, privacyLevel,
entityType, entityType,
@@ -114,7 +117,10 @@ class GuildScheduledEventManager extends CachedManager {
entity_metadata = { location: entityMetadata?.location }; entity_metadata = { location: entityMetadata?.location };
} else { } else {
channel_id = this.guild.channels.resolveId(channel); channel_id = this.guild.channels.resolveId(channel);
if (!channel_id) throw new DiscordjsError(ErrorCodes.GuildVoiceChannelResolve); if (!channel_id) {
throw new DiscordjsError(ErrorCodes.GuildVoiceChannelResolve);
}
entity_metadata = entityMetadata === undefined ? entityMetadata : null; entity_metadata = entityMetadata === undefined ? entityMetadata : null;
} }
@@ -167,7 +173,9 @@ class GuildScheduledEventManager extends CachedManager {
if (id) { if (id) {
if (!options.force) { if (!options.force) {
const existing = this.cache.get(id); const existing = this.cache.get(id);
if (existing) return existing; if (existing) {
return existing;
}
} }
const innerData = await this.client.rest.get(Routes.guildScheduledEvent(this.guild.id, id), { const innerData = await this.client.rest.get(Routes.guildScheduledEvent(this.guild.id, id), {
@@ -218,9 +226,14 @@ class GuildScheduledEventManager extends CachedManager {
*/ */
async edit(guildScheduledEvent, options) { async edit(guildScheduledEvent, options) {
const guildScheduledEventId = this.resolveId(guildScheduledEvent); const guildScheduledEventId = this.resolveId(guildScheduledEvent);
if (!guildScheduledEventId) throw new DiscordjsError(ErrorCodes.GuildScheduledEventResolve); if (!guildScheduledEventId) {
throw new DiscordjsError(ErrorCodes.GuildScheduledEventResolve);
}
if (typeof options !== 'object') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
}
if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
const { const {
privacyLevel, privacyLevel,
entityType, entityType,
@@ -271,7 +284,9 @@ class GuildScheduledEventManager extends CachedManager {
*/ */
async delete(guildScheduledEvent) { async delete(guildScheduledEvent) {
const guildScheduledEventId = this.resolveId(guildScheduledEvent); const guildScheduledEventId = this.resolveId(guildScheduledEvent);
if (!guildScheduledEventId) throw new DiscordjsError(ErrorCodes.GuildScheduledEventResolve); if (!guildScheduledEventId) {
throw new DiscordjsError(ErrorCodes.GuildScheduledEventResolve);
}
await this.client.rest.delete(Routes.guildScheduledEvent(this.guild.id, guildScheduledEventId)); await this.client.rest.delete(Routes.guildScheduledEvent(this.guild.id, guildScheduledEventId));
} }
@@ -305,7 +320,9 @@ class GuildScheduledEventManager extends CachedManager {
*/ */
async fetchSubscribers(guildScheduledEvent, options = {}) { async fetchSubscribers(guildScheduledEvent, options = {}) {
const guildScheduledEventId = this.resolveId(guildScheduledEvent); const guildScheduledEventId = this.resolveId(guildScheduledEvent);
if (!guildScheduledEventId) throw new DiscordjsError(ErrorCodes.GuildScheduledEventResolve); if (!guildScheduledEventId) {
throw new DiscordjsError(ErrorCodes.GuildScheduledEventResolve);
}
const query = makeURLSearchParams({ const query = makeURLSearchParams({
limit: options.limit, limit: options.limit,

View File

@@ -63,8 +63,14 @@ class GuildSoundboardSoundManager extends CachedManager {
* @returns {?Snowflake} * @returns {?Snowflake}
*/ */
resolveId(soundboardSound) { resolveId(soundboardSound) {
if (soundboardSound instanceof this.holds) return soundboardSound.soundId; if (soundboardSound instanceof this.holds) {
if (typeof soundboardSound === 'string') return soundboardSound; return soundboardSound.soundId;
}
if (typeof soundboardSound === 'string') {
return soundboardSound;
}
return null; return null;
} }
@@ -130,7 +136,9 @@ class GuildSoundboardSoundManager extends CachedManager {
async edit(soundboardSound, options = {}) { async edit(soundboardSound, options = {}) {
const soundId = this.resolveId(soundboardSound); const soundId = this.resolveId(soundboardSound);
if (!soundId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'soundboardSound', 'SoundboardSoundResolvable'); if (!soundId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'soundboardSound', 'SoundboardSoundResolvable');
}
const { emojiId, emojiName, name, reason, volume } = options; const { emojiId, emojiName, name, reason, volume } = options;
@@ -163,7 +171,9 @@ class GuildSoundboardSoundManager extends CachedManager {
async delete(soundboardSound, reason) { async delete(soundboardSound, reason) {
const soundId = this.resolveId(soundboardSound); const soundId = this.resolveId(soundboardSound);
if (!soundId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'soundboardSound', 'SoundboardSoundResolvable'); if (!soundId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'soundboardSound', 'SoundboardSoundResolvable');
}
await this.client.rest.delete(Routes.guildSoundboardSound(this.guild.id, soundId), { reason }); await this.client.rest.delete(Routes.guildSoundboardSound(this.guild.id, soundId), { reason });
} }
@@ -199,17 +209,25 @@ class GuildSoundboardSoundManager extends CachedManager {
* .catch(console.error); * .catch(console.error);
*/ */
async fetch(options) { async fetch(options) {
if (!options) return this._fetchMany(); if (!options) {
return this._fetchMany();
}
const { cache, force, soundboardSound } = options; const { cache, force, soundboardSound } = options;
const resolvedSoundboardSound = this.resolveId(soundboardSound ?? options); const resolvedSoundboardSound = this.resolveId(soundboardSound ?? options);
if (resolvedSoundboardSound) return this._fetchSingle({ cache, force, soundboardSound: resolvedSoundboardSound }); if (resolvedSoundboardSound) {
return this._fetchSingle({ cache, force, soundboardSound: resolvedSoundboardSound });
}
return this._fetchMany({ cache }); return this._fetchMany({ cache });
} }
async _fetchSingle({ cache, force, soundboardSound } = {}) { async _fetchSingle({ cache, force, soundboardSound } = {}) {
if (!force) { if (!force) {
const existing = this.cache.get(soundboardSound); const existing = this.cache.get(soundboardSound);
if (existing) return existing; if (existing) {
return existing;
}
} }
const data = await this.client.rest.get(Routes.guildSoundboardSound(this.guild.id, soundboardSound)); const data = await this.client.rest.get(Routes.guildSoundboardSound(this.guild.id, soundboardSound));

View File

@@ -114,7 +114,9 @@ class GuildStickerManager extends CachedManager {
*/ */
async edit(sticker, options = {}) { async edit(sticker, options = {}) {
const stickerId = this.resolveId(sticker); const stickerId = this.resolveId(sticker);
if (!stickerId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sticker', 'StickerResolvable'); if (!stickerId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sticker', 'StickerResolvable');
}
const data = await this.client.rest.patch(Routes.guildSticker(this.guild.id, stickerId), { const data = await this.client.rest.patch(Routes.guildSticker(this.guild.id, stickerId), {
body: options, body: options,
@@ -140,7 +142,9 @@ class GuildStickerManager extends CachedManager {
*/ */
async delete(sticker, reason) { async delete(sticker, reason) {
const resolvedStickerId = this.resolveId(sticker); const resolvedStickerId = this.resolveId(sticker);
if (!resolvedStickerId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sticker', 'StickerResolvable'); if (!resolvedStickerId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sticker', 'StickerResolvable');
}
await this.client.rest.delete(Routes.guildSticker(this.guild.id, resolvedStickerId), { reason }); await this.client.rest.delete(Routes.guildSticker(this.guild.id, resolvedStickerId), { reason });
} }
@@ -166,7 +170,9 @@ class GuildStickerManager extends CachedManager {
if (id) { if (id) {
if (!force) { if (!force) {
const existing = this.cache.get(id); const existing = this.cache.get(id);
if (existing) return existing; if (existing) {
return existing;
}
} }
const sticker = await this.client.rest.get(Routes.guildSticker(this.guild.id, id)); const sticker = await this.client.rest.get(Routes.guildSticker(this.guild.id, id));
@@ -185,7 +191,10 @@ class GuildStickerManager extends CachedManager {
*/ */
async fetchUser(sticker) { async fetchUser(sticker) {
const resolvedSticker = this.resolve(sticker); const resolvedSticker = this.resolve(sticker);
if (!resolvedSticker) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sticker', 'StickerResolvable'); if (!resolvedSticker) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sticker', 'StickerResolvable');
}
const data = await this.client.rest.get(Routes.guildSticker(this.guild.id, resolvedSticker.id)); const data = await this.client.rest.get(Routes.guildSticker(this.guild.id, resolvedSticker.id));
resolvedSticker._patch(data); resolvedSticker._patch(data);
return resolvedSticker.user; return resolvedSticker.user;

View File

@@ -72,7 +72,9 @@ class GuildTextThreadManager extends ThreadManager {
let startMessageId; let startMessageId;
if (startMessage) { if (startMessage) {
startMessageId = this.channel.messages.resolveId(startMessage); startMessageId = this.channel.messages.resolveId(startMessage);
if (!startMessageId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'startMessage', 'MessageResolvable'); if (!startMessageId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'startMessage', 'MessageResolvable');
}
} else if (this.channel.type !== ChannelType.GuildAnnouncement) { } else if (this.channel.type !== ChannelType.GuildAnnouncement) {
resolvedType = type ?? resolvedType; resolvedType = type ?? resolvedType;
} }

View File

@@ -98,17 +98,25 @@ class MessageManager extends CachedManager {
* .catch(console.error); * .catch(console.error);
*/ */
async fetch(options) { async fetch(options) {
if (!options) return this._fetchMany(); if (!options) {
return this._fetchMany();
}
const { message, cache, force } = options; const { message, cache, force } = options;
const resolvedMessage = this.resolveId(message ?? options); const resolvedMessage = this.resolveId(message ?? options);
if (resolvedMessage) return this._fetchSingle({ message: resolvedMessage, cache, force }); if (resolvedMessage) {
return this._fetchSingle({ message: resolvedMessage, cache, force });
}
return this._fetchMany(options); return this._fetchMany(options);
} }
async _fetchSingle({ message, cache, force = false }) { async _fetchSingle({ message, cache, force = false }) {
if (!force) { if (!force) {
const existing = this.cache.get(message); const existing = this.cache.get(message);
if (existing && !existing.partial) return existing; if (existing && !existing.partial) {
return existing;
}
} }
const data = await this.client.rest.get(Routes.channelMessage(this.channel.id, message)); const data = await this.client.rest.get(Routes.channelMessage(this.channel.id, message));
@@ -228,7 +236,9 @@ class MessageManager extends CachedManager {
*/ */
async edit(message, options) { async edit(message, options) {
const messageId = this.resolveId(message); const messageId = this.resolveId(message);
if (!messageId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable'); if (!messageId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
}
const { body, files } = await ( const { body, files } = await (
options instanceof MessagePayload options instanceof MessagePayload
@@ -258,7 +268,9 @@ class MessageManager extends CachedManager {
*/ */
async pin(message, reason) { async pin(message, reason) {
const messageId = this.resolveId(message); const messageId = this.resolveId(message);
if (!messageId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable'); if (!messageId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
}
await this.client.rest.put(Routes.channelMessagesPin(this.channel.id, messageId), { reason }); await this.client.rest.put(Routes.channelMessagesPin(this.channel.id, messageId), { reason });
} }
@@ -272,7 +284,9 @@ class MessageManager extends CachedManager {
*/ */
async unpin(message, reason) { async unpin(message, reason) {
const messageId = this.resolveId(message); const messageId = this.resolveId(message);
if (!messageId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable'); if (!messageId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
}
await this.client.rest.delete(Routes.channelMessagesPin(this.channel.id, messageId), { reason }); await this.client.rest.delete(Routes.channelMessagesPin(this.channel.id, messageId), { reason });
} }
@@ -286,10 +300,14 @@ class MessageManager extends CachedManager {
*/ */
async react(message, emoji) { async react(message, emoji) {
const messageId = this.resolveId(message); const messageId = this.resolveId(message);
if (!messageId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable'); if (!messageId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
}
const resolvedEmoji = resolvePartialEmoji(emoji); const resolvedEmoji = resolvePartialEmoji(emoji);
if (!resolvedEmoji) throw new DiscordjsTypeError(ErrorCodes.EmojiType, 'emoji', 'EmojiIdentifierResolvable'); if (!resolvedEmoji) {
throw new DiscordjsTypeError(ErrorCodes.EmojiType, 'emoji', 'EmojiIdentifierResolvable');
}
const emojiId = resolvedEmoji.id const emojiId = resolvedEmoji.id
? `${resolvedEmoji.animated ? 'a:' : ''}${resolvedEmoji.name}:${resolvedEmoji.id}` ? `${resolvedEmoji.animated ? 'a:' : ''}${resolvedEmoji.name}:${resolvedEmoji.id}`
@@ -306,7 +324,9 @@ class MessageManager extends CachedManager {
*/ */
async delete(message) { async delete(message) {
const messageId = this.resolveId(message); const messageId = this.resolveId(message);
if (!messageId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable'); if (!messageId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
}
await this.client.rest.delete(Routes.channelMessage(this.channel.id, messageId)); await this.client.rest.delete(Routes.channelMessage(this.channel.id, messageId));
} }

View File

@@ -104,7 +104,10 @@ class PermissionOverwriteManager extends CachedManager {
let resolvedType = type; let resolvedType = type;
if (typeof resolvedType !== 'number') { if (typeof resolvedType !== 'number') {
const resolvedUserOrRole = this.channel.guild.roles.resolve(userOrRole) ?? this.client.users.resolve(userOrRole); const resolvedUserOrRole = this.channel.guild.roles.resolve(userOrRole) ?? this.client.users.resolve(userOrRole);
if (!resolvedUserOrRole) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'parameter', 'User nor a Role'); if (!resolvedUserOrRole) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'parameter', 'User nor a Role');
}
resolvedType = resolvedUserOrRole instanceof Role ? OverwriteType.Role : OverwriteType.Member; resolvedType = resolvedUserOrRole instanceof Role ? OverwriteType.Role : OverwriteType.Member;
} }
@@ -167,7 +170,9 @@ class PermissionOverwriteManager extends CachedManager {
*/ */
async delete(userOrRole, reason) { async delete(userOrRole, reason) {
const userOrRoleId = this.channel.guild.roles.resolveId(userOrRole) ?? this.client.users.resolveId(userOrRole); const userOrRoleId = this.channel.guild.roles.resolveId(userOrRole) ?? this.client.users.resolveId(userOrRole);
if (!userOrRoleId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'parameter', 'User nor a Role'); if (!userOrRoleId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'parameter', 'User nor a Role');
}
await this.client.rest.delete(Routes.channelPermission(this.channel.id, userOrRoleId), { reason }); await this.client.rest.delete(Routes.channelPermission(this.channel.id, userOrRoleId), { reason });
return this.channel; return this.channel;

View File

@@ -41,7 +41,10 @@ class PresenceManager extends CachedManager {
*/ */
resolve(presence) { resolve(presence) {
const presenceResolvable = super.resolve(presence); const presenceResolvable = super.resolve(presence);
if (presenceResolvable) return presenceResolvable; if (presenceResolvable) {
return presenceResolvable;
}
const userId = this.client.users.resolveId(presence); const userId = this.client.users.resolveId(presence);
return super.cache.get(userId) ?? null; return super.cache.get(userId) ?? null;
} }
@@ -54,7 +57,10 @@ class PresenceManager extends CachedManager {
*/ */
resolveId(presence) { resolveId(presence) {
const presenceResolvable = super.resolveId(presence); const presenceResolvable = super.resolveId(presence);
if (presenceResolvable) return presenceResolvable; if (presenceResolvable) {
return presenceResolvable;
}
const userId = this.client.users.resolveId(presence); const userId = this.client.users.resolveId(presence);
return this.cache.has(userId) ? userId : null; return this.cache.has(userId) ? userId : null;
} }

View File

@@ -71,7 +71,10 @@ class ReactionUserManager extends CachedManager {
*/ */
async remove(user = this.client.user) { async remove(user = this.client.user) {
const userId = this.client.users.resolveId(user); const userId = this.client.users.resolveId(user);
if (!userId) throw new DiscordjsError(ErrorCodes.ReactionResolveUser); if (!userId) {
throw new DiscordjsError(ErrorCodes.ReactionResolveUser);
}
const message = this.reaction.message; const message = this.reaction.message;
const route = const route =
userId === this.client.user.id userId === this.client.user.id

View File

@@ -68,13 +68,18 @@ class RoleManager extends CachedManager {
if (!id) { if (!id) {
const innerData = await this.client.rest.get(Routes.guildRoles(this.guild.id)); const innerData = await this.client.rest.get(Routes.guildRoles(this.guild.id));
const roles = new Collection(); const roles = new Collection();
for (const role of innerData) roles.set(role.id, this._add(role, cache)); for (const role of innerData) {
roles.set(role.id, this._add(role, cache));
}
return roles; return roles;
} }
if (!force) { if (!force) {
const existing = this.cache.get(id); const existing = this.cache.get(id);
if (existing) return existing; if (existing) {
return existing;
}
} }
const data = await this.client.rest.get(Routes.guildRole(this.guild.id, id)); const data = await this.client.rest.get(Routes.guildRole(this.guild.id, id));
@@ -175,11 +180,16 @@ class RoleManager extends CachedManager {
async create(options = {}) { async create(options = {}) {
let { permissions, icon } = options; let { permissions, icon } = options;
const { name, hoist, position, mentionable, reason, unicodeEmoji } = options; const { name, hoist, position, mentionable, reason, unicodeEmoji } = options;
if (permissions !== undefined) permissions = new PermissionsBitField(permissions); if (permissions !== undefined) {
permissions = new PermissionsBitField(permissions);
}
if (icon) { if (icon) {
const guildEmojiURL = this.guild.emojis.resolve(icon)?.imageURL(); const guildEmojiURL = this.guild.emojis.resolve(icon)?.imageURL();
icon = guildEmojiURL ? await resolveImage(guildEmojiURL) : await resolveImage(icon); icon = guildEmojiURL ? await resolveImage(guildEmojiURL) : await resolveImage(icon);
if (typeof icon !== 'string') icon = undefined; if (typeof icon !== 'string') {
icon = undefined;
}
} }
const colors = options.colors && { const colors = options.colors && {
@@ -204,7 +214,10 @@ class RoleManager extends CachedManager {
guild_id: this.guild.id, guild_id: this.guild.id,
role: data, role: data,
}); });
if (position) return this.setPosition(role, position, { reason }); if (position) {
return this.setPosition(role, position, { reason });
}
return role; return role;
} }
@@ -229,7 +242,9 @@ class RoleManager extends CachedManager {
*/ */
async edit(role, options) { async edit(role, options) {
const resolvedRole = this.resolve(role); const resolvedRole = this.resolve(role);
if (!resolvedRole) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'role', 'RoleResolvable'); if (!resolvedRole) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'role', 'RoleResolvable');
}
if (typeof options.position === 'number') { if (typeof options.position === 'number') {
await this.setPosition(resolvedRole, options.position, { reason: options.reason }); await this.setPosition(resolvedRole, options.position, { reason: options.reason });
@@ -239,7 +254,9 @@ class RoleManager extends CachedManager {
if (icon) { if (icon) {
const guildEmojiURL = this.guild.emojis.resolve(icon)?.imageURL(); const guildEmojiURL = this.guild.emojis.resolve(icon)?.imageURL();
icon = guildEmojiURL ? await resolveImage(guildEmojiURL) : await resolveImage(icon); icon = guildEmojiURL ? await resolveImage(guildEmojiURL) : await resolveImage(icon);
if (typeof icon !== 'string') icon = undefined; if (typeof icon !== 'string') {
icon = undefined;
}
} }
const colors = options.colors && { const colors = options.colors && {
@@ -301,7 +318,10 @@ class RoleManager extends CachedManager {
*/ */
async setPosition(role, position, { relative, reason } = {}) { async setPosition(role, position, { relative, reason } = {}) {
const resolvedRole = this.resolve(role); const resolvedRole = this.resolve(role);
if (!resolvedRole) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'role', 'RoleResolvable'); if (!resolvedRole) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'role', 'RoleResolvable');
}
const updatedRoles = await setPosition( const updatedRoles = await setPosition(
resolvedRole, resolvedRole,
position, position,
@@ -386,7 +406,10 @@ class RoleManager extends CachedManager {
*/ */
botRoleFor(user) { botRoleFor(user) {
const userId = this.client.users.resolveId(user); const userId = this.client.users.resolveId(user);
if (!userId) return null; if (!userId) {
return null;
}
return this.cache.find(role => role.tags?.botId === userId) ?? null; return this.cache.find(role => role.tags?.botId === userId) ?? null;
} }

View File

@@ -65,8 +65,14 @@ class StageInstanceManager extends CachedManager {
*/ */
async create(channel, options) { async create(channel, options) {
const channelId = this.guild.channels.resolveId(channel); const channelId = this.guild.channels.resolveId(channel);
if (!channelId) throw new DiscordjsError(ErrorCodes.StageChannelResolve); if (!channelId) {
if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true); throw new DiscordjsError(ErrorCodes.StageChannelResolve);
}
if (typeof options !== 'object') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
}
const { guildScheduledEvent, topic, privacyLevel, sendStartNotification } = options; const { guildScheduledEvent, topic, privacyLevel, sendStartNotification } = options;
const guildScheduledEventId = guildScheduledEvent && this.resolveId(guildScheduledEvent); const guildScheduledEventId = guildScheduledEvent && this.resolveId(guildScheduledEvent);
@@ -98,11 +104,15 @@ class StageInstanceManager extends CachedManager {
*/ */
async fetch(channel, { cache = true, force = false } = {}) { async fetch(channel, { cache = true, force = false } = {}) {
const channelId = this.guild.channels.resolveId(channel); const channelId = this.guild.channels.resolveId(channel);
if (!channelId) throw new DiscordjsError(ErrorCodes.StageChannelResolve); if (!channelId) {
throw new DiscordjsError(ErrorCodes.StageChannelResolve);
}
if (!force) { if (!force) {
const existing = this.cache.find(stageInstance => stageInstance.channelId === channelId); const existing = this.cache.find(stageInstance => stageInstance.channelId === channelId);
if (existing) return existing; if (existing) {
return existing;
}
} }
const data = await this.client.rest.get(Routes.stageInstance(channelId)); const data = await this.client.rest.get(Routes.stageInstance(channelId));
@@ -130,9 +140,14 @@ class StageInstanceManager extends CachedManager {
* .catch(console.error); * .catch(console.error);
*/ */
async edit(channel, options) { async edit(channel, options) {
if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true); if (typeof options !== 'object') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
}
const channelId = this.guild.channels.resolveId(channel); const channelId = this.guild.channels.resolveId(channel);
if (!channelId) throw new DiscordjsError(ErrorCodes.StageChannelResolve); if (!channelId) {
throw new DiscordjsError(ErrorCodes.StageChannelResolve);
}
const { topic, privacyLevel } = options; const { topic, privacyLevel } = options;
@@ -160,7 +175,9 @@ class StageInstanceManager extends CachedManager {
*/ */
async delete(channel) { async delete(channel) {
const channelId = this.guild.channels.resolveId(channel); const channelId = this.guild.channels.resolveId(channel);
if (!channelId) throw new DiscordjsError(ErrorCodes.StageChannelResolve); if (!channelId) {
throw new DiscordjsError(ErrorCodes.StageChannelResolve);
}
await this.client.rest.delete(Routes.stageInstance(channelId)); await this.client.rest.delete(Routes.stageInstance(channelId));
} }

View File

@@ -52,13 +52,17 @@ class SubscriptionManager extends CachedManager {
* @returns {Promise<Subscription|Collection<Snowflake, Subscription>>} * @returns {Promise<Subscription|Collection<Snowflake, Subscription>>}
*/ */
async fetch(options = {}) { async fetch(options = {}) {
if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true); if (typeof options !== 'object') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
}
const { after, before, cache, limit, sku, subscriptionId, user } = options; const { after, before, cache, limit, sku, subscriptionId, user } = options;
const skuId = resolveSKUId(sku); const skuId = resolveSKUId(sku);
if (!skuId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sku', 'SKUResolvable'); if (!skuId) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sku', 'SKUResolvable');
}
if (subscriptionId) { if (subscriptionId) {
const subscription = await this.client.rest.get(Routes.skuSubscription(skuId, subscriptionId)); const subscription = await this.client.rest.get(Routes.skuSubscription(skuId, subscriptionId));

View File

@@ -44,7 +44,10 @@ class ThreadManager extends CachedManager {
_add(thread) { _add(thread) {
const existing = this.cache.get(thread.id); const existing = this.cache.get(thread.id);
if (existing) return existing; if (existing) {
return existing;
}
this.cache.set(thread.id, thread); this.cache.set(thread.id, thread);
return thread; return thread;
} }
@@ -92,11 +95,17 @@ class ThreadManager extends CachedManager {
* .catch(console.error); * .catch(console.error);
*/ */
async fetch(options, { cache, force } = {}) { async fetch(options, { cache, force } = {}) {
if (!options) return this.fetchActive(cache); if (!options) {
return this.fetchActive(cache);
}
const channel = this.client.channels.resolveId(options); const channel = this.client.channels.resolveId(options);
if (channel) { if (channel) {
const threadChannel = await this.client.channels.fetch(channel, { cache, force }); const threadChannel = await this.client.channels.fetch(channel, { cache, force });
if (threadChannel.parentId !== this.channel.id) throw new DiscordjsTypeError(ErrorCodes.NotAThreadOfParent); if (threadChannel.parentId !== this.channel.id) {
throw new DiscordjsTypeError(ErrorCodes.NotAThreadOfParent);
}
return threadChannel; return threadChannel;
} }
@@ -192,7 +201,10 @@ class ThreadManager extends CachedManager {
static _mapThreads(rawThreads, client, { parent, guild, cache }) { static _mapThreads(rawThreads, client, { parent, guild, cache }) {
const threads = rawThreads.threads.reduce((coll, raw) => { const threads = rawThreads.threads.reduce((coll, raw) => {
const thread = client.channels._add(raw, guild ?? parent?.guild, { cache }); const thread = client.channels._add(raw, guild ?? parent?.guild, { cache });
if (parent && thread.parentId !== parent.id) return coll; if (parent && thread.parentId !== parent.id) {
return coll;
}
return coll.set(thread.id, thread); return coll.set(thread.id, thread);
}, new Collection()); }, new Collection());
@@ -205,7 +217,10 @@ class ThreadManager extends CachedManager {
const response = { threads, members: threadMembers }; const response = { threads, members: threadMembers };
// The GET `/guilds/{guild.id}/threads/active` route does not return `has_more`. // The GET `/guilds/{guild.id}/threads/active` route does not return `has_more`.
if ('has_more' in rawThreads) response.hasMore = rawThreads.has_more; if ('has_more' in rawThreads) {
response.hasMore = rawThreads.has_more;
}
return response; return response;
} }
} }

View File

@@ -33,11 +33,19 @@ class ThreadMemberManager extends CachedManager {
_add(data, cache = true) { _add(data, cache = true) {
const existing = this.cache.get(data.user_id); const existing = this.cache.get(data.user_id);
if (cache) existing?._patch(data, { cache }); if (cache) {
if (existing) return existing; existing?._patch(data, { cache });
}
if (existing) {
return existing;
}
const member = new ThreadMember(this.thread, data, { cache }); const member = new ThreadMember(this.thread, data, { cache });
if (cache) this.cache.set(data.user_id, member); if (cache) {
this.cache.set(data.user_id, member);
}
return member; return member;
} }
@@ -77,9 +85,15 @@ class ThreadMemberManager extends CachedManager {
*/ */
resolve(member) { resolve(member) {
const memberResolvable = super.resolve(member); const memberResolvable = super.resolve(member);
if (memberResolvable) return memberResolvable; if (memberResolvable) {
return memberResolvable;
}
const userId = this.client.users.resolveId(member); const userId = this.client.users.resolveId(member);
if (userId) return super.cache.get(userId) ?? null; if (userId) {
return super.cache.get(userId) ?? null;
}
return null; return null;
} }
@@ -91,7 +105,10 @@ class ThreadMemberManager extends CachedManager {
*/ */
resolveId(member) { resolveId(member) {
const memberResolvable = super.resolveId(member); const memberResolvable = super.resolveId(member);
if (memberResolvable) return memberResolvable; if (memberResolvable) {
return memberResolvable;
}
const userResolvable = this.client.users.resolveId(member); const userResolvable = this.client.users.resolveId(member);
return this.cache.has(userResolvable) ? userResolvable : null; return this.cache.has(userResolvable) ? userResolvable : null;
} }
@@ -104,7 +121,10 @@ class ThreadMemberManager extends CachedManager {
*/ */
async add(member) { async add(member) {
const id = member === '@me' ? member : this.client.users.resolveId(member); const id = member === '@me' ? member : this.client.users.resolveId(member);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'member', 'UserResolvable'); if (!id) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'member', 'UserResolvable');
}
await this.client.rest.put(Routes.threadMembers(this.thread.id, id)); await this.client.rest.put(Routes.threadMembers(this.thread.id, id));
return id; return id;
} }
@@ -117,7 +137,10 @@ class ThreadMemberManager extends CachedManager {
*/ */
async remove(member) { async remove(member) {
const id = member === '@me' ? member : this.client.users.resolveId(member); const id = member === '@me' ? member : this.client.users.resolveId(member);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'member', 'UserResolvable'); if (!id) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'member', 'UserResolvable');
}
await this.client.rest.delete(Routes.threadMembers(this.thread.id, id)); await this.client.rest.delete(Routes.threadMembers(this.thread.id, id));
return id; return id;
} }
@@ -165,17 +188,25 @@ class ThreadMemberManager extends CachedManager {
* @returns {Promise<ThreadMember|Collection<Snowflake, ThreadMember>>} * @returns {Promise<ThreadMember|Collection<Snowflake, ThreadMember>>}
*/ */
async fetch(options) { async fetch(options) {
if (!options) return this._fetchMany(); if (!options) {
return this._fetchMany();
}
const { member, withMember, cache, force } = options; const { member, withMember, cache, force } = options;
const resolvedMember = this.resolveId(member ?? options); const resolvedMember = this.resolveId(member ?? options);
if (resolvedMember) return this._fetchSingle({ member: resolvedMember, withMember, cache, force }); if (resolvedMember) {
return this._fetchSingle({ member: resolvedMember, withMember, cache, force });
}
return this._fetchMany(options); return this._fetchMany(options);
} }
async _fetchSingle({ member, withMember, cache, force = false }) { async _fetchSingle({ member, withMember, cache, force = false }) {
if (!force) { if (!force) {
const existing = this.cache.get(member); const existing = this.cache.get(member);
if (existing) return existing; if (existing) {
return existing;
}
} }
const data = await this.client.rest.get(Routes.threadMembers(this.thread.id, member), { const data = await this.client.rest.get(Routes.threadMembers(this.thread.id, member), {

View File

@@ -62,7 +62,9 @@ class UserManager extends CachedManager {
if (!force) { if (!force) {
const dmChannel = this.dmChannel(id); const dmChannel = this.dmChannel(id);
if (dmChannel && !dmChannel.partial) return dmChannel; if (dmChannel && !dmChannel.partial) {
return dmChannel;
}
} }
const data = await this.client.rest.post(Routes.userChannels(), { body: { recipient_id: id } }); const data = await this.client.rest.post(Routes.userChannels(), { body: { recipient_id: id } });
@@ -78,7 +80,10 @@ class UserManager extends CachedManager {
async deleteDM(user) { async deleteDM(user) {
const id = this.resolveId(user); const id = this.resolveId(user);
const dmChannel = this.dmChannel(id); const dmChannel = this.dmChannel(id);
if (!dmChannel) throw new DiscordjsError(ErrorCodes.UserNoDMChannel); if (!dmChannel) {
throw new DiscordjsError(ErrorCodes.UserNoDMChannel);
}
await this.client.rest.delete(Routes.channel(dmChannel.id)); await this.client.rest.delete(Routes.channel(dmChannel.id));
this.client.channels._remove(dmChannel.id); this.client.channels._remove(dmChannel.id);
return dmChannel; return dmChannel;
@@ -95,7 +100,9 @@ class UserManager extends CachedManager {
const id = this.resolveId(user); const id = this.resolveId(user);
if (!force) { if (!force) {
const existing = this.cache.get(id); const existing = this.cache.get(id);
if (existing && !existing.partial) return existing; if (existing && !existing.partial) {
return existing;
}
} }
const data = await this.client.rest.get(Routes.user(id)); const data = await this.client.rest.get(Routes.user(id));
@@ -120,8 +127,14 @@ class UserManager extends CachedManager {
* @returns {?User} * @returns {?User}
*/ */
resolve(user) { resolve(user) {
if (user instanceof GuildMember || user instanceof ThreadMember) return user.user; if (user instanceof GuildMember || user instanceof ThreadMember) {
if (user instanceof Message) return user.author; return user.user;
}
if (user instanceof Message) {
return user.author;
}
return super.resolve(user); return super.resolve(user);
} }
@@ -132,9 +145,18 @@ class UserManager extends CachedManager {
* @returns {?Snowflake} * @returns {?Snowflake}
*/ */
resolveId(user) { resolveId(user) {
if (user instanceof ThreadMember) return user.id; if (user instanceof ThreadMember) {
if (user instanceof GuildMember) return user.user.id; return user.id;
if (user instanceof Message) return user.author.id; }
if (user instanceof GuildMember) {
return user.user.id;
}
if (user instanceof Message) {
return user.author.id;
}
return super.resolveId(user); return super.resolveId(user);
} }
} }

View File

@@ -30,10 +30,15 @@ class VoiceStateManager extends CachedManager {
_add(data, cache = true) { _add(data, cache = true) {
const existing = this.cache.get(data.user_id); const existing = this.cache.get(data.user_id);
if (existing) return existing._patch(data); if (existing) {
return existing._patch(data);
}
const entry = new this.holds(this.guild, data); const entry = new this.holds(this.guild, data);
if (cache) this.cache.set(data.user_id, entry); if (cache) {
this.cache.set(data.user_id, entry);
}
return entry; return entry;
} }
@@ -53,7 +58,9 @@ class VoiceStateManager extends CachedManager {
const id = member === '@me' ? member : this.guild.members.resolveId(member); const id = member === '@me' ? member : this.guild.members.resolveId(member);
if (!force) { if (!force) {
const existing = this.cache.get(id === '@me' ? this.client.user.id : id); const existing = this.cache.get(id === '@me' ? this.client.user.id : id);
if (existing) return existing; if (existing) {
return existing;
}
} }
const data = await this.client.rest.get(Routes.guildVoiceState(this.guild.id, id)); const data = await this.client.rest.get(Routes.guildVoiceState(this.guild.id, id));

View File

@@ -139,8 +139,13 @@ class Shard extends AsyncEventEmitter {
* @returns {Promise<ChildProcess>} * @returns {Promise<ChildProcess>}
*/ */
async spawn(timeout = 30_000) { async spawn(timeout = 30_000) {
if (this.process) throw new DiscordjsError(ErrorCodes.ShardingProcessExists, this.id); if (this.process) {
if (this.worker) throw new DiscordjsError(ErrorCodes.ShardingWorkerExists, this.id); throw new DiscordjsError(ErrorCodes.ShardingProcessExists, this.id);
}
if (this.worker) {
throw new DiscordjsError(ErrorCodes.ShardingWorkerExists, this.id);
}
this._exitListener = this._handleExit.bind(this, undefined, timeout); this._exitListener = this._handleExit.bind(this, undefined, timeout);
@@ -182,7 +187,10 @@ class Shard extends AsyncEventEmitter {
*/ */
this.emit(ShardEvents.Spawn, child); this.emit(ShardEvents.Spawn, child);
if (timeout === -1 || timeout === Infinity) return child; if (timeout === -1 || timeout === Infinity) {
return child;
}
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const cleanup = () => { const cleanup = () => {
clearTimeout(spawnTimeoutTimer); clearTimeout(spawnTimeoutTimer);
@@ -251,7 +259,10 @@ class Shard extends AsyncEventEmitter {
*/ */
async respawn({ delay = 500, timeout = 30_000 } = {}) { async respawn({ delay = 500, timeout = 30_000 } = {}) {
this.kill(); this.kill();
if (delay > 0) await sleep(delay); if (delay > 0) {
await sleep(delay);
}
return this.spawn(timeout); return this.spawn(timeout);
} }
@@ -265,8 +276,11 @@ class Shard extends AsyncEventEmitter {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (this.process) { if (this.process) {
this.process.send(message, err => { this.process.send(message, err => {
if (err) reject(err); if (err) {
else resolve(this); reject(err);
} else {
resolve(this);
}
}); });
} else { } else {
this.worker.postMessage(message); this.worker.postMessage(message);
@@ -292,18 +306,26 @@ class Shard extends AsyncEventEmitter {
} }
// Cached promise from previous call // Cached promise from previous call
if (this._fetches.has(prop)) return this._fetches.get(prop); if (this._fetches.has(prop)) {
return this._fetches.get(prop);
}
const promise = new Promise((resolve, reject) => { const promise = new Promise((resolve, reject) => {
const child = this.process ?? this.worker; const child = this.process ?? this.worker;
const listener = message => { const listener = message => {
if (message?._fetchProp !== prop) return; if (message?._fetchProp !== prop) {
return;
}
child.removeListener('message', listener); child.removeListener('message', listener);
this.decrementMaxListeners(child); this.decrementMaxListeners(child);
this._fetches.delete(prop); this._fetches.delete(prop);
if (message._error) reject(makeError(message._error)); if (message._error) {
else resolve(message._result); reject(makeError(message._error));
} else {
resolve(message._result);
}
}; };
this.incrementMaxListeners(child); this.incrementMaxListeners(child);
@@ -338,18 +360,26 @@ class Shard extends AsyncEventEmitter {
} }
// Cached promise from previous call // Cached promise from previous call
if (this._evals.has(_eval)) return this._evals.get(_eval); if (this._evals.has(_eval)) {
return this._evals.get(_eval);
}
const promise = new Promise((resolve, reject) => { const promise = new Promise((resolve, reject) => {
const child = this.process ?? this.worker; const child = this.process ?? this.worker;
const listener = message => { const listener = message => {
if (message?._eval !== _eval) return; if (message?._eval !== _eval) {
return;
}
child.removeListener('message', listener); child.removeListener('message', listener);
this.decrementMaxListeners(child); this.decrementMaxListeners(child);
this._evals.delete(_eval); this._evals.delete(_eval);
if (message._error) reject(makeError(message._error)); if (message._error) {
else resolve(message._result); reject(makeError(message._error));
} else {
resolve(message._result);
}
}; };
this.incrementMaxListeners(child); this.incrementMaxListeners(child);
@@ -473,7 +503,9 @@ class Shard extends AsyncEventEmitter {
this._evals.clear(); this._evals.clear();
this._fetches.clear(); this._fetches.clear();
if (respawn) this.spawn(timeout).catch(error => this.emit(ShardEvents.Error, error)); if (respawn) {
this.spawn(timeout).catch(error => this.emit(ShardEvents.Error, error));
}
} }
/** /**

Some files were not shown because too many files have changed in this diff Show More