Compare commits

..

1 Commits

Author SHA1 Message Date
iCrawl
444d7c98dd chore(ws): release @discordjs/ws@0.1.0 2022-07-27 14:15:35 +02:00
206 changed files with 4565 additions and 6103 deletions

11
.github/.kodiak.toml vendored
View File

@@ -1,11 +0,0 @@
version = 1
[merge]
require_automerge_label = false
blocking_labels = ['blocked']
method = 'squash'
[merge.message]
title = 'pull_request_title'
strip_html_comments = true
include_coauthors = true

13
.github/check_deploy_branch.sh vendored Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/bash
git diff HEAD^ HEAD --quiet .
if [[ "$VERCEL_GIT_COMMIT_REF" == "main" || $? -eq 1 ]]; then
# Proceed with the build
echo "✅ - Proceed"
exit 1;
else
# Don't build
echo "🛑 - Build cancelled"
exit 0;
fi

4
.github/labeler.yml vendored
View File

@@ -1,3 +1,7 @@
chore:
- any: ['*']
all: ['!packages/*', '!packages/**/*']
'packages:builders':
- packages/builders/*
- packages/builders/**/*

View File

@@ -3,6 +3,8 @@ on:
push:
branches:
- 'main'
- 'stable'
- '!docs'
tags:
- '**'
workflow_dispatch:
@@ -10,28 +12,15 @@ on:
ref:
description: 'The branch, tag or SHA to checkout'
required: true
ref_type:
type: choice
description: 'Branch or tag'
options:
- branch
- tag
required: true
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
build:
name: Build documentation
runs-on: ubuntu-latest
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
if: github.repository_owner == 'discordjs'
outputs:
BRANCH_NAME: ${{ steps.env.outputs.BRANCH_NAME }}
BRANCH_OR_TAG: ${{ steps.env.outputs.BRANCH_OR_TAG }}
SHA: ${{ steps.env.outputs.SHA }}
if: github.repository_owner == 'discordjs'
steps:
- name: Checkout repository
uses: actions/checkout@v3
@@ -43,6 +32,7 @@ jobs:
with:
node-version: 16
cache: 'yarn'
cache-dependency-path: yarn.lock
- name: Install dependencies
run: yarn --immutable
@@ -82,10 +72,8 @@ jobs:
package: ['builders', 'collection', 'discord.js', 'proxy', 'rest', 'voice', 'ws']
runs-on: ubuntu-latest
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
BRANCH_NAME: ${{ github.event.inputs.ref || needs.build.outputs.BRANCH_NAME }}
BRANCH_OR_TAG: ${{ github.event.inputs.ref_type || needs.build.outputs.BRANCH_OR_TAG }}
BRANCH_OR_TAG: ${{ needs.build.outputs.BRANCH_OR_TAG }}
SHA: ${{ needs.build.outputs.SHA }}
steps:
- name: Checkout repository
@@ -96,12 +84,13 @@ jobs:
with:
node-version: 16
cache: 'yarn'
cache-dependency-path: yarn.lock
- name: Install dependencies
run: yarn --immutable
- name: Build actions
run: yarn workspace @discordjs/actions build
run: yarn build
- name: Download docgen artifacts
uses: actions/download-artifact@v3
@@ -123,14 +112,14 @@ jobs:
path: 'out'
- name: Extract package and semver from tag
if: ${{ github.event.inputs.ref_type == 'tag' || env.BRANCH_OR_TAG == 'tag' }}
if: ${{ github.event.inputs.ref || env.BRANCH_OR_TAG == 'tag' }}
id: extract-tag
uses: ./packages/actions/src/formatTag
with:
tag: ${{ env.BRANCH_NAME }}
- name: Move docs to correct directory
if: ${{ (github.event.inputs.ref_type == 'tag' || env.BRANCH_OR_TAG == 'tag') && matrix.package == steps.extract-tag.outputs.package }}
if: ${{ (github.event.inputs.ref || env.BRANCH_OR_TAG == 'tag') && matrix.package == steps.extract-tag.outputs.package }}
env:
PACKAGE: ${{ steps.extract-tag.outputs.package }}
SEMVER: ${{ steps.extract-tag.outputs.semver }}
@@ -142,7 +131,7 @@ jobs:
fi
- name: Move docs to correct directory
if: ${{ github.event.inputs.ref_type == 'branch' || env.BRANCH_OR_TAG == 'branch' }}
if: ${{ !github.event.inputs.ref && env.BRANCH_OR_TAG == 'branch' }}
env:
PACKAGE: ${{ matrix.package }}
run: |

View File

@@ -1,8 +1,8 @@
name: npm auto deprecate
on:
workflow_dispatch:
schedule:
- cron: '0 1 * * *'
workflow_dispatch:
jobs:
npm-auto-deprecate:
name: npm auto deprecate
@@ -17,6 +17,7 @@ jobs:
with:
node-version: 16
cache: 'yarn'
cache-dependency-path: yarn.lock
- name: Install dependencies
run: yarn --immutable

View File

@@ -1,8 +1,8 @@
name: Publish dev docker images
on:
workflow_dispatch:
schedule:
- cron: '0 */12 * * *'
workflow_dispatch:
jobs:
docker-publish:
name: Docker publish

View File

@@ -1,8 +1,8 @@
name: Publish dev
on:
workflow_dispatch:
schedule:
- cron: '0 */12 * * *'
workflow_dispatch:
jobs:
npm-publish:
name: npm publish
@@ -25,9 +25,6 @@ jobs:
- package: '@discordjs/ws'
folder: 'ws'
runs-on: ubuntu-latest
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
if: github.repository_owner == 'discordjs'
steps:
- name: Checkout repository
@@ -39,6 +36,7 @@ jobs:
node-version: 16
registry-url: https://registry.npmjs.org/
cache: 'yarn'
cache-dependency-path: yarn.lock
- name: Install dependencies
run: yarn --immutable

View File

@@ -1,18 +1,9 @@
name: Tests
on:
push:
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
on: [push, pull_request]
jobs:
tests:
name: Tests
runs-on: ubuntu-latest
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
NEXT_PUBLIC_LOCAL_DEV: true
steps:
- name: Checkout repository
uses: actions/checkout@v3
@@ -22,9 +13,10 @@ jobs:
with:
node-version: 16
cache: 'yarn'
cache-dependency-path: yarn.lock
- name: Install dependencies
run: yarn install --immutable
run: yarn --immutable
- name: Build dependencies
run: yarn build
@@ -36,5 +28,5 @@ jobs:
run: yarn test
- name: Upload Coverage
if: github.repository_owner == 'discordjs'
uses: ./packages/actions/src/uploadCoverage
if: github.repository_owner == 'discordjs'

View File

@@ -1,5 +1,5 @@
{
"*": "prettier --ignore-unknown --write",
"{src/**,__tests__/**}.{mjs,js,ts}": "eslint --ext mjs,js,ts --fix",
"src/**.ts": "vitest related --run"
"src/**.ts": "vitest related"
}

View File

@@ -0,0 +1,36 @@
diff --git a/dist/rollup-plugin-typescript2.cjs.js b/dist/rollup-plugin-typescript2.cjs.js
index 9ab972b041cc76f8f786d6a20f3efb53c364cad6..13e056a3c0971eb18b307d91fad096a9f3b9de79 100644
--- a/dist/rollup-plugin-typescript2.cjs.js
+++ b/dist/rollup-plugin-typescript2.cjs.js
@@ -29799,6 +29799,13 @@ const typescript = (options) => {
declarations[key] = { type: result.dts, map: result.dtsmap };
context.debug(() => `${safe.exports.blue("generated declarations")} for '${key}'`);
}
+ // if a user sets this compilerOption, they probably want another plugin (e.g. Babel, ESBuild) to transform their TS instead, while rpt2 just type-checks and/or outputs declarations
+ // note that result.code is non-existent if emitDeclarationOnly per https://github.com/ezolenko/rollup-plugin-typescript2/issues/268
+ if (parsedConfig.options.emitDeclarationOnly)
+ {
+ context.debug(() => `${blue("emitDeclarationOnly")} enabled, not transforming TS'`);
+ return undefined;
+ }
const transformResult = { code: result.code, map: { mappings: "" } };
if (result.map) {
if (pluginOptions.sourceMapCallback)
diff --git a/dist/rollup-plugin-typescript2.es.js b/dist/rollup-plugin-typescript2.es.js
index e43bf8f03bc6792b61d8352e04bb6466712426c2..420e8f0d0d109076bc72e9d60240077235a9ba11 100644
--- a/dist/rollup-plugin-typescript2.es.js
+++ b/dist/rollup-plugin-typescript2.es.js
@@ -29770,6 +29770,13 @@ const typescript = (options) => {
declarations[key] = { type: result.dts, map: result.dtsmap };
context.debug(() => `${safe.exports.blue("generated declarations")} for '${key}'`);
}
+ // if a user sets this compilerOption, they probably want another plugin (e.g. Babel, ESBuild) to transform their TS instead, while rpt2 just type-checks and/or outputs declarations
+ // note that result.code is non-existent if emitDeclarationOnly per https://github.com/ezolenko/rollup-plugin-typescript2/issues/268
+ if (parsedConfig.options.emitDeclarationOnly)
+ {
+ context.debug(() => `${blue("emitDeclarationOnly")} enabled, not transforming TS'`);
+ return undefined;
+ }
const transformResult = { code: result.code, map: { mappings: "" } };
if (result.map) {
if (pluginOptions.sourceMapCallback)

View File

@@ -46,18 +46,19 @@ pnpm add discord.js
## Example usage
Install discord.js:
Install all required dependencies:
```sh-session
npm install discord.js
yarn add discord.js
pnpm add discord.js
npm install discord.js @discordjs/rest
yarn add discord.js @discordjs/rest
pnpm add discord.js @discordjs/rest
```
Register a slash command against the Discord API:
```js
const { REST, Routes } = require('discord.js');
const { REST } = require('@discordjs/rest');
const { Routes } = require('discord.js');
const commands = [
{
@@ -72,7 +73,7 @@ const rest = new REST({ version: '10' }).setToken('token');
try {
console.log('Started refreshing application (/) commands.');
await rest.put(Routes.applicationCommands(CLIENT_ID), { body: commands });
await rest.put(Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID), { body: commands });
console.log('Successfully reloaded application (/) commands.');
} catch (error) {

View File

@@ -1,6 +1,5 @@
import { relative, resolve } from 'node:path';
import glob from 'fast-glob';
import isCi from 'is-ci';
import typescript from 'rollup-plugin-typescript2';
import { defineBuildConfig, BuildEntry } from 'unbuild';
@@ -27,7 +26,7 @@ export function createUnbuildConfig({
preserveModules = true,
preserveModulesRoot = 'src',
declaration = true,
typeCheck = isCi,
typeCheck = false,
}: Partial<ConfigOptions> = {}) {
const files = glob
.sync('**', { cwd: 'src' })
@@ -46,7 +45,6 @@ export function createUnbuildConfig({
cjsBridge,
json: {
namedExports: false,
preferConst: true,
},
},

View File

@@ -4,13 +4,13 @@
"description": "A powerful library for interacting with the Discord API",
"private": true,
"scripts": {
"build": "turbo run build",
"test": "turbo run test --parallel",
"lint": "turbo run lint --parallel",
"format": "turbo run format --parallel",
"fmt": "turbo run format --parallel",
"build": "yarn workspaces foreach --parallel --topological run build",
"test": "yarn workspaces foreach --parallel --topological run test",
"lint": "yarn workspaces foreach --parallel --topological run lint",
"format": "yarn workspaces foreach --parallel --topological run format",
"fmt": "yarn format",
"postinstall": "is-ci || husky install",
"docs": "turbo run docs --parallel",
"docs": "yarn workspaces foreach --parallel --topological run docs",
"update": "yarn upgrade-interactive"
},
"contributors": [
@@ -39,18 +39,25 @@
"devDependencies": {
"@commitlint/cli": "^17.0.3",
"@commitlint/config-angular": "^17.0.3",
"@favware/cliff-jumper": "^1.8.7",
"@favware/npm-deprecate": "^1.0.5",
"@types/is-ci": "^3.0.0",
"@favware/cliff-jumper": "^1.8.5",
"@favware/npm-deprecate": "^1.0.4",
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0",
"conventional-changelog-cli": "^2.2.2",
"eslint": "^8.20.0",
"eslint-config-marine": "^9.4.1",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-typescript": "^3.3.0",
"eslint-plugin-import": "^2.26.0",
"fast-glob": "^3.2.11",
"husky": "^8.0.1",
"is-ci": "^3.0.1",
"lint-staged": "^13.0.3",
"turbo": "^1.4.3",
"prettier": "^2.7.1",
"typescript": "^4.7.4"
},
"resolutions": {
"rollup-plugin-typescript2@0.32.1": "patch:rollup-plugin-typescript2@npm:0.32.1#.yarn/patches/rollup-plugin-typescript2-npm-0.32.1-b5887420f2.patch",
"@microsoft/tsdoc-config": "patch:@microsoft/tsdoc-config@npm:0.16.1#.yarn/patches/@microsoft-tsdoc-config-npm-0.16.1-81031b1bbf.patch"
},
"engines": {

View File

@@ -5,4 +5,5 @@ dist/
docs/**/*
!docs/index.yml
!docs/README.md
coverage/
coverage/
tsup.config.*.mjs

View File

@@ -1,11 +1,3 @@
import { createUnbuildConfig } from '../../build.config';
export default createUnbuildConfig({
entries: [
{ builder: 'rollup', input: 'src/index' },
{ builder: 'rollup', input: 'src/formatTag/index' },
],
preserveModules: false,
minify: true,
emitCJS: false,
});
export default createUnbuildConfig({ minify: true });

View File

@@ -6,12 +6,18 @@
"scripts": {
"test": "vitest run",
"build": "unbuild",
"lint": "prettier --check . && TIMING=1 eslint src __tests__ --ext mjs,js,ts",
"format": "prettier --write . && TIMING=1 eslint src __tests__ --ext mjs,js,ts --fix",
"lint": "prettier --check . && eslint src __tests__ --ext mjs,js,ts",
"format": "prettier --write . && eslint src __tests__ --ext mjs,js,ts --fix",
"fmt": "yarn format"
},
"main": "./dist/index.mjs",
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"types": "./dist/index.d.ts"
},
"directories": {
"lib": "src",
"test": "__tests__"
@@ -39,24 +45,19 @@
},
"homepage": "https://discord.js.org",
"dependencies": {
"@actions/core": "^1.9.1",
"@actions/core": "^1.9.0",
"tslib": "^2.4.0"
},
"devDependencies": {
"@types/node": "^16.11.52",
"@typescript-eslint/eslint-plugin": "^5.33.1",
"@typescript-eslint/parser": "^5.33.1",
"@vitest/coverage-c8": "^0.22.1",
"eslint": "^8.22.0",
"eslint-config-marine": "^9.4.1",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-typescript": "^3.4.2",
"eslint-plugin-import": "^2.26.0",
"@types/node": "^16.11.45",
"c8": "^7.12.0",
"eslint": "^8.20.0",
"prettier": "^2.7.1",
"rollup-plugin-typescript2": "^0.33.0",
"rollup-plugin-typescript2": "0.32.1",
"tsup": "^6.2.0",
"typescript": "^4.7.4",
"unbuild": "^0.8.9",
"vitest": "^0.22.1"
"unbuild": "^0.7.6",
"vitest": "^0.19.1"
},
"engines": {
"node": ">=16.9.0"

View File

@@ -11,4 +11,4 @@ outputs:
description: 'The semver string that was extracted from this tag'
runs:
using: node16
main: ../../dist/index.mjs
main: ../../dist/formatTag/index.js

View File

@@ -0,0 +1,9 @@
import { createTsupConfig } from '../../tsup.config';
export default createTsupConfig({
entry: ['src/index.ts', 'src/formatTag/index.ts'],
format: ['cjs'],
skipNodeModulesBundle: false,
noExternal: ['@actions/core'],
minify: true,
});

View File

@@ -1,7 +1,3 @@
{
"extends": "../../.eslintrc.json",
"plugins": ["eslint-plugin-tsdoc"],
"rules": {
"tsdoc/syntax": "warn"
}
"extends": "../../.eslintrc.json"
}

View File

@@ -5,4 +5,5 @@ dist/
docs/**/*
!docs/index.yml
!docs/README.md
coverage/
coverage/
tsup.config.*.mjs

View File

@@ -2,22 +2,6 @@
All notable changes to this project will be documented in this file.
# [@discordjs/builders@1.1.0](https://github.com/discordjs/discord.js/compare/@discordjs/builders@1.0.0...@discordjs/builders@1.1.0) - (2022-07-29)
## Bug Fixes
- Use proper format for `@link` text (#8384) ([2655639](https://github.com/discordjs/discord.js/commit/26556390a3800e954974a00c1328ff47d3e67e9a))
- **Formatters:** Add newline in `codeBlock` (#8369) ([5d8bd03](https://github.com/discordjs/discord.js/commit/5d8bd030d60ef364de3ef5f9963da8bda5c4efd4))
- **selectMenu:** Allow json to be used for select menu options (#8322) ([6a2d0d8](https://github.com/discordjs/discord.js/commit/6a2d0d8e96d157d5b85cee7f17bffdfff4240074))
## Documentation
- Use link tags (#8382) ([5494791](https://github.com/discordjs/discord.js/commit/549479131318c659f86f0eb18578d597e22522d3))
## Features
- Add channel & message URL formatters (#8371) ([a7deb8f](https://github.com/discordjs/discord.js/commit/a7deb8f89830ead6185c5fb46a49688b6d209ed1))
# [@discordjs/builders@1.0.0](https://github.com/discordjs/discord.js/compare/@discordjs/builders@0.16.0...@discordjs/builders@1.0.0) - (2022-07-17)
## Info

View File

@@ -3,7 +3,6 @@ import { describe, test, expect, vitest } from 'vitest';
import {
blockQuote,
bold,
channelLink,
channelMention,
codeBlock,
Faces,
@@ -12,7 +11,6 @@ import {
hyperlink,
inlineCode,
italic,
messageLink,
quote,
roleMention,
spoiler,
@@ -152,34 +150,6 @@ describe('Message formatters', () => {
});
});
describe('channelLink', () => {
test('GIVEN channelId THEN returns "https://discord.com/channels/@me/${channelId}"', () => {
expect<'https://discord.com/channels/@me/123456789012345678'>(channelLink('123456789012345678')).toEqual(
'https://discord.com/channels/@me/123456789012345678',
);
});
test('GIVEN channelId WITH guildId THEN returns "https://discord.com/channels/${guildId}/${channelId}"', () => {
expect<'https://discord.com/channels/987654321987654/123456789012345678'>(
channelLink('123456789012345678', '987654321987654'),
).toEqual('https://discord.com/channels/987654321987654/123456789012345678');
});
});
describe('messageLink', () => {
test('GIVEN channelId AND messageId THEN returns "https://discord.com/channels/@me/${channelId}/${messageId}"', () => {
expect<'https://discord.com/channels/@me/123456789012345678/102938475657483'>(
messageLink('123456789012345678', '102938475657483'),
).toEqual('https://discord.com/channels/@me/123456789012345678/102938475657483');
});
test('GIVEN channelId AND messageId WITH guildId THEN returns "https://discord.com/channels/${guildId}/${channelId}/${messageId}"', () => {
expect<'https://discord.com/channels/987654321987654/123456789012345678/102938475657483'>(
messageLink('123456789012345678', '102938475657483', '987654321987654'),
).toEqual('https://discord.com/channels/987654321987654/123456789012345678/102938475657483');
});
});
describe('time', () => {
test('GIVEN no arguments THEN returns "<t:${bigint}>"', () => {
vitest.useFakeTimers();

View File

@@ -59,5 +59,5 @@ commit_parsers = [
filter_commits = true
tag_pattern = "@discordjs/builders@[0-9]*"
ignore_tags = ""
date_order = true
topo_order = false
sort_commits = "newest"

View File

@@ -1,12 +1,12 @@
{
"name": "@discordjs/builders",
"version": "1.1.0",
"version": "1.0.0",
"description": "A set of builders that you can use when creating your bot",
"scripts": {
"test": "vitest run",
"build": "unbuild",
"lint": "prettier --check . && TIMING=1 eslint src __tests__ --ext mjs,js,ts",
"format": "prettier --write . && TIMING=1 eslint src __tests__ --ext mjs,js,ts --fix",
"lint": "prettier --check . && eslint src __tests__ --ext mjs,js,ts",
"format": "prettier --write . && eslint src __tests__ --ext mjs,js,ts --fix",
"fmt": "yarn format",
"docs": "downlevel-dts . docs --to=3.7 && docgen -i src/index.ts -c docs/index.json -o docs/docs.json --typescript && api-extractor run --local",
"prepack": "yarn lint && yarn test && yarn build",
@@ -55,31 +55,25 @@
"homepage": "https://discord.js.org",
"dependencies": {
"@sapphire/shapeshift": "^3.5.1",
"discord-api-types": "^0.37.3",
"discord-api-types": "^0.36.3",
"fast-deep-equal": "^3.1.3",
"ts-mixer": "^6.0.1",
"tslib": "^2.4.0"
},
"devDependencies": {
"@discordjs/docgen": "workspace:^",
"@favware/cliff-jumper": "^1.8.7",
"@microsoft/api-extractor": "^7.29.3",
"@types/node": "^16.11.52",
"@typescript-eslint/eslint-plugin": "^5.33.1",
"@typescript-eslint/parser": "^5.33.1",
"@vitest/coverage-c8": "^0.22.1",
"@favware/cliff-jumper": "^1.8.5",
"@microsoft/api-extractor": "^7.28.6",
"@types/node": "^16.11.45",
"c8": "^7.12.0",
"downlevel-dts": "^0.10.0",
"eslint": "^8.22.0",
"eslint-config-marine": "^9.4.1",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-typescript": "^3.4.2",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-tsdoc": "^0.2.16",
"eslint": "^8.20.0",
"prettier": "^2.7.1",
"rollup-plugin-typescript2": "^0.33.0",
"rollup-plugin-typescript2": "0.32.1",
"tsup": "^6.2.0",
"typescript": "^4.7.4",
"unbuild": "^0.8.9",
"vitest": "^0.22.1"
"unbuild": "^0.7.6",
"vitest": "^0.19.1"
},
"engines": {
"node": ">=16.9.0"

View File

@@ -22,8 +22,6 @@ export type AnyComponentBuilder = MessageActionRowComponentBuilder | ModalAction
/**
* Represents an action row component
*
* @typeParam T - The types of components this action row holds
*/
export class ActionRowBuilder<T extends AnyComponentBuilder> extends ComponentBuilder<
APIActionRowComponent<APIMessageActionRowComponent | APIModalActionRowComponent>
@@ -58,9 +56,6 @@ export class ActionRowBuilder<T extends AnyComponentBuilder> extends ComponentBu
return this;
}
/**
* {@inheritDoc ComponentBuilder.toJSON}
*/
public toJSON(): APIActionRowComponent<ReturnType<T['toJSON']>> {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return {

View File

@@ -10,8 +10,6 @@ export type AnyAPIActionRowComponent = APIActionRowComponentTypes | APIActionRow
/**
* Represents a discord component
*
* @typeParam DataType - The type of internal API data that is stored within the component
*/
export abstract class ComponentBuilder<
DataType extends Partial<APIBaseComponent<ComponentType>> = APIBaseComponent<ComponentType>,
@@ -22,13 +20,6 @@ export abstract class ComponentBuilder<
*/
public readonly data: Partial<DataType>;
/**
* Serializes this component to an API-compatible JSON object
*
* @remarks
* This method runs validations on the data before serializing it.
* As such, it may throw an error if the data is invalid.
*/
public abstract toJSON(): AnyAPIActionRowComponent;
public constructor(data: Partial<DataType>) {

View File

@@ -21,35 +21,6 @@ import { ComponentBuilder } from '../Component';
* Represents a button component
*/
export class ButtonBuilder extends ComponentBuilder<APIButtonComponent> {
/**
* Creates a new button from API data
* @param data - The API data to create this button with
*
* @example
* Creating a button from an API data object
* ```ts
* const button = new ButtonBuilder({
* style: 'primary',
* label: 'Click Me',
* emoji: {
* name: ':smile:',
* id: '12345678901234567890123456789012',
* },
* custom_id: '12345678901234567890123456789012',
* });
* ```
*
* @example
* Creating a button using setters and API data
* ```ts
* const button = new ButtonBuilder({
* style: 'primary',
* label: 'Click Me',
* })
* .setEmoji({ name: ':smile:', id: '12345678901234567890123456789012' })
* .setCustomId('12345678901234567890123456789012');
* ```
*/
public constructor(data?: Partial<APIButtonComponent>) {
super({ type: ComponentType.Button, ...data });
}
@@ -67,10 +38,6 @@ export class ButtonBuilder extends ComponentBuilder<APIButtonComponent> {
/**
* Sets the URL for this button
*
* @remarks
* This method is only available to buttons using the `Link` button style.
* Only three types of URL schemes are currently supported: `https://`, `http://` and `discord://`
*
* @param url - The URL to open when this button is clicked
*/
public setURL(url: string) {
@@ -81,9 +48,6 @@ export class ButtonBuilder extends ComponentBuilder<APIButtonComponent> {
/**
* Sets the custom id for this button
*
* @remarks
* This method is only applicable to buttons that are not using the `Link` button style.
*
* @param customId - The custom id to use for this button
*/
public setCustomId(customId: string) {
@@ -121,9 +85,6 @@ export class ButtonBuilder extends ComponentBuilder<APIButtonComponent> {
return this;
}
/**
* {@inheritDoc ComponentBuilder.toJSON}
*/
public toJSON(): APIButtonComponent {
validateRequiredButtonParameters(
this.data.style,

View File

@@ -116,9 +116,6 @@ export class SelectMenuBuilder extends ComponentBuilder<APISelectMenuComponent>
return this;
}
/**
* {@inheritDoc ComponentBuilder.toJSON}
*/
public toJSON(): APISelectMenuComponent {
validateRequiredSelectMenuParameters(this.options, this.data.custom_id);
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions

View File

@@ -1,5 +1,4 @@
import type { APIMessageComponentEmoji, APISelectMenuOption } from 'discord-api-types/v10';
import type { JSONEncodable } from '../../util/jsonEncodable';
import {
defaultValidator,
@@ -11,7 +10,7 @@ import {
/**
* Represents a option within a select menu component
*/
export class SelectMenuOptionBuilder implements JSONEncodable<APISelectMenuOption> {
export class SelectMenuOptionBuilder {
public constructor(public data: Partial<APISelectMenuOption> = {}) {}
/**
@@ -64,9 +63,6 @@ export class SelectMenuOptionBuilder implements JSONEncodable<APISelectMenuOptio
return this;
}
/**
* {@inheritDoc ComponentBuilder.toJSON}
*/
public toJSON(): APISelectMenuOption {
validateRequiredSelectMenuOptionParameters(this.data.label, this.data.value);
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions

View File

@@ -10,15 +10,11 @@ import {
labelValidator,
textInputStyleValidator,
} from './Assertions';
import type { Equatable } from '../../util/equatable';
import { isJSONEncodable, type JSONEncodable } from '../../util/jsonEncodable';
import { customIdValidator } from '../Assertions';
import { ComponentBuilder } from '../Component';
export class TextInputBuilder
extends ComponentBuilder<APITextInputComponent>
implements Equatable<JSONEncodable<APITextInputComponent> | APITextInputComponent>
{
export class TextInputBuilder extends ComponentBuilder<APITextInputComponent> {
public constructor(data?: APITextInputComponent & { type?: ComponentType.TextInput }) {
super({ type: ComponentType.TextInput, ...data });
}
@@ -103,9 +99,6 @@ export class TextInputBuilder
return this;
}
/**
* {@inheritDoc ComponentBuilder.toJSON}
*/
public toJSON(): APITextInputComponent {
validateRequiredParameters(this.data.custom_id, this.data.style, this.data.label);
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
@@ -114,9 +107,6 @@ export class TextInputBuilder
} as APITextInputComponent;
}
/**
* {@inheritDoc Equatable.equals}
*/
public equals(other: JSONEncodable<APITextInputComponent> | APITextInputComponent): boolean {
if (isJSONEncodable(other)) {
return isEqual(other.toJSON(), this.data);

View File

@@ -35,7 +35,7 @@ export class ContextMenuCommandBuilder {
* Whether the command is enabled by default when the app is added to a guild
*
* @deprecated This property is deprecated and will be removed in the future.
* You should use {@link ContextMenuCommandBuilder.setDefaultMemberPermissions} or {@link ContextMenuCommandBuilder.setDMPermission} instead.
* You should use `setDefaultMemberPermissions` or `setDMPermission` instead.
*/
public readonly default_permission: boolean | undefined = undefined;
@@ -86,7 +86,7 @@ export class ContextMenuCommandBuilder {
* @param value - Whether or not to enable this command by default
*
* @see https://discord.com/developers/docs/interactions/application-commands#permissions
* @deprecated Use {@link ContextMenuCommandBuilder.setDefaultMemberPermissions} or {@link ContextMenuCommandBuilder.setDMPermission} instead.
* @deprecated Use `setDefaultMemberPermissions` or `setDMPermission` instead.
*/
public setDefaultPermission(value: boolean) {
// Assert the value matches the conditions

View File

@@ -70,9 +70,6 @@ export class ModalBuilder implements JSONEncodable<APIModalInteractionResponseCa
return this;
}
/**
* {@inheritDoc ComponentBuilder.toJSON}
*/
public toJSON(): APIModalInteractionResponseCallbackData {
validateRequiredParameters(this.data.custom_id, this.data.title, this.components);
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions

View File

@@ -49,7 +49,7 @@ export class SlashCommandBuilder {
* Whether the command is enabled by default when the app is added to a guild
*
* @deprecated This property is deprecated and will be removed in the future.
* You should use {@link (SlashCommandBuilder:class).setDefaultMemberPermissions} or {@link (SlashCommandBuilder:class).setDMPermission} instead.
* You should use `setDefaultMemberPermissions` or `setDMPermission` instead.
*/
public readonly default_permission: boolean | undefined = undefined;
@@ -89,7 +89,7 @@ export class SlashCommandBuilder {
* @param value - Whether or not to enable this command by default
*
* @see https://discord.com/developers/docs/interactions/application-commands#permissions
* @deprecated Use {@link (SlashCommandBuilder:class).setDefaultMemberPermissions} or {@link (SlashCommandBuilder:class).setDMPermission} instead.
* @deprecated Use `setDefaultMemberPermissions` or `setDMPermission` instead.
*/
public setDefaultPermission(value: boolean) {
// Assert the value matches the conditions

View File

@@ -14,9 +14,6 @@ export class SlashCommandIntegerOption
{
public readonly type = ApplicationCommandOptionType.Integer as const;
/**
* {@inheritDoc ApplicationCommandNumericOptionMinMaxValueMixin.setMaxValue}
*/
public setMaxValue(max: number): this {
numberValidator.parse(max);
@@ -25,9 +22,6 @@ export class SlashCommandIntegerOption
return this;
}
/**
* {@inheritDoc ApplicationCommandNumericOptionMinMaxValueMixin.setMinValue}
*/
public setMinValue(min: number): this {
numberValidator.parse(min);

View File

@@ -14,9 +14,6 @@ export class SlashCommandNumberOption
{
public readonly type = ApplicationCommandOptionType.Number as const;
/**
* {@inheritDoc ApplicationCommandNumericOptionMinMaxValueMixin.setMaxValue}
*/
public setMaxValue(max: number): this {
numberValidator.parse(max);
@@ -25,9 +22,6 @@ export class SlashCommandNumberOption
return this;
}
/**
* {@inheritDoc ApplicationCommandNumericOptionMinMaxValueMixin.setMinValue}
*/
public setMinValue(min: number): this {
numberValidator.parse(min);

View File

@@ -52,31 +52,9 @@ export class EmbedBuilder {
}
/**
* Appends fields to the embed
* Adds fields to the embed (max 25)
*
* @remarks
* This method accepts either an array of fields or a variable number of field parameters.
* The maximum amount of fields that can be added is 25.
*
* @example
* Using an array
* ```ts
* const fields: APIEmbedField[] = ...;
* const embed = new EmbedBuilder()
* .addFields(fields);
* ```
*
* @example
* Using rest parameters (variadic)
* ```ts
* const embed = new EmbedBuilder()
* .addFields(
* { name: 'Field 1', value: 'Value 1' },
* { name: 'Field 2', value: 'Value 2' },
* );
* ```
*
* @param fields - The fields to add
* @param fields The fields to add
*/
public addFields(...fields: RestOrArray<APIEmbedField>): this {
fields = normalizeArray(fields);
@@ -92,37 +70,11 @@ export class EmbedBuilder {
}
/**
* Removes, replaces, or inserts fields in the embed.
* Removes, replaces, or inserts fields in the embed (max 25)
*
* @remarks
* This method behaves similarly
* to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice | Array.prototype.splice}.
* The maximum amount of fields that can be added is 25.
*
* It's useful for modifying and adjusting order of the already-existing fields of an embed.
*
* @example
* Remove the first field
* ```ts
* embed.spliceFields(0, 1);
* ```
*
* @example
* Remove the first n fields
* ```ts
* const n = 4
* embed.spliceFields(0, n);
* ```
*
* @example
* Remove the last field
* ```ts
* embed.spliceFields(-1, 1);
* ```
*
* @param index - The index to start at
* @param deleteCount - The number of fields to remove
* @param fields - The replacing field objects
* @param index The index to start at
* @param deleteCount The number of fields to remove
* @param fields The replacing field objects
*/
public spliceFields(index: number, deleteCount: number, ...fields: APIEmbedField[]): this {
// Ensure adding these fields won't exceed the 25 field limit
@@ -136,15 +88,8 @@ export class EmbedBuilder {
}
/**
* Sets the embed's fields
*
* @remarks
* This method is an alias for {@link EmbedBuilder.spliceFields}. More specifically,
* it splices the entire array of fields, replacing them with the provided fields.
*
* You can set a maximum of 25 fields.
*
* @param fields - The fields to set
* Sets the embed's fields (max 25).
* @param fields The fields to set
*/
public setFields(...fields: RestOrArray<APIEmbedField>) {
this.spliceFields(0, this.data.fields?.length ?? 0, ...normalizeArray(fields));
@@ -154,7 +99,7 @@ export class EmbedBuilder {
/**
* Sets the author of this embed
*
* @param options - The options for the author
* @param options The options for the author
*/
public setAuthor(options: EmbedAuthorOptions | null): this {
@@ -173,7 +118,7 @@ export class EmbedBuilder {
/**
* Sets the color of this embed
*
* @param color - The color of the embed
* @param color The color of the embed
*/
public setColor(color: number | RGBTuple | null): this {
// Data assertions
@@ -191,7 +136,7 @@ export class EmbedBuilder {
/**
* Sets the description of this embed
*
* @param description - The description
* @param description The description
*/
public setDescription(description: string | null): this {
// Data assertions
@@ -204,7 +149,7 @@ export class EmbedBuilder {
/**
* Sets the footer of this embed
*
* @param options - The options for the footer
* @param options The options for the footer
*/
public setFooter(options: EmbedFooterOptions | null): this {
if (options === null) {
@@ -222,7 +167,7 @@ export class EmbedBuilder {
/**
* Sets the image of this embed
*
* @param url - The URL of the image
* @param url The URL of the image
*/
public setImage(url: string | null): this {
// Data assertions
@@ -235,7 +180,7 @@ export class EmbedBuilder {
/**
* Sets the thumbnail of this embed
*
* @param url - The URL of the thumbnail
* @param url The URL of the thumbnail
*/
public setThumbnail(url: string | null): this {
// Data assertions
@@ -248,7 +193,7 @@ export class EmbedBuilder {
/**
* Sets the timestamp of this embed
*
* @param timestamp - The timestamp or date
* @param timestamp The timestamp or date
*/
public setTimestamp(timestamp: number | Date | null = Date.now()): this {
// Data assertions
@@ -261,7 +206,7 @@ export class EmbedBuilder {
/**
* Sets the title of this embed
*
* @param title - The title
* @param title The title
*/
public setTitle(title: string | null): this {
// Data assertions
@@ -274,7 +219,7 @@ export class EmbedBuilder {
/**
* Sets the URL of this embed
*
* @param url - The URL
* @param url The URL
*/
public setURL(url: string | null): this {
// Data assertions

View File

@@ -207,63 +207,6 @@ export function formatEmoji<C extends Snowflake>(emojiId: C, animated = false):
return `<${animated ? 'a' : ''}:_:${emojiId}>`;
}
/**
* Formats a channel link for a direct message channel.
*
* @param channelId - The channel's id
*/
export function channelLink<C extends Snowflake>(channelId: C): `https://discord.com/channels/@me/${C}`;
/**
* Formats a channel link for a guild channel.
*
* @param channelId - The channel's id
* @param guildId - The guild's id
*/
export function channelLink<C extends Snowflake, G extends Snowflake>(
channelId: C,
guildId: G,
): `https://discord.com/channels/${G}/${C}`;
export function channelLink<C extends Snowflake, G extends Snowflake>(
channelId: C,
guildId?: G,
): `https://discord.com/channels/@me/${C}` | `https://discord.com/channels/${G}/${C}` {
return `https://discord.com/channels/${guildId ?? '@me'}/${channelId}`;
}
/**
* Formats a message link for a direct message channel.
*
* @param channelId - The channel's id
* @param messageId - The message's id
*/
export function messageLink<C extends Snowflake, M extends Snowflake>(
channelId: C,
messageId: M,
): `https://discord.com/channels/@me/${C}/${M}`;
/**
* Formats a message link for a guild channel.
*
* @param channelId - The channel's id
* @param messageId - The message's id
* @param guildId - The guild's id
*/
export function messageLink<C extends Snowflake, M extends Snowflake, G extends Snowflake>(
channelId: C,
messageId: M,
guildId: G,
): `https://discord.com/channels/${G}/${C}/${M}`;
export function messageLink<C extends Snowflake, M extends Snowflake, G extends Snowflake>(
channelId: C,
messageId: M,
guildId?: G,
): `https://discord.com/channels/@me/${C}/${M}` | `https://discord.com/channels/${G}/${C}/${M}` {
return `${typeof guildId === 'undefined' ? channelLink(channelId) : channelLink(channelId, guildId)}/${messageId}`;
}
/**
* Formats a date into a short date-time string
*
@@ -302,7 +245,7 @@ export function time(timeOrSeconds?: number | Date, style?: TimestampStylesStrin
}
/**
* The {@link https://discord.com/developers/docs/reference#message-formatting-timestamp-styles | message formatting timestamp styles} supported by Discord
* The [message formatting timestamp styles](https://discord.com/developers/docs/reference#message-formatting-timestamp-styles) supported by Discord
*/
export const TimestampStyles = {
/**

View File

@@ -1,9 +1,3 @@
/**
* Represents a structure that can be checked against another
* given structure for equality
*
* @typeParam T - The type of object to compare the current object to
*/
export interface Equatable<T> {
/**
* Whether or not this is equal to another structure

View File

@@ -1,8 +1,3 @@
/**
* Represents an object capable of representing itself as a JSON object
*
* @typeParam T - The JSON type corresponding to {@link JSONEncodable.toJSON} outputs.
*/
export interface JSONEncodable<T> {
/**
* Transforms this object to its JSON format

View File

@@ -0,0 +1,3 @@
import { createTsupConfig } from '../../tsup.config';
export default createTsupConfig();

View File

@@ -1,7 +1,3 @@
{
"extends": "../../.eslintrc.json",
"plugins": ["eslint-plugin-tsdoc"],
"rules": {
"tsdoc/syntax": "warn"
}
"extends": "../../.eslintrc.json"
}

View File

@@ -5,4 +5,5 @@ dist/
docs/**/*
!docs/index.yml
!docs/README.md
coverage/
coverage/
tsup.config.*.mjs

View File

@@ -33,6 +33,43 @@ All notable changes to this project will be documented in this file.
- **collection:** Improve coverage (#8222) ([a51f721](https://github.com/discordjs/discord.js/commit/a51f7215eca67a0f46fba8b2d706f7ec6f6dc228))
# [@discordjs/collection@1.0.0](https://github.com/discordjs/discord.js/compare/@discordjs/collection@0.8.0...@discordjs/collection@1.0.0) - (2022-07-17)
## Info
- 1.0.0 release bump, no new features.
# [@discordjs/collection@0.8.0](https://github.com/discordjs/discord.js/compare/@discordjs/collection@0.7.0...@discordjs/collection@0.8.0) - (2022-07-17)
## Bug Fixes
- **Collection:** Make error messages consistent (#8224) ([5bd6b28](https://github.com/discordjs/discord.js/commit/5bd6b28b3ebfced1cb9d23e83bd7c0def7a12404))
- Check for function type (#8064) ([3bb9c0e](https://github.com/discordjs/discord.js/commit/3bb9c0e5c37311044ff41761b572ac4f91cda57c))
## Documentation
- Add codecov coverage badge to readmes (#8226) ([f6db285](https://github.com/discordjs/discord.js/commit/f6db285c073898a749fe4591cbd4463d1896daf5))
## Features
- Codecov (#8219) ([f10f4cd](https://github.com/discordjs/discord.js/commit/f10f4cdcd88ca6be7ec735ed3a415ba13da83db0))
- **docgen:** Update typedoc ([b3346f4](https://github.com/discordjs/discord.js/commit/b3346f4b9b3d4f96443506643d4631dc1c6d7b21))
- Website (#8043) ([127931d](https://github.com/discordjs/discord.js/commit/127931d1df7a2a5c27923c2f2151dbf3824e50cc))
- **docgen:** Typescript support ([3279b40](https://github.com/discordjs/discord.js/commit/3279b40912e6aa61507bedb7db15a2b8668de44b))
- Docgen package (#8029) ([8b979c0](https://github.com/discordjs/discord.js/commit/8b979c0245c42fd824d8e98745ee869f5360fc86))
- Use vitest instead of jest for more speed ([8d8e6c0](https://github.com/discordjs/discord.js/commit/8d8e6c03decd7352a2aa180f6e5bc1a13602539b))
- Add scripts package for locally used scripts ([f2ae1f9](https://github.com/discordjs/discord.js/commit/f2ae1f9348bfd893332a9060f71a8a5f272a1b8b))
## Refactor
- **collection:** Remove `default` property (#8055) ([c8f1690](https://github.com/discordjs/discord.js/commit/c8f1690896f55f06e05a83704262783cfc2bb91d))
- **collection:** Remove default export (#8053) ([16810f3](https://github.com/discordjs/discord.js/commit/16810f3e410bf35ed7e6e7412d517ea74c792c5d))
- Move all the config files to root (#8033) ([769ea0b](https://github.com/discordjs/discord.js/commit/769ea0bfe78c4f1d413c6b397c604ffe91e39c6a))
## Testing
- **collection:** Improve coverage (#8222) ([a51f721](https://github.com/discordjs/discord.js/commit/a51f7215eca67a0f46fba8b2d706f7ec6f6dc228))
# [@discordjs/collection@0.7.0](https://github.com/discordjs/discord.js/compare/@discordjs/collection@0.6.0...@discordjs/collection@0.7.0) - (2022-06-04)
## Styling

View File

@@ -59,5 +59,5 @@ commit_parsers = [
filter_commits = true
tag_pattern = "@discordjs/collection@[0-9]*"
ignore_tags = ""
date_order = true
topo_order = false
sort_commits = "newest"

View File

@@ -5,8 +5,8 @@
"scripts": {
"test": "vitest run",
"build": "unbuild",
"lint": "prettier --check . && TIMING=1 eslint src __tests__ --ext mjs,js,ts",
"format": "prettier --write . && TIMING=1 eslint src __tests__ --ext mjs,js,ts --fix",
"lint": "prettier --check . && eslint src __tests__ --ext mjs,js,ts",
"format": "prettier --write . && eslint src __tests__ --ext mjs,js,ts --fix",
"fmt": "yarn format",
"docs": "downlevel-dts . docs --to=3.7 && docgen -i src/index.ts -c docs/index.json -o docs/docs.json --typescript && api-extractor run --local",
"prepack": "yarn lint && yarn test && yarn build",
@@ -51,24 +51,18 @@
"homepage": "https://discord.js.org",
"devDependencies": {
"@discordjs/docgen": "workspace:^",
"@favware/cliff-jumper": "^1.8.7",
"@microsoft/api-extractor": "^7.29.3",
"@types/node": "^16.11.52",
"@typescript-eslint/eslint-plugin": "^5.33.1",
"@typescript-eslint/parser": "^5.33.1",
"@vitest/coverage-c8": "^0.22.1",
"@favware/cliff-jumper": "^1.8.5",
"@microsoft/api-extractor": "^7.28.6",
"@types/node": "^16.11.45",
"c8": "^7.12.0",
"downlevel-dts": "^0.10.0",
"eslint": "^8.22.0",
"eslint-config-marine": "^9.4.1",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-typescript": "^3.4.2",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-tsdoc": "^0.2.16",
"eslint": "^8.20.0",
"prettier": "^2.7.1",
"rollup-plugin-typescript2": "^0.33.0",
"rollup-plugin-typescript2": "0.32.1",
"tsup": "^6.2.0",
"typescript": "^4.7.4",
"unbuild": "^0.8.9",
"vitest": "^0.22.1"
"unbuild": "^0.7.6",
"vitest": "^0.19.1"
},
"engines": {
"node": ">=16.9.0"

View File

@@ -28,9 +28,6 @@ export interface Collection<K, V> extends Map<K, V> {
/**
* A Map with additional utility methods. This is used throughout discord.js rather than Arrays for anything that has
* an ID, for significantly improved performance and ease-of-use.
*
* @typeParam K - The key type this collection holds
* @typeParam V - The value type this collection holds
*/
export class Collection<K, V> extends Map<K, V> {
/**
@@ -40,9 +37,7 @@ export class Collection<K, V> extends Map<K, V> {
* @param defaultValueGenerator - A function that generates the default value
*
* @example
* ```ts
* collection.ensure(guildId, () => defaultGuildConfig);
* ```
*/
public ensure(key: K, defaultValueGenerator: (key: K, collection: this) => V): V {
if (this.has(key)) return this.get(key)!;
@@ -150,7 +145,7 @@ export class Collection<K, V> extends Map<K, V> {
}
/**
* Identical to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at | Array.at()}.
* Identical to [Array.at()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at).
* Returns the item at a given index, allowing for positive and negative integers.
* Negative integers count back from the last item in the collection.
*
@@ -163,7 +158,7 @@ export class Collection<K, V> extends Map<K, V> {
}
/**
* Identical to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at | Array.at()}.
* Identical to [Array.at()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at).
* Returns the key at a given index, allowing for positive and negative integers.
* Negative integers count back from the last item in the collection.
*
@@ -214,7 +209,7 @@ export class Collection<K, V> extends Map<K, V> {
}
/**
* Identical to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse | Array.reverse()}
* Identical to [Array.reverse()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse)
* but returns a Collection instead of an Array.
*/
public reverse() {
@@ -226,18 +221,16 @@ export class Collection<K, V> extends Map<K, V> {
/**
* Searches for a single item where the given function returns a truthy value. This behaves like
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find | Array.find()}.
* [Array.find()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find).
* <warn>All collections used in Discord.js are mapped using their `id` property, and if you want to find by id you
* should use the `get` method. See
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get | MDN} for details.</warn>
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get) for details.</warn>
*
* @param fn - The function to test with (should return boolean)
* @param thisArg - Value to use as `this` when executing function
*
* @example
* ```ts
* collection.find(user => user.username === 'Bob');
* ```
*/
public find<V2 extends V>(fn: (value: V, key: K, collection: this) => value is V2): V2 | undefined;
public find(fn: (value: V, key: K, collection: this) => boolean): V | undefined;
@@ -257,16 +250,14 @@ export class Collection<K, V> extends Map<K, V> {
/**
* Searches for the key of a single item where the given function returns a truthy value. This behaves like
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex | Array.findIndex()},
* [Array.findIndex()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex),
* but returns the key rather than the positional index.
*
* @param fn - The function to test with (should return boolean)
* @param thisArg - Value to use as `this` when executing function
*
* @example
* ```ts
* collection.findKey(user => user.username === 'Bob');
* ```
*/
public findKey<K2 extends K>(fn: (value: V, key: K, collection: this) => key is K2): K2 | undefined;
public findKey(fn: (value: V, key: K, collection: this) => boolean): K | undefined;
@@ -306,16 +297,14 @@ export class Collection<K, V> extends Map<K, V> {
/**
* Identical to
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter | Array.filter()},
* [Array.filter()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter),
* but returns a Collection instead of an Array.
*
* @param fn - The function to test with (should return boolean)
* @param thisArg - Value to use as `this` when executing function
*
* @example
* ```ts
* collection.filter(user => user.username === 'Bob');
* ```
*/
public filter<K2 extends K>(fn: (value: V, key: K, collection: this) => key is K2): Collection<K2, V>;
public filter<V2 extends V>(fn: (value: V, key: K, collection: this) => value is V2): Collection<K, V2>;
@@ -347,9 +336,7 @@ export class Collection<K, V> extends Map<K, V> {
* @param thisArg - Value to use as `this` when executing function
*
* @example
* ```ts
* const [big, small] = collection.partition(guild => guild.memberCount > 250);
* ```
*/
public partition<K2 extends K>(
fn: (value: V, key: K, collection: this) => key is K2,
@@ -392,15 +379,13 @@ export class Collection<K, V> extends Map<K, V> {
/**
* Maps each item into a Collection, then joins the results into a single Collection. Identical in behavior to
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap | Array.flatMap()}.
* [Array.flatMap()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap).
*
* @param fn - Function that produces a new Collection
* @param thisArg - Value to use as `this` when executing function
*
* @example
* ```ts
* collection.flatMap(guild => guild.members.cache);
* ```
*/
public flatMap<T>(fn: (value: V, key: K, collection: this) => Collection<K, T>): Collection<K, T>;
public flatMap<T, This>(
@@ -414,15 +399,13 @@ export class Collection<K, V> extends Map<K, V> {
/**
* Maps each item to another value into an array. Identical in behavior to
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map | Array.map()}.
* [Array.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map).
*
* @param fn - Function that produces an element of the new array, taking three arguments
* @param thisArg - Value to use as `this` when executing function
*
* @example
* ```ts
* collection.map(user => user.tag);
* ```
*/
public map<T>(fn: (value: V, key: K, collection: this) => T): T[];
public map<This, T>(fn: (this: This, value: V, key: K, collection: this) => T, thisArg: This): T[];
@@ -440,15 +423,13 @@ export class Collection<K, V> extends Map<K, V> {
/**
* Maps each item to another value into a collection. Identical in behavior to
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map | Array.map()}.
* [Array.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map).
*
* @param fn - Function that produces an element of the new collection, taking three arguments
* @param thisArg - Value to use as `this` when executing function
*
* @example
* ```ts
* collection.mapValues(user => user.tag);
* ```
*/
public mapValues<T>(fn: (value: V, key: K, collection: this) => T): Collection<K, T>;
public mapValues<This, T>(fn: (this: This, value: V, key: K, collection: this) => T, thisArg: This): Collection<K, T>;
@@ -462,15 +443,13 @@ export class Collection<K, V> extends Map<K, V> {
/**
* Checks if there exists an item that passes a test. Identical in behavior to
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some | Array.some()}.
* [Array.some()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some).
*
* @param fn - Function used to test (should return a boolean)
* @param thisArg - Value to use as `this` when executing function
*
* @example
* ```ts
* collection.some(user => user.discriminator === '0000');
* ```
*/
public some(fn: (value: V, key: K, collection: this) => boolean): boolean;
public some<T>(fn: (this: T, value: V, key: K, collection: this) => boolean, thisArg: T): boolean;
@@ -485,15 +464,13 @@ export class Collection<K, V> extends Map<K, V> {
/**
* Checks if all items passes a test. Identical in behavior to
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every | Array.every()}.
* [Array.every()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every).
*
* @param fn - Function used to test (should return a boolean)
* @param thisArg - Value to use as `this` when executing function
*
* @example
* ```ts
* collection.every(user => !user.bot);
* ```
*/
public every<K2 extends K>(fn: (value: V, key: K, collection: this) => key is K2): this is Collection<K2, V>;
public every<V2 extends V>(fn: (value: V, key: K, collection: this) => value is V2): this is Collection<K, V2>;
@@ -518,16 +495,14 @@ export class Collection<K, V> extends Map<K, V> {
/**
* Applies a function to produce a single value. Identical in behavior to
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce | Array.reduce()}.
* [Array.reduce()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce).
*
* @param fn - Function used to reduce, taking four arguments; `accumulator`, `currentValue`, `currentKey`,
* and `collection`
* @param initialValue - Starting value for the accumulator
*
* @example
* ```ts
* collection.reduce((acc, guild) => acc + guild.memberCount, 0);
* ```
*/
public reduce<T>(fn: (accumulator: T, value: V, key: K, collection: this) => T, initialValue?: T): T {
if (typeof fn !== 'function') throw new TypeError(`${fn} is not a function`);
@@ -558,19 +533,17 @@ export class Collection<K, V> extends Map<K, V> {
/**
* Identical to
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach | Map.forEach()},
* [Map.forEach()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach),
* but returns the collection instead of undefined.
*
* @param fn - Function to execute for each element
* @param thisArg - Value to use as `this` when executing function
*
* @example
* ```ts
* collection
* .each(user => console.log(user.username))
* .filter(user => user.bot)
* .each(user => console.log(user.username));
* ```
*/
public each(fn: (value: V, key: K, collection: this) => void): this;
public each<T>(fn: (this: T, value: V, key: K, collection: this) => void, thisArg: T): this;
@@ -587,12 +560,10 @@ export class Collection<K, V> extends Map<K, V> {
* @param thisArg - Value to use as `this` when executing function
*
* @example
* ```ts
* collection
* .tap(coll => console.log(coll.size))
* .filter(user => user.bot)
* .tap(coll => console.log(coll.size))
* ```
*/
public tap(fn: (collection: this) => void): this;
public tap<T>(fn: (this: T, collection: this) => void, thisArg: T): this;
@@ -607,9 +578,7 @@ export class Collection<K, V> extends Map<K, V> {
* Creates an identical shallow copy of this collection.
*
* @example
* ```ts
* const newColl = someColl.clone();
* ```
*/
public clone(): Collection<K, V> {
return new this.constructor[Symbol.species](this);
@@ -621,9 +590,7 @@ export class Collection<K, V> extends Map<K, V> {
* @param collections - Collections to merge
*
* @example
* ```ts
* const newColl = someColl.concat(someOtherColl, anotherColl, ohBoyAColl);
* ```
*/
public concat(...collections: ReadonlyCollection<K, V>[]) {
const newColl = this.clone();
@@ -664,9 +631,7 @@ export class Collection<K, V> extends Map<K, V> {
* If omitted, the collection is sorted according to each character's Unicode code point value, according to the string conversion of each element.
*
* @example
* ```ts
* collection.sort((userA, userB) => userA.createdTimestamp - userB.createdTimestamp);
* ```
*/
public sort(compareFunction: Comparator<K, V> = Collection.defaultSort) {
const entries = [...this.entries()];
@@ -721,7 +686,6 @@ export class Collection<K, V> extends Map<K, V> {
* @param whenInBoth - Function getting the result if the entry exists in both Collections
*
* @example
* ```ts
* // Sums up the entries in two collections.
* coll.merge(
* other,
@@ -729,10 +693,8 @@ export class Collection<K, V> extends Map<K, V> {
* y => ({ keep: true, value: y }),
* (x, y) => ({ keep: true, value: x + y }),
* );
* ```
*
* @example
* ```ts
* // Intersects two collections in a left-biased manner.
* coll.merge(
* other,
@@ -740,7 +702,6 @@ export class Collection<K, V> extends Map<K, V> {
* y => ({ keep: false }),
* (x, _) => ({ keep: true, value: x }),
* );
* ```
*/
public merge<T, R>(
other: ReadonlyCollection<K, T>,
@@ -778,9 +739,7 @@ export class Collection<K, V> extends Map<K, V> {
* according to the string conversion of each element.
*
* @example
* ```ts
* collection.sorted((userA, userB) => userA.createdTimestamp - userB.createdTimestamp);
* ```
*/
public sorted(compareFunction: Comparator<K, V> = Collection.defaultSort) {
return new this.constructor[Symbol.species](this).sort((av, bv, ak, bk) => compareFunction(av, bv, ak, bk));
@@ -802,10 +761,8 @@ export class Collection<K, V> extends Map<K, V> {
* @param combine - Function to combine an existing entry with a new one
*
* @example
* ```ts
* Collection.combineEntries([["a", 1], ["b", 2], ["a", 2]], (x, y) => x + y);
* // returns Collection { "a" => 3, "b" => 2 }
* ```
*/
public static combineEntries<K, V>(
entries: Iterable<[K, V]>,

View File

@@ -0,0 +1,3 @@
import { createTsupConfig } from '../../tsup.config';
export default createTsupConfig();

View File

@@ -5,4 +5,5 @@ dist/
docs/**/*
!docs/index.yml
!docs/README.md
coverage/
coverage/
tsup.config.*.mjs

View File

@@ -2,81 +2,6 @@
All notable changes to this project will be documented in this file.
# [14.2.0](https://github.com/discordjs/discord.js/compare/14.1.2...14.2.0) - (2022-08-10)
## Bug Fixes
- **ThreadChannel:** Handle possibly `null` parent (#8466) ([afa27b1](https://github.com/discordjs/discord.js/commit/afa27b15c5b92bc8d55b8285834d8e03f6692d06))
- Remove DM channels from `Client#messageDeleteBulk`'s types (#8460) ([6c6fe74](https://github.com/discordjs/discord.js/commit/6c6fe74dd84859c5319efa999404e8168f189710))
- **Transformers:** Do not transform `Date` objects (#8463) ([0e2a095](https://github.com/discordjs/discord.js/commit/0e2a09571c8e5ee61153b04e45334a226a1b4534))
- **ModalSubmitInteraction:** Allow deferUpdate (#8455) ([0fab869](https://github.com/discordjs/discord.js/commit/0fab869e5179dca7ddec75b5519615278e51ad82))
- **Guild:** Unable to fetch templates (#8420) ([aac8acc](https://github.com/discordjs/discord.js/commit/aac8acc22be7d7af99933ef099eca7deda43cb40))
- **MessageMentions:** Infinite loop in `parsedUsers` getter (#8430) ([b8a3136](https://github.com/discordjs/discord.js/commit/b8a31360a220e3d796f5381bd215d30a379ecb7c))
- **DataResolver:** Make `Buffer` from string (#8416) ([e72b986](https://github.com/discordjs/discord.js/commit/e72b986939e2958547c0e54d6d27472c8d111609))
## Documentation
- Change registration example to use global commands (#8454) ([64a4041](https://github.com/discordjs/discord.js/commit/64a4041a05e9514334a9f9e1f38a1ea18bb676d5))
- **Colors:** Provide enum descriptions (#8437) ([6ef4754](https://github.com/discordjs/discord.js/commit/6ef4754d40c5ec65715fc1e00e643c52fe0a6209))
- **AttachmentBuilder:** Fix #8407 (#8421) ([5b053cf](https://github.com/discordjs/discord.js/commit/5b053cf82ec2f2b717a490485af052dc956fe3c9))
## Features
- **Guild:** Add `max_video_channel_users` (#8423) ([3a96ce7](https://github.com/discordjs/discord.js/commit/3a96ce7970947f6268c21a1323d986aac8cb736d))
## Typings
- **Message:** Correct `bulkDelete` return type (#8465) ([c5b96a1](https://github.com/discordjs/discord.js/commit/c5b96a185cb8ba836b7cd10526c14059866f218f))
- Fix missing types for mentionable options (#8443) ([452e94f](https://github.com/discordjs/discord.js/commit/452e94fd3ecc12de9e3408982c5c7fd931bae634))
- **ApplicationCommandOption:** Add `ApplicationCommandBooleanOption` (#8434) ([38275fc](https://github.com/discordjs/discord.js/commit/38275fc53d633ce77ed2b142aff788dcbd4fad8c))
# [14.1.2](https://github.com/discordjs/discord.js/compare/14.1.1...14.1.2) - (2022-07-30)
## Bug Fixes
- **errors:** Error codes (#8398) ([480c85c](https://github.com/discordjs/discord.js/commit/480c85c9c3d129204b3399ed726a4e570e0b2852))
## Documentation
- **Embed:** Ensure height and width are numbers (#8396) ([fca3dad](https://github.com/discordjs/discord.js/commit/fca3dada2a565eecfc7e5275cc9317df1d261871))
# [14.1.0](https://github.com/discordjs/discord.js/compare/14.0.3...14.1.0) - (2022-07-29)
## Bug Fixes
- **MessageMentions:** `ignoreRepliedUser` option in `has()` (#8202) ([b4e2c0c](https://github.com/discordjs/discord.js/commit/b4e2c0c4d5538b945f9d597c6410a6f84b315084))
- **GuildChannelManager:** Allow unsetting rtcRegion (#8359) ([a7d49e5](https://github.com/discordjs/discord.js/commit/a7d49e56fc7c34d2e4548d9e5bf0aec45273506e))
- **ThreadChannel:** Omit webhook fetching (#8351) ([3839958](https://github.com/discordjs/discord.js/commit/3839958e3f682c715f1017da05436d2fe34900fd))
- **GuildAuditLogsEntry:** Replace OverwriteType with AuditLogOptionsType (#8345) ([58c1b51](https://github.com/discordjs/discord.js/commit/58c1b51c5ceab137ad9851919b338419eeeab69e))
- **ShardClientUtil#\_respond:** Construct global error (#8348) ([8e520f9](https://github.com/discordjs/discord.js/commit/8e520f946a5b9f93a939290facf4ccca2c05ff21))
- **Presence:** Do not return NaN for activity timestamp (#8340) ([df42fdf](https://github.com/discordjs/discord.js/commit/df42fdfc421f1190f0a2267a66efd3c921ec2348))
- **Client:** Omit private properties from toJSON (#8337) ([830c670](https://github.com/discordjs/discord.js/commit/830c670c61dcb17d8ab2a894a3203c68917d27e0))
- **ApplicationCommandManager:** Allow passing 0n to defaultMemberPermissions (#8311) ([1fb7b30](https://github.com/discordjs/discord.js/commit/1fb7b30963cfe7ea4c05b1f3b42171c879c46a1d))
## Documentation
- **InteractionResponses:** Add `showModal()` return type (#8376) ([0b61dbf](https://github.com/discordjs/discord.js/commit/0b61dbf720e844322b066e30080c3537ab3d8174))
- **WebhookClient:** Document working options (#8375) ([ba6797e](https://github.com/discordjs/discord.js/commit/ba6797e74209161b64c412de1b6f307cb28736b8))
- **Message:** Document gateway intent for content (#8364) ([2130aae](https://github.com/discordjs/discord.js/commit/2130aae3210a8eaf91c5ccae5463940d49052c7d))
- Use info blocks for requirements (#8361) ([80b9738](https://github.com/discordjs/discord.js/commit/80b9738957ebf5b6eb7c9858cec0fb1c897d0a1f))
- **WebhookClient:** Make constructor a union (#8370) ([e9920a9](https://github.com/discordjs/discord.js/commit/e9920a9c98ffb78bd7d0ae00d486476367296646))
- Update docs and examples to PascalCase links (#8305) ([34ba9d1](https://github.com/discordjs/discord.js/commit/34ba9d1c4c80eff7e6ac199a40232d07491432cc))
## Features
- Add channel & message URL formatters (#8371) ([a7deb8f](https://github.com/discordjs/discord.js/commit/a7deb8f89830ead6185c5fb46a49688b6d209ed1))
- Restore missing typeguards (#8328) ([77ed407](https://github.com/discordjs/discord.js/commit/77ed407f6aadb68e729470c5269e9b526cb1b3f0))
- **GuildMember:** Add dmChannel getter (#8281) ([4fc2c60](https://github.com/discordjs/discord.js/commit/4fc2c60a3bb43671b4b0202ae75eab42aba163ff))
## Refactor
- Deprecate `Formatter` class (#8373) ([7fd9ed8](https://github.com/discordjs/discord.js/commit/7fd9ed8f13d17ce7e98e34f7454d9047054d8467))
- **PermissionOverwriteManager:** Use `OverwriteType` (#8374) ([6d24805](https://github.com/discordjs/discord.js/commit/6d248051cfd431e9cb1c65cb98f56aa0a6556407))
## Typings
- **GuildAuditLogsEntryExtraField:** Use `AuditLogOptionsType` (#8349) ([200ab91](https://github.com/discordjs/discord.js/commit/200ab91f527d8a5706d277b89a975096f75d141a))
# [14.0.3](https://github.com/discordjs/discord.js/compare/14.0.2...14.0.3) - (2022-07-18)
## Bug Fixes
@@ -95,7 +20,7 @@ All notable changes to this project will be documented in this file.
- 14.0.1 release bump, no new features.
# [14.0.0](https://github.com/discordjs/discord.js/compare/13.10.2...14.0.0) - (2022-07-17)
# [14.0.0](https://github.com/discordjs/discord.js/compare/13.9.0...14.0.0) - (2022-07-17)
## Bug Fixes
@@ -501,43 +426,6 @@ All notable changes to this project will be documented in this file.
- AssertType -> expectType ([3f36746](https://github.com/discordjs/discord.js/commit/3f36746561a40cd61a7cd2e054b7ef80d58fc707))
- Fix cache types resolving to `never` (#7164) ([c978dbb](https://github.com/discordjs/discord.js/commit/c978dbb6233bcd85408caf0bca7619c9c5d508f0))
# [13.10.2](https://github.com/discordjs/discord.js/compare/13.10.1...13.10.2) - (2022-08-10)
## Typings
- **Message:** Correct `bulkDelete` return type (v13) (#8469) ([03c59e3](https://github.com/discordjs/discord.js/commit/03c59e3a837edcaa428549c8387ef4d29e3ef6e4))
# [13.10.1](https://github.com/discordjs/discord.js/compare/13.10.0...13.10.1) - (2022-08-10)
## Bug Fixes
- **ThreadChannel:** Handle possibly `null` parent (v13) (#8467) ([2a46d9f](https://github.com/discordjs/discord.js/commit/2a46d9f58e4714c8580218a3459992bbfec2bcf7))
# [13.10.0](https://github.com/discordjs/discord.js/compare/13.9.2...13.10.0) - (2022-08-08)
## Features
- **Guild:** Add `max_video_channel_users` (v13) (#8424) ([ae43bca](https://github.com/discordjs/discord.js/commit/ae43bca8b0afd8b90db7a1d99f67205b29338c2d))
# [13.9.2](https://github.com/discordjs/discord.js/compare/13.9.1...13.9.2) - (2022-07-29)
## Bug Fixes
- **MessageMentions:** `ignoreRepliedUser` option in `has()` (v13) (#8365) ([d0a4199](https://github.com/discordjs/discord.js/commit/d0a4199760b4c7fe64f558d8d4d2302873f78b0e))
- **GuildChannelManager:** Allow unsetting rtcRegion (v13) (#8362) ([9612507](https://github.com/discordjs/discord.js/commit/96125079a23c87fe0fb3ee01a0de5a9889fc1057))
- **ThreadChannel:** Omit webhook fetching (v13) (#8352) ([4f7c1e3](https://github.com/discordjs/discord.js/commit/4f7c1e35c38bb9f1d524406c008ffceb2cfde3db))
# [13.9.1](https://github.com/discordjs/discord.js/compare/13.9.0...13.9.1) - (2022-07-23)
## Bug Fixes
- **ApplicationCommandManager:** Allow passing 0n to defaultMemberPermissions (v13) (#8312) ([4cf0555](https://github.com/discordjs/discord.js/commit/4cf05559a2cc6c4dfc409f8aab60256e5b030bca))
## Refactor
- **embed:** Deprecate addField (#8318) ([be35db2](https://github.com/discordjs/discord.js/commit/be35db2410c24fcca8b28ddfb3c1c580e7e2a22f))
- **Presence:** Remove redundant date parsing (v13) (#8341) ([e95caa7](https://github.com/discordjs/discord.js/commit/e95caa7e4515beab627b5394d011a6b6a8ae6a18))
# [13.9.0](https://github.com/discordjs/discord.js/compare/13.8.1...13.9.0) - (2022-07-17)
## Bug Fixes

View File

@@ -45,18 +45,19 @@ pnpm add discord.js
## Example usage
Install discord.js:
Install all required dependencies:
```sh-session
npm install discord.js
yarn add discord.js
pnpm add discord.js
npm install discord.js @discordjs/rest
yarn add discord.js @discordjs/rest
pnpm add discord.js @discordjs/rest
```
Register a slash command against the Discord API:
```js
const { REST, Routes } = require('discord.js');
const { REST } = require('@discordjs/rest');
const { Routes } = require('discord.js');
const commands = [
{
@@ -71,7 +72,7 @@ const rest = new REST({ version: '10' }).setToken('token');
try {
console.log('Started refreshing application (/) commands.');
await rest.put(Routes.applicationCommands(CLIENT_ID), { body: commands });
await rest.put(Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID), { body: commands });
console.log('Successfully reloaded application (/) commands.');
} catch (error) {

View File

@@ -60,5 +60,5 @@ filter_commits = true
tag_pattern = "[0-9]*"
skip_tags = "v[0-9]*|9*|11*|12*|@discordjs*"
ignore_tags = ""
date_order = true
topo_order = false
sort_commits = "newest"

View File

@@ -1,6 +1,6 @@
{
"name": "discord.js",
"version": "14.2.0",
"version": "14.0.3",
"description": "A powerful library for interacting with the Discord API",
"scripts": {
"test": "yarn docs:test && yarn test:typescript",
@@ -54,19 +54,19 @@
"@discordjs/rest": "workspace:^",
"@sapphire/snowflake": "^3.2.2",
"@types/ws": "^8.5.3",
"discord-api-types": "^0.37.3",
"discord-api-types": "^0.36.3",
"fast-deep-equal": "^3.1.3",
"lodash.snakecase": "^4.1.1",
"tslib": "^2.4.0",
"undici": "^5.9.1",
"undici": "^5.8.0",
"ws": "^8.8.1"
},
"devDependencies": {
"@discordjs/docgen": "workspace:^",
"@favware/cliff-jumper": "^1.8.7",
"@types/node": "^16.11.52",
"@favware/cliff-jumper": "^1.8.5",
"@types/node": "^16.11.45",
"dtslint": "^4.2.1",
"eslint": "^8.22.0",
"eslint": "^8.20.0",
"jest": "^28.1.3",
"prettier": "^2.7.1",
"tsd": "^0.22.0",

View File

@@ -33,7 +33,7 @@ class MessageDeleteBulkAction extends Action {
* Emitted whenever messages are deleted in bulk.
* @event Client#messageDeleteBulk
* @param {Collection<Snowflake, Message>} messages The deleted messages, mapped by their id
* @param {GuildTextBasedChannel} channel The channel that the messages were deleted in
* @param {TextBasedChannels} channel The channel that the messages were deleted in
*/
if (messages.size > 0) client.emit(Events.MessageBulkDelete, messages, channel);
return { messages };

View File

@@ -3,6 +3,7 @@
// Heavily inspired by node's `internal/errors` module
const ErrorCodes = require('./ErrorCodes');
const Messages = require('./Messages');
const kCode = Symbol('code');
/**
* Extend an error of some sort into a DiscordjsError.
@@ -14,13 +15,17 @@ function makeDiscordjsError(Base) {
return class DiscordjsError extends Base {
constructor(code, ...args) {
super(message(code, args));
this.code = code;
this[kCode] = code;
Error.captureStackTrace?.(this, DiscordjsError);
}
get name() {
return `${super.name} [${this.code}]`;
}
get code() {
return ErrorCodes[this[kCode]];
}
};
}
@@ -32,9 +37,9 @@ function makeDiscordjsError(Base) {
* @ignore
*/
function message(code, args) {
if (!(code in ErrorCodes)) throw new Error('Error code must be a valid DiscordjsErrorCodes');
if (typeof code !== 'number') throw new Error('Error code must be a valid DiscordjsErrorCodes');
const msg = Messages[code];
if (!msg) throw new Error(`No message associated with error code: ${code}.`);
if (!msg) throw new Error(`An invalid error code was used: ${code}.`);
if (typeof msg === 'function') return msg(...args);
if (!args?.length) return msg;
args.unshift(msg);

View File

@@ -1,152 +1,159 @@
'use strict';
const { createEnum } = require('../util/Enums');
/**
* @typedef {Object} DiscordjsErrorCodes
* @property {'ClientInvalidOption'} ClientInvalidOption
* @property {'ClientInvalidProvidedShards'} ClientInvalidProvidedShards
* @property {'ClientMissingIntents'} ClientMissingIntents
* @property {'ClientNotReady'} ClientNotReady
* @property {number} ClientInvalidOption
* @property {number} ClientInvalidProvidedShards
* @property {number} ClientMissingIntents
* @property {number} ClientNotReady
* @property {'TokenInvalid'} TokenInvalid
* @property {'TokenMissing'} TokenMissing
* @property {'ApplicationCommandPermissionsTokenMissing'} ApplicationCommandPermissionsTokenMissing
* @property {number} TokenInvalid
* @property {number} TokenMissing
* @property {number} ApplicationCommandPermissionsTokenMissing
* @property {'WSCloseRequested'} WSCloseRequested
* @property {'WSConnectionExists'} WSConnectionExists
* @property {'WSNotOpen'} WSNotOpen
* @property {'ManagerDestroyed'} ManagerDestroyed
* @property {number} WSCloseRequested
* @property {number} WSConnectionExists
* @property {number} WSNotOpen
* @property {number} ManagerDestroyed
* @property {'BitFieldInvalid'} BitFieldInvalid
* @property {number} BitFieldInvalid
* @property {'ShardingInvalid'} ShardingInvalid
* @property {'ShardingRequired'} ShardingRequired
* @property {'InvalidIntents'} InvalidIntents
* @property {'DisallowedIntents'} DisallowedIntents
* @property {'ShardingNoShards'} ShardingNoShards
* @property {'ShardingInProcess'} ShardingInProcess
* @property {'ShardingInvalidEvalBroadcast'} ShardingInvalidEvalBroadcast
* @property {'ShardingShardNotFound'} ShardingShardNotFound
* @property {'ShardingAlreadySpawned'} ShardingAlreadySpawned
* @property {'ShardingProcessExists'} ShardingProcessExists
* @property {'ShardingWorkerExists'} ShardingWorkerExists
* @property {'ShardingReadyTimeout'} ShardingReadyTimeout
* @property {'ShardingReadyDisconnected'} ShardingReadyDisconnected
* @property {'ShardingReadyDied'} ShardingReadyDied
* @property {'ShardingNoChildExists'} ShardingNoChildExists
* @property {'ShardingShardMiscalculation'} ShardingShardMiscalculation
* @property {number} ShardingInvalid
* @property {number} ShardingRequired
* @property {number} InvalidIntents
* @property {number} DisallowedIntents
* @property {number} ShardingNoShards
* @property {number} ShardingInProcess
* @property {number} ShardingInvalidEvalBroadcast
* @property {number} ShardingShardNotFound
* @property {number} ShardingAlreadySpawned
* @property {number} ShardingProcessExists
* @property {number} ShardingWorkerExists
* @property {number} ShardingReadyTimeout
* @property {number} ShardingReadyDisconnected
* @property {number} ShardingReadyDied
* @property {number} ShardingNoChildExists
* @property {number} ShardingShardMiscalculation
* @property {'ColorRange'} ColorRange
* @property {'ColorConvert'} ColorConvert
* @property {number} ColorRange
* @property {number} ColorConvert
* @property {'InviteOptionsMissingChannel'} InviteOptionsMissingChannel
* @property {number} InviteOptionsMissingChannel
* @property {'ButtonLabel'} ButtonLabel
* @property {'ButtonURL'} ButtonURL
* @property {'ButtonCustomId'} ButtonCustomId
* @property {number} ButtonLabel
* @property {number} ButtonURL
* @property {number} ButtonCustomId
* @property {'SelectMenuCustomId'} SelectMenuCustomId
* @property {'SelectMenuPlaceholder'} SelectMenuPlaceholder
* @property {'SelectOptionLabel'} SelectOptionLabel
* @property {'SelectOptionValue'} SelectOptionValue
* @property {'SelectOptionDescription'} SelectOptionDescription
* @property {number} SelectMenuCustomId
* @property {number} SelectMenuPlaceholder
* @property {number} SelectOptionLabel
* @property {number} SelectOptionValue
* @property {number} SelectOptionDescription
* @property {'InteractionCollectorError'} InteractionCollectorError
* @property {number} InteractionCollectorError
* @property {'FileNotFound'} FileNotFound
* @property {number} FileNotFound
* @property {'UserBannerNotFetched'} UserBannerNotFetched
* @property {'UserNoDMChannel'} UserNoDMChannel
* @property {number} UserBannerNotFetched
* @property {number} UserNoDMChannel
* @property {'VoiceNotStageChannel'} VoiceNotStageChannel
* @property {number} VoiceNotStageChannel
* @property {'VoiceStateNotOwn'} VoiceStateNotOwn
* @property {'VoiceStateInvalidType'} VoiceStateInvalidType
* @property {number} VoiceStateNotOwn
* @property {number} VoiceStateInvalidType
* @property {'ReqResourceType'} ReqResourceType
* @property {number} ReqResourceType
* @property {'ImageFormat'} ImageFormat
* @property {'ImageSize'} ImageSize
* @property {number} ImageFormat
* @property {number} ImageSize
* @property {'MessageBulkDeleteType'} MessageBulkDeleteType
* @property {'MessageNonceType'} MessageNonceType
* @property {'MessageContentType'} MessageContentType
* @property {number} MessageBulkDeleteType
* @property {number} MessageNonceType
* @property {number} MessageContentType
* @property {'SplitMaxLen'} SplitMaxLen
* @property {number} SplitMaxLen
* @property {'BanResolveId'} BanResolveId
* @property {'FetchBanResolveId'} FetchBanResolveId
* @property {number} BanResolveId
* @property {number} FetchBanResolveId
* @property {'PruneDaysType'} PruneDaysType
* @property {number} PruneDaysType
* @property {'GuildChannelResolve'} GuildChannelResolve
* @property {'GuildVoiceChannelResolve'} GuildVoiceChannelResolve
* @property {'GuildChannelOrphan'} GuildChannelOrphan
* @property {'GuildChannelUnowned'} GuildChannelUnowned
* @property {'GuildOwned'} GuildOwned
* @property {'GuildMembersTimeout'} GuildMembersTimeout
* @property {'GuildUncachedMe'} GuildUncachedMe
* @property {'ChannelNotCached'} ChannelNotCached
* @property {'StageChannelResolve'} StageChannelResolve
* @property {'GuildScheduledEventResolve'} GuildScheduledEventResolve
* @property {'FetchOwnerId'} FetchOwnerId
* @property {number} GuildChannelResolve
* @property {number} GuildVoiceChannelResolve
* @property {number} GuildChannelOrphan
* @property {number} GuildChannelUnowned
* @property {number} GuildOwned
* @property {number} GuildMembersTimeout
* @property {number} GuildUncachedMe
* @property {number} ChannelNotCached
* @property {number} StageChannelResolve
* @property {number} GuildScheduledEventResolve
* @property {number} FetchOwnerId
* @property {'InvalidType'} InvalidType
* @property {'InvalidElement'} InvalidElement
* @property {number} InvalidType
* @property {number} InvalidElement
* @property {'MessageThreadParent'} MessageThreadParent
* @property {'MessageExistingThread'} MessageExistingThread
* @property {'ThreadInvitableType'} ThreadInvitableType
* @property {number} MessageThreadParent
* @property {number} MessageExistingThread
* @property {number} ThreadInvitableType
* @property {'WebhookMessage'} WebhookMessage
* @property {'WebhookTokenUnavailable'} WebhookTokenUnavailable
* @property {'WebhookURLInvalid'} WebhookURLInvalid
* @property {'WebhookApplication'} WebhookApplication
* @property {'MessageReferenceMissing'} MessageReferenceMissing
* @property {number} WebhookMessage
* @property {number} WebhookTokenUnavailable
* @property {number} WebhookURLInvalid
* @property {number} WebhookApplication
* @property {number} MessageReferenceMissing
* @property {'EmojiType'} EmojiType
* @property {'EmojiManaged'} EmojiManaged
* @property {'MissingManageEmojisAndStickersPermission'} MissingManageEmojisAndStickersPermission
* @property {'NotGuildSticker'} NotGuildSticker
* @property {number} EmojiType
* @property {number} EmojiManaged
* @property {number} MissingManageEmojisAndStickersPermission
* @property {number} NotGuildSticker
* @property {'ReactionResolveUser'} ReactionResolveUser
* @property {number} ReactionResolveUser
* @property {'VanityURL'} VanityURL
* @property {number} VanityURL
* @property {'InviteResolveCode'} InviteResolveCode
* @property {number} InviteResolveCode
* @property {'InviteNotFound'} InviteNotFound
* @property {number} InviteNotFound
* @property {'DeleteGroupDMChannel'} DeleteGroupDMChannel
* @property {'FetchGroupDMChannel'} FetchGroupDMChannel
* @property {number} DeleteGroupDMChannel
* @property {number} FetchGroupDMChannel
* @property {'MemberFetchNonceLength'} MemberFetchNonceLength
* @property {number} MemberFetchNonceLength
* @property {'GlobalCommandPermissions'} GlobalCommandPermissions
* @property {'GuildUncachedEntityResolve'} GuildUncachedEntityResolve
* @property {number} GlobalCommandPermissions
* @property {number} GuildUncachedEntityResolve
* @property {'InteractionAlreadyReplied'} InteractionAlreadyReplied
* @property {'InteractionNotReplied'} InteractionNotReplied
* @property {'InteractionEphemeralReplied'} InteractionEphemeralReplied
* @property {number} InteractionAlreadyReplied
* @property {number} InteractionNotReplied
* @property {number} InteractionEphemeralReplied
* @property {'CommandInteractionOptionNotFound'} CommandInteractionOptionNotFound
* @property {'CommandInteractionOptionType'} CommandInteractionOptionType
* @property {'CommandInteractionOptionEmpty'} CommandInteractionOptionEmpty
* @property {'CommandInteractionOptionNoSubcommand'} CommandInteractionOptionNoSubcommand
* @property {'CommandInteractionOptionNoSubcommandGroup'} CommandInteractionOptionNoSubcommandGroup
* @property {'AutocompleteInteractionOptionNoFocusedOption'} AutocompleteInteractionOptionNoFocusedOption
* @property {number} CommandInteractionOptionNotFound
* @property {number} CommandInteractionOptionType
* @property {number} CommandInteractionOptionEmpty
* @property {number} CommandInteractionOptionNoSubcommand
* @property {number} CommandInteractionOptionNoSubcommandGroup
* @property {number} AutocompleteInteractionOptionNoFocusedOption
* @property {'ModalSubmitInteractionFieldNotFound'} ModalSubmitInteractionFieldNotFound
* @property {'ModalSubmitInteractionFieldType'} ModalSubmitInteractionFieldType
* @property {number} ModalSubmitInteractionFieldNotFound
* @property {number} ModalSubmitInteractionFieldType
* @property {'InvalidMissingScopes'} InvalidMissingScopes
* @property {number} InvalidMissingScopes
* @property {'NotImplemented'} NotImplemented
* @property {number} NotImplemented
* @property {'SweepFilterReturn'} SweepFilterReturn
* @property {number} SweepFilterReturn
*/
const keys = [
// JSDoc for IntelliSense purposes
/**
* @type {DiscordjsErrorCodes}
* @ignore
*/
module.exports = createEnum([
'ClientInvalidOption',
'ClientInvalidProvidedShards',
'ClientMissingIntents',
@@ -288,11 +295,4 @@ const keys = [
'NotImplemented',
'SweepFilterReturn',
];
// JSDoc for IntelliSense purposes
/**
* @type {DiscordjsErrorCodes}
* @ignore
*/
module.exports = Object.fromEntries(keys.map(key => [key, key]));
]);

View File

@@ -180,6 +180,9 @@ exports.WelcomeScreen = require('./structures/WelcomeScreen');
exports.WebSocket = require('./WebSocket');
// External
exports.DiscordAPIError = require('@discordjs/rest').DiscordAPIError;
exports.HTTPError = require('@discordjs/rest').HTTPError;
exports.RateLimitError = require('@discordjs/rest').RateLimitError;
__exportStar(require('discord-api-types/v10'), exports);
__exportStar(require('@discordjs/builders'), exports);
__exportStar(require('@discordjs/rest'), exports);

View File

@@ -164,7 +164,7 @@ class GuildChannelManager extends CachedManager {
/**
* @typedef {ChannelWebhookCreateOptions} WebhookCreateOptions
* @property {TextChannel|NewsChannel|VoiceChannel|Snowflake} channel The channel to create the webhook for
* @property {GuildChannelResolvable} channel The channel to create the webhook for
*/
/**

View File

@@ -1,5 +1,6 @@
'use strict';
const { Buffer } = require('node:buffer');
const { setTimeout, clearTimeout } = require('node:timers');
const { Collection } = require('@discordjs/collection');
const { makeURLSearchParams } = require('@discordjs/rest');
@@ -127,12 +128,8 @@ class GuildMemberManager extends CachedManager {
resolvedOptions.roles = resolvedRoles;
}
const data = await this.client.rest.put(Routes.guildMember(this.guild.id, userId), { body: resolvedOptions });
// Data is an empty Uint8Array if the member is already part of the guild.
return data instanceof Uint8Array
? options.fetchWhenExisting === false
? null
: this.fetch(userId)
: this._add(data);
// Data is an empty buffer if the member is already part of the guild.
return data instanceof Buffer ? (options.fetchWhenExisting === false ? null : this.fetch(userId)) : this._add(data);
}
/**
@@ -444,42 +441,6 @@ class GuildMemberManager extends CachedManager {
return this.guild.bans.remove(user, reason);
}
/**
* Options used for adding or removing a role from a member.
* @typedef {Object} AddOrRemoveGuildMemberRoleOptions
* @property {GuildMemberResolvable} user The user to add/remove the role from
* @property {RoleResolvable} role The role to add/remove
* @property {string} [reason] Reason for adding/removing the role
*/
/**
* Adds a role to a member.
* @param {AddOrRemoveGuildMemberRoleOptions} options Options for adding the role
* @returns {Promise<GuildMember|User|Snowflake>}
*/
async addRole(options) {
const { user, role, reason } = options;
const userId = this.guild.members.resolveId(user);
const roleId = this.guild.roles.resolveId(role);
await this.client.rest.put(Routes.guildMemberRole(this.guild.id, userId, roleId), { reason });
return this.resolve(user) ?? this.client.users.resolve(user) ?? userId;
}
/**
* Removes a role from a member.
* @param {AddOrRemoveGuildMemberRoleOptions} options Options for removing the role
* @returns {Promise<GuildMember|User|Snowflake>}
*/
async removeRole(options) {
const { user, role, reason } = options;
const userId = this.guild.members.resolveId(user);
const roleId = this.guild.roles.resolveId(role);
await this.client.rest.delete(Routes.guildMemberRole(this.guild.id, userId, roleId), { reason });
return this.resolve(user) ?? this.client.users.resolve(user) ?? userId;
}
async _fetchSingle({ user, cache, force = false }) {
if (!force) {
const existing = this.cache.get(user);

View File

@@ -1,6 +1,5 @@
'use strict';
const { deprecate } = require('node:util');
const { isJSONEncodable } = require('@discordjs/builders');
const Component = require('./Component');
const { createComponent } = require('../util/Components');
@@ -25,7 +24,6 @@ class ActionRow extends Component {
* Creates a new action row builder from JSON data
* @param {JSONEncodable<APIActionRowComponent>|APIActionRowComponent} other The other data
* @returns {ActionRowBuilder}
* @deprecated Use {@link ActionRowBuilder.from()} instead.
*/
static from(other) {
if (isJSONEncodable(other)) {
@@ -43,6 +41,4 @@ class ActionRow extends Component {
}
}
ActionRow.from = deprecate(ActionRow.from, 'ActionRow.from() is deprecated. Use ActionRowBuilder.from() instead.');
module.exports = ActionRow;

View File

@@ -8,7 +8,7 @@ const { basename, flatten } = require('../util/Util');
class AttachmentBuilder {
/**
* @param {BufferResolvable|Stream} attachment The file
* @param {AttachmentData} [data] Extra data
* @param {APIAttachment} [data] Extra data
*/
constructor(attachment, data = {}) {
/**
@@ -108,9 +108,3 @@ module.exports = AttachmentBuilder;
* @external APIAttachment
* @see {@link https://discord.com/developers/docs/resources/channel#attachment-object}
*/
/**
* @typedef {Object} AttachmentData
* @property {string} [name] The name of the attachment
* @property {string} [description] The description of the attachment
*/

View File

@@ -1,6 +1,5 @@
'use strict';
const { channelLink } = require('@discordjs/builders');
const { DiscordSnowflake } = require('@sapphire/snowflake');
const { ChannelType, Routes } = require('discord-api-types/v10');
const Base = require('./Base');
@@ -56,7 +55,7 @@ class BaseChannel extends Base {
* @readonly
*/
get url() {
return this.isDMBased() ? channelLink(this.id) : channelLink(this.id, this.guildId);
return `https://discord.com/channels/${this.isDMBased() ? '@me' : this.guildId}/${this.id}`;
}
/**

View File

@@ -73,8 +73,8 @@ class Embed {
* @typedef {Object} EmbedAssetData
* @property {?string} url The URL of the image
* @property {?string} proxyURL The proxy URL of the image
* @property {?number} height The height of the image
* @property {?number} width The width of the image
* @property {?string} height The height of the image
* @property {?string} width The width of the image
*/
/**
@@ -115,10 +115,10 @@ class Embed {
get video() {
if (!this.data.video) return null;
return {
url: this.data.video.url,
proxyURL: this.data.video.proxy_url,
height: this.data.video.height,
width: this.data.video.width,
url: this.data.image.url,
proxyURL: this.data.image.proxy_url,
height: this.data.image.height,
width: this.data.image.width,
};
}

View File

@@ -216,8 +216,6 @@ class Guild extends AnonymousGuild {
* @type {?boolean}
*/
this.widgetEnabled = data.widget_enabled;
} else {
this.widgetEnabled ??= null;
}
if ('widget_channel_id' in data) {
@@ -226,8 +224,6 @@ class Guild extends AnonymousGuild {
* @type {?string}
*/
this.widgetChannelId = data.widget_channel_id;
} else {
this.widgetChannelId ??= null;
}
if ('explicit_content_filter' in data) {
@@ -291,16 +287,6 @@ class Guild extends AnonymousGuild {
this.maximumPresences ??= null;
}
if ('max_video_channel_users' in data) {
/**
* The maximum amount of users allowed in a video channel.
* @type {?number}
*/
this.maxVideoChannelUsers = data.max_video_channel_users;
} else {
this.maxVideoChannelUsers ??= null;
}
if ('approximate_member_count' in data) {
/**
* The approximate amount of members the guild has
@@ -493,7 +479,7 @@ class Guild extends AnonymousGuild {
/**
* Widget channel for this guild
* @type {?(TextChannel|NewsChannel|VoiceChannel|StageChannel)}
* @type {?TextChannel}
* @readonly
*/
get widgetChannel() {
@@ -564,7 +550,7 @@ class Guild extends AnonymousGuild {
* @returns {Promise<Collection<string, GuildTemplate>>}
*/
async fetchTemplates() {
const templates = await this.client.rest.get(Routes.guildTemplates(this.id));
const templates = await this.client.rest.get(Routes.guildTemplate(this.id));
return templates.reduce((col, data) => col.set(data.code, new GuildTemplate(this.client, data)), new Collection());
}
@@ -660,14 +646,14 @@ class Guild extends AnonymousGuild {
* Data for the Guild Widget Settings object
* @typedef {Object} GuildWidgetSettings
* @property {boolean} enabled Whether the widget is enabled
* @property {?(TextChannel|NewsChannel|VoiceChannel|StageChannel)} channel The widget invite channel
* @property {?GuildChannel} channel The widget invite channel
*/
/**
* The Guild Widget Settings object
* @typedef {Object} GuildWidgetSettingsData
* @property {boolean} enabled Whether the widget is enabled
* @property {?(TextChannel|NewsChannel|VoiceChannel|StageChannel|Snowflake)} channel The widget invite channel
* @property {?GuildChannelResolvable} channel The widget invite channel
*/
/**

View File

@@ -106,7 +106,7 @@ class GuildAuditLogsEntry {
this.actionType = GuildAuditLogsEntry.actionType(data.action_type);
/**
* The type of action that occured.
* Specific action type of this entry in its string presentation
* @type {AuditLogEvent}
*/
this.action = data.action_type;
@@ -220,6 +220,7 @@ class GuildAuditLogsEntry {
case AuditLogEvent.ApplicationCommandPermissionUpdate:
this.extra = {
applicationId: data.options.application_id,
guild: guild.client.guilds.cache.get(data.options.guild_id) ?? { id: data.options.guild_id },
};
break;

View File

@@ -1,6 +1,5 @@
'use strict';
const { messageLink } = require('@discordjs/builders');
const { Collection } = require('@discordjs/collection');
const { DiscordSnowflake } = require('@sapphire/snowflake');
const {
@@ -440,7 +439,7 @@ class Message extends Base {
* @readonly
*/
get url() {
return this.inGuild() ? messageLink(this.channelId, this.id, this.guildId) : messageLink(this.channelId, this.id);
return `https://discord.com/channels/${this.guildId ?? '@me'}/${this.channelId}/${this.id}`;
}
/**

View File

@@ -48,14 +48,6 @@ class MessageMentions {
*/
static GlobalChannelsPattern = new RegExp(this.ChannelsPattern.source, 'g');
/**
* A global regular expression variant of {@link MessageMentions.UsersPattern}.
* @type {RegExp}
* @memberof MessageMentions
* @private
*/
static GlobalUsersPattern = new RegExp(this.UsersPattern.source, 'g');
constructor(message, users, roles, everyone, crosspostedChannels, repliedUser) {
/**
* The client the message is from
@@ -141,13 +133,6 @@ class MessageMentions {
*/
this._channels = null;
/**
* Cached users for {@link MessageMentions#parsedUsers}
* @type {?Collection<Snowflake, User>}
* @private
*/
this._parsedUsers = null;
/**
* Crossposted channel data.
* @typedef {Object} CrosspostedChannel
@@ -223,23 +208,6 @@ class MessageMentions {
return this._channels;
}
/**
* Any user mentions that were included in the message content
* <info>Order as they appear first in the message content</info>
* @type {Collection<Snowflake, User>}
* @readonly
*/
get parsedUsers() {
if (this._parsedUsers) return this._parsedUsers;
this._parsedUsers = new Collection();
let matches;
while ((matches = this.constructor.GlobalUsersPattern.exec(this._content)) !== null) {
const user = this.client.users.cache.get(matches[1]);
if (user) this._parsedUsers.set(user.id, user);
}
return this._parsedUsers;
}
/**
* Options used to check for a mention.
* @typedef {Object} MessageMentionsHasOptions
@@ -259,23 +227,16 @@ class MessageMentions {
*/
has(data, { ignoreDirect = false, ignoreRoles = false, ignoreRepliedUser = false, ignoreEveryone = false } = {}) {
const user = this.client.users.resolve(data);
const role = this.guild?.roles.resolve(data);
const channel = this.client.channels.resolve(data);
if (!ignoreEveryone && user && this.everyone) return true;
const userWasRepliedTo = user && this.repliedUser?.id === user.id;
if (!ignoreRepliedUser && userWasRepliedTo && this.users.has(user.id)) return true;
if (!ignoreRepliedUser && this.users.has(this.repliedUser?.id) && this.repliedUser?.id === user?.id) return true;
if (!ignoreDirect) {
if (user && (!ignoreRepliedUser || this.parsedUsers.has(user.id)) && this.users.has(user.id)) return true;
const role = this.guild?.roles.resolve(data);
if (role && this.roles.has(role.id)) return true;
const channel = this.client.channels.resolve(data);
if (channel && this.channels.has(channel.id)) return true;
if (this.users.has(user?.id)) return true;
if (this.roles.has(role?.id)) return true;
if (this.channels.has(channel?.id)) return true;
}
if (user && !ignoreEveryone && this.everyone) return true;
if (!ignoreRoles) {
const member = this.guild?.members.resolve(data);
if (member) {

View File

@@ -283,11 +283,10 @@ class ThreadChannel extends BaseChannel {
* <info>This only works when the thread started from a message in the parent channel, otherwise the promise will
* reject. If you just need the id of that message, use {@link ThreadChannel#id} instead.</info>
* @param {BaseFetchOptions} [options] Additional options for this fetch
* @returns {Promise<Message|null>}
* @returns {Promise<Message>}
*/
// eslint-disable-next-line require-await
async fetchStarterMessage(options) {
return this.parent?.messages.fetch({ message: this.id, ...options }) ?? null;
fetchStarterMessage(options) {
return this.parent.messages.fetch({ message: this.id, ...options });
}
/**

View File

@@ -197,7 +197,7 @@ class InteractionResponses {
});
this.deferred = true;
return options.fetchReply ? this.fetchReply() : new InteractionResponse(this, this.message?.interaction?.id);
return options.fetchReply ? this.fetchReply() : new InteractionResponse(this, this.message.interaction?.id);
}
/**
@@ -255,7 +255,7 @@ class InteractionResponses {
* An object containing the same properties as {@link CollectorOptions}, but a few less:
* @typedef {Object} AwaitModalSubmitOptions
* @property {CollectorFilter} [filter] The filter applied to this collector
* @property {number} time Time in milliseconds to wait for an interaction before rejecting
* @property {number} time Time to wait for an interaction before rejecting
*/
/**

View File

@@ -283,7 +283,7 @@ class TextBasedChannel {
* @param {Collection<Snowflake, Message>|MessageResolvable[]|number} messages
* Messages or number of messages to delete
* @param {boolean} [filterOld=false] Filter messages to remove those which are older than two weeks automatically
* @returns {Promise<Collection<Snowflake, Message|undefined>>} Returns the deleted messages
* @returns {Promise<Collection<Snowflake, Message>>} Returns the deleted messages
* @example
* // Bulk delete messages
* channel.bulkDelete(5)

View File

@@ -2,36 +2,36 @@
/**
* @typedef {Object} Colors
* @property {number} Default 0x000000 | rgb(0,0,0)
* @property {number} White 0xFFFFFF | rgb(255,255,255)
* @property {number} Aqua 0x1ABC9C | rgb(26,188,156)
* @property {number} Green 0x57F287 | rgb(87,242,135)
* @property {number} Blue 0x3498DB | rgb(52,152,219)
* @property {number} Yellow 0xFEE75C | rgb(254,231,92)
* @property {number} Purple 0x9B59B6 | rgb(155,89,182)
* @property {number} LuminousVividPink 0xE91E63 | rgb(233,30,99)
* @property {number} Fuchsia 0xEB459E | rgb(235,69,158)
* @property {number} Gold 0xF1C40F | rgb(241,196,15)
* @property {number} Orange 0xE67E22 | rgb(230,126,34)
* @property {number} Red 0xED4245 | rgb(237,66,69)
* @property {number} Grey 0x95A5A6 | rgb(149,165,166)
* @property {number} Navy 0x34495E | rgb(52,73,94)
* @property {number} DarkAqua 0x11806A | rgb(17,128,106)
* @property {number} DarkGreen 0x1F8B4C | rgb(31,139,76)
* @property {number} DarkBlue 0x206694 | rgb(32,102,148)
* @property {number} DarkPurple 0x71368A | rgb(113,54,138)
* @property {number} DarkVividPink 0xAD1457 | rgb(173,20,87)
* @property {number} DarkGold 0xC27C0E | rgb(194,124,14)
* @property {number} DarkOrange 0xA84300 | rgb(168,67,0)
* @property {number} DarkRed 0x992D22 | rgb(153,45,34)
* @property {number} DarkGrey 0x979C9F | rgb(151,156,159)
* @property {number} DarkerGrey 0x7F8C8D | rgb(127,140,141)
* @property {number} LightGrey 0xBCC0C0 | rgb(188,192,192)
* @property {number} DarkNavy 0x2C3E50 | rgb(44,62,80)
* @property {number} Blurple 0x5865F2 | rgb(88,101,242)
* @property {number} Greyple 0x99AAb5 | rgb(153,170,181)
* @property {number} DarkButNotBlack 0x2C2F33 | rgb(44,47,51)
* @property {number} NotQuiteBlack 0x23272A | rgb(35,39,42)
* @property {number} Default
* @property {number} White
* @property {number} Aqua
* @property {number} Green
* @property {number} Blue
* @property {number} Yellow
* @property {number} Purple
* @property {number} LuminousVividPink
* @property {number} Fuchsia
* @property {number} Gold
* @property {number} Orange
* @property {number} Red
* @property {number} Grey
* @property {number} Navy
* @property {number} DarkAqua
* @property {number} DarkGreen
* @property {number} DarkBlue
* @property {number} DarkPurple
* @property {number} DarkVividPink
* @property {number} DarkGold
* @property {number} DarkOrange
* @property {number} DarkRed
* @property {number} DarkGrey
* @property {number} DarkerGrey
* @property {number} LightGrey
* @property {number} DarkNavy
* @property {number} Blurple
* @property {number} Greyple
* @property {number} DarkButNotBlack
* @property {number} NotQuiteBlack
*/
// JSDoc for IntelliSense purposes

View File

@@ -53,19 +53,13 @@ exports.NonSystemMessageTypes = [
];
/**
* The guild channels that are text-based.
* The channels that are text-based.
* * DMChannel
* * TextChannel
* * NewsChannel
* * ThreadChannel
* * VoiceChannel
* @typedef {TextChannel|NewsChannel|ThreadChannel|VoiceChannel} GuildTextBasedChannel
*/
/**
* The channels that are text-based.
* * DMChannel
* * GuildTextBasedChannel
* @typedef {DMChannel|GuildTextBasedChannel} TextBasedChannels
* @typedef {DMChannel|TextChannel|NewsChannel|ThreadChannel|VoiceChannel} TextBasedChannels
*/
/**

View File

@@ -116,7 +116,7 @@ class DataResolver extends null {
if (typeof resource[Symbol.asyncIterator] === 'function') {
const buffers = [];
for await (const data of resource) buffers.push(Buffer.from(data));
for await (const data of resource) buffers.push(data);
return { data: Buffer.concat(buffers) };
}

View File

@@ -132,23 +132,6 @@ const {
* @returns {string}
*/
/**
* Formats a channel link for a channel.
* @method channelLink
* @param {Snowflake} channelId The id of the channel
* @param {Snowflake} [guildId] The id of the guild
* @returns {string}
*/
/**
* Formats a message link for a channel.
* @method messageLink
* @param {Snowflake} channelId The id of the channel
* @param {Snowflake} messageId The id of the message
* @param {Snowflake} [guildId] The id of the guild
* @returns {string}
*/
/**
* A message formatting timestamp style, as defined in
* [here](https://discord.com/developers/docs/reference#message-formatting-timestamp-styles).

View File

@@ -9,7 +9,6 @@ const snakeCase = require('lodash.snakecase');
*/
function toSnakeCase(obj) {
if (typeof obj !== 'object' || !obj) return obj;
if (obj instanceof Date) return obj;
if (Array.isArray(obj)) return obj.map(toSnakeCase);
return Object.fromEntries(Object.entries(obj).map(([key, value]) => [snakeCase(key), toSnakeCase(value)]));
}

View File

@@ -192,10 +192,7 @@ declare module 'node:events' {
class EventEmitter {
// Add type overloads for client events.
public static once<K extends keyof ClientEvents>(eventEmitter: Client, eventName: K): Promise<ClientEvents[K]>;
public static on<K extends keyof ClientEvents>(
eventEmitter: Client,
eventName: K,
): AsyncIterableIterator<ClientEvents[K]>;
public static on<K extends keyof ClientEvents>(eventEmitter: Client, eventName: K): AsyncIterator<ClientEvents[K]>;
}
}
@@ -1086,7 +1083,6 @@ export class Guild extends AnonymousGuild {
public afkChannelId: Snowflake | null;
public afkTimeout: number;
public applicationId: Snowflake | null;
public maxVideoChannelUsers: number | null;
public approximateMemberCount: number | null;
public approximatePresenceCount: number | null;
public available: boolean;
@@ -1127,7 +1123,7 @@ export class Guild extends AnonymousGuild {
public vanityURLUses: number | null;
public get voiceAdapterCreator(): InternalDiscordGatewayAdapterCreator;
public voiceStates: VoiceStateManager;
public get widgetChannel(): TextChannel | NewsChannel | VoiceBasedChannel | null;
public get widgetChannel(): TextChannel | null;
public widgetChannelId: Snowflake | null;
public widgetEnabled: boolean | null;
public get maximumBitrate(): number;
@@ -1181,37 +1177,35 @@ export class Guild extends AnonymousGuild {
public toJSON(): unknown;
}
export class GuildAuditLogs<T extends GuildAuditLogsResolvable = AuditLogEvent> {
export class GuildAuditLogs<T extends GuildAuditLogsResolvable = null> {
private constructor(guild: Guild, data: RawGuildAuditLogData);
private applicationCommands: Collection<Snowflake, ApplicationCommand>;
private webhooks: Collection<Snowflake, Webhook>;
private integrations: Collection<Snowflake | string, Integration>;
private guildScheduledEvents: Collection<Snowflake, GuildScheduledEvent>;
public entries: Collection<Snowflake, GuildAuditLogsEntry<T>>;
public static Entry: typeof GuildAuditLogsEntry;
public toJSON(): unknown;
}
export class GuildAuditLogsEntry<
TAction extends GuildAuditLogsResolvable = AuditLogEvent,
TAction extends GuildAuditLogsResolvable = null,
TActionType extends GuildAuditLogsActionType = TAction extends keyof GuildAuditLogsTypes
? GuildAuditLogsTypes[TAction][1]
: GuildAuditLogsActionType,
: 'All',
TTargetType extends GuildAuditLogsTargetType = TAction extends keyof GuildAuditLogsTypes
? GuildAuditLogsTypes[TAction][0]
: GuildAuditLogsTargetType,
TResolvedType = TAction extends null ? AuditLogEvent : TAction,
: 'Unknown',
> {
private constructor(logs: GuildAuditLogs, guild: Guild, data: RawGuildAuditLogEntryData);
public static Targets: GuildAuditLogsTargets;
public action: TResolvedType;
public action: TAction;
public actionType: TActionType;
public changes: AuditLogChange[];
public get createdAt(): Date;
public get createdTimestamp(): number;
public executor: User | null;
public extra: TResolvedType extends keyof GuildAuditLogsEntryExtraField
? GuildAuditLogsEntryExtraField[TResolvedType]
: null;
public extra: TAction extends keyof GuildAuditLogsEntryExtraField ? GuildAuditLogsEntryExtraField[TAction] : null;
public id: Snowflake;
public reason: string | null;
public target: TTargetType extends keyof GuildAuditLogsEntryTargetField<TActionType>
@@ -1871,7 +1865,6 @@ export class MessageMentions {
private _channels: Collection<Snowflake, Channel> | null;
private readonly _content: string;
private _members: Collection<Snowflake, GuildMember> | null;
private _parsedUsers: Collection<Snowflake, User> | null;
public get channels(): Collection<Snowflake, Channel>;
public readonly client: Client;
@@ -1879,16 +1872,14 @@ export class MessageMentions {
public readonly guild: Guild;
public has(data: UserResolvable | RoleResolvable | ChannelResolvable, options?: MessageMentionsHasOptions): boolean;
public get members(): Collection<Snowflake, GuildMember> | null;
public get parsedUsers(): Collection<Snowflake, User>;
public repliedUser: User | null;
public roles: Collection<Snowflake, Role>;
public users: Collection<Snowflake, User>;
public crosspostedChannels: Collection<Snowflake, CrosspostedChannel>;
public toJSON(): unknown;
private static GlobalChannelsPattern: RegExp;
private static GlobalUsersPattern: RegExp;
public static ChannelsPattern: typeof FormattingPatterns.Channel;
private static GlobalChannelsPattern: RegExp;
public static EveryonePattern: RegExp;
public static RolesPattern: typeof FormattingPatterns.Role;
public static UsersPattern: typeof FormattingPatterns.User;
@@ -1975,11 +1966,12 @@ export class ModalSubmitFields {
export interface ModalMessageModalSubmitInteraction<Cached extends CacheType = CacheType>
extends ModalSubmitInteraction<Cached> {
message: Message<BooleanCache<Cached>>;
channelId: Snowflake;
update(options: InteractionUpdateOptions & { fetchReply: true }): Promise<Message>;
update(
options: string | MessagePayload | InteractionUpdateOptions,
): Promise<InteractionResponse<BooleanCache<Cached>>>;
deferUpdate(options: InteractionDeferUpdateOptions & { fetchReply: true }): Promise<Message>;
deferUpdate(options?: InteractionDeferUpdateOptions): Promise<InteractionResponse<BooleanCache<Cached>>>;
inGuild(): this is ModalMessageModalSubmitInteraction<'raw' | 'cached'>;
inCachedGuild(): this is ModalMessageModalSubmitInteraction<'cached'>;
inRawGuild(): this is ModalMessageModalSubmitInteraction<'raw'>;
@@ -2010,8 +2002,6 @@ export class ModalSubmitInteraction<Cached extends CacheType = CacheType> extend
public deferReply(options?: InteractionDeferReplyOptions): Promise<InteractionResponse<BooleanCache<Cached>>>;
public fetchReply(): Promise<Message<BooleanCache<Cached>>>;
public followUp(options: string | MessagePayload | InteractionReplyOptions): Promise<Message<BooleanCache<Cached>>>;
public deferUpdate(options: InteractionDeferUpdateOptions & { fetchReply: true }): Promise<Message>;
public deferUpdate(options?: InteractionDeferUpdateOptions): Promise<InteractionResponse<BooleanCache<Cached>>>;
public inGuild(): this is ModalSubmitInteraction<'raw' | 'cached'>;
public inCachedGuild(): this is ModalSubmitInteraction<'cached'>;
public inRawGuild(): this is ModalSubmitInteraction<'raw'>;
@@ -2546,7 +2536,7 @@ export class ThreadChannel extends TextBasedChannelMixin(BaseChannel, ['fetchWeb
checkAdmin?: boolean,
): Readonly<PermissionsBitField> | null;
public fetchOwner(options?: BaseFetchOptions): Promise<ThreadMember | null>;
public fetchStarterMessage(options?: BaseFetchOptions): Promise<Message | null>;
public fetchStarterMessage(options?: BaseFetchOptions): Promise<Message>;
public setArchived(archived?: boolean, reason?: string): Promise<AnyThreadChannel>;
public setAutoArchiveDuration(
autoArchiveDuration: ThreadAutoArchiveDuration,
@@ -3029,152 +3019,152 @@ export const version: string;
//#region Errors
export enum DiscordjsErrorCodes {
ClientInvalidOption = 'ClientInvalidOption',
ClientInvalidProvidedShards = 'ClientInvalidProvidedShards',
ClientMissingIntents = 'ClientMissingIntents',
ClientNotReady = 'ClientNotReady',
ClientInvalidOption,
ClientInvalidProvidedShards,
ClientMissingIntents,
ClientNotReady,
TokenInvalid = 'TokenInvalid',
TokenMissing = 'TokenMissing',
ApplicationCommandPermissionsTokenMissing = 'ApplicationCommandPermissionsTokenMissing',
TokenInvalid,
TokenMissing,
ApplicationCommandPermissionsTokenMissing,
WSCloseRequested = 'WSCloseRequested',
WSConnectionExists = 'WSConnectionExists',
WSNotOpen = 'WSNotOpen',
ManagerDestroyed = 'ManagerDestroyed',
WSCloseRequested,
WSConnectionExists,
WSNotOpen,
ManagerDestroyed,
BitFieldInvalid = 'BitFieldInvalid',
BitFieldInvalid,
ShardingInvalid = 'ShardingInvalid',
ShardingRequired = 'ShardingRequired',
InvalidIntents = 'InvalidIntents',
DisallowedIntents = 'DisallowedIntents',
ShardingNoShards = 'ShardingNoShards',
ShardingInProcess = 'ShardingInProcess',
ShardingInvalidEvalBroadcast = 'ShardingInvalidEvalBroadcast',
ShardingShardNotFound = 'ShardingShardNotFound',
ShardingAlreadySpawned = 'ShardingAlreadySpawned',
ShardingProcessExists = 'ShardingProcessExists',
ShardingWorkerExists = 'ShardingWorkerExists',
ShardingReadyTimeout = 'ShardingReadyTimeout',
ShardingReadyDisconnected = 'ShardingReadyDisconnected',
ShardingReadyDied = 'ShardingReadyDied',
ShardingNoChildExists = 'ShardingNoChildExists',
ShardingShardMiscalculation = 'ShardingShardMiscalculation',
ShardingInvalid,
ShardingRequired,
InvalidIntents,
DisallowedIntents,
ShardingNoShards,
ShardingInProcess,
ShardingInvalidEvalBroadcast,
ShardingShardNotFound,
ShardingAlreadySpawned,
ShardingProcessExists,
ShardingWorkerExists,
ShardingReadyTimeout,
ShardingReadyDisconnected,
ShardingReadyDied,
ShardingNoChildExists,
ShardingShardMiscalculation,
ColorRange = 'ColorRange',
ColorConvert = 'ColorConvert',
ColorRange,
ColorConvert,
InviteOptionsMissingChannel = 'InviteOptionsMissingChannel',
InviteOptionsMissingChannel,
ButtonLabel = 'ButtonLabel',
ButtonURL = 'ButtonURL',
ButtonCustomId = 'ButtonCustomId',
ButtonLabel,
ButtonURL,
ButtonCustomId,
SelectMenuCustomId = 'SelectMenuCustomId',
SelectMenuPlaceholder = 'SelectMenuPlaceholder',
SelectOptionLabel = 'SelectOptionLabel',
SelectOptionValue = 'SelectOptionValue',
SelectOptionDescription = 'SelectOptionDescription',
SelectMenuCustomId,
SelectMenuPlaceholder,
SelectOptionLabel,
SelectOptionValue,
SelectOptionDescription,
InteractionCollectorError = 'InteractionCollectorError',
InteractionCollectorError,
FileNotFound = 'FileNotFound',
FileNotFound,
UserBannerNotFetched = 'UserBannerNotFetched',
UserNoDMChannel = 'UserNoDMChannel',
UserBannerNotFetched,
UserNoDMChannel,
VoiceNotStageChannel = 'VoiceNotStageChannel',
VoiceNotStageChannel,
VoiceStateNotOwn = 'VoiceStateNotOwn',
VoiceStateInvalidType = 'VoiceStateInvalidType',
VoiceStateNotOwn,
VoiceStateInvalidType,
ReqResourceType = 'ReqResourceType',
ReqResourceType,
ImageFormat = 'ImageFormat',
ImageSize = 'ImageSize',
ImageFormat,
ImageSize,
MessageBulkDeleteType = 'MessageBulkDeleteType',
MessageNonceType = 'MessageNonceType',
MessageContentType = 'MessageContentType',
MessageBulkDeleteType,
MessageNonceType,
MessageContentType,
SplitMaxLen = 'SplitMaxLen',
SplitMaxLen,
BanResolveId = 'BanResolveId',
FetchBanResolveId = 'FetchBanResolveId',
BanResolveId,
FetchBanResolveId,
PruneDaysType = 'PruneDaysType',
PruneDaysType,
GuildChannelResolve = 'GuildChannelResolve',
GuildVoiceChannelResolve = 'GuildVoiceChannelResolve',
GuildChannelOrphan = 'GuildChannelOrphan',
GuildChannelUnowned = 'GuildChannelUnowned',
GuildOwned = 'GuildOwned',
GuildMembersTimeout = 'GuildMembersTimeout',
GuildUncachedMe = 'GuildUncachedMe',
ChannelNotCached = 'ChannelNotCached',
StageChannelResolve = 'StageChannelResolve',
GuildScheduledEventResolve = 'GuildScheduledEventResolve',
FetchOwnerId = 'FetchOwnerId',
GuildChannelResolve,
GuildVoiceChannelResolve,
GuildChannelOrphan,
GuildChannelUnowned,
GuildOwned,
GuildMembersTimeout,
GuildUncachedMe,
ChannelNotCached,
StageChannelResolve,
GuildScheduledEventResolve,
FetchOwnerId,
InvalidType = 'InvalidType',
InvalidElement = 'InvalidElement',
InvalidType,
InvalidElement,
MessageThreadParent = 'MessageThreadParent',
MessageExistingThread = 'MessageExistingThread',
ThreadInvitableType = 'ThreadInvitableType',
MessageThreadParent,
MessageExistingThread,
ThreadInvitableType,
WebhookMessage = 'WebhookMessage',
WebhookTokenUnavailable = 'WebhookTokenUnavailable',
WebhookURLInvalid = 'WebhookURLInvalid',
WebhookApplication = 'WebhookApplication',
MessageReferenceMissing = 'MessageReferenceMissing',
WebhookMessage,
WebhookTokenUnavailable,
WebhookURLInvalid,
WebhookApplication,
MessageReferenceMissing,
EmojiType = 'EmojiType',
EmojiManaged = 'EmojiManaged',
MissingManageEmojisAndStickersPermission = 'MissingManageEmojisAndStickersPermission',
NotGuildSticker = 'NotGuildSticker',
EmojiType,
EmojiManaged,
MissingManageEmojisAndStickersPermission,
NotGuildSticker,
ReactionResolveUser = 'ReactionResolveUser',
ReactionResolveUser,
VanityURL = 'VanityURL',
VanityURL,
InviteResolveCode = 'InviteResolveCode',
InviteResolveCode,
InviteNotFound = 'InviteNotFound',
InviteNotFound,
DeleteGroupDMChannel = 'DeleteGroupDMChannel',
FetchGroupDMChannel = 'FetchGroupDMChannel',
DeleteGroupDMChannel,
FetchGroupDMChannel,
MemberFetchNonceLength = 'MemberFetchNonceLength',
MemberFetchNonceLength,
GlobalCommandPermissions = 'GlobalCommandPermissions',
GuildUncachedEntityResolve = 'GuildUncachedEntityResolve',
GlobalCommandPermissions,
GuildUncachedEntityResolve,
InteractionAlreadyReplied = 'InteractionAlreadyReplied',
InteractionNotReplied = 'InteractionNotReplied',
InteractionEphemeralReplied = 'InteractionEphemeralReplied',
InteractionAlreadyReplied,
InteractionNotReplied,
InteractionEphemeralReplied,
CommandInteractionOptionNotFound = 'CommandInteractionOptionNotFound',
CommandInteractionOptionType = 'CommandInteractionOptionType',
CommandInteractionOptionEmpty = 'CommandInteractionOptionEmpty',
CommandInteractionOptionNoSubcommand = 'CommandInteractionOptionNoSubcommand',
CommandInteractionOptionNoSubcommandGroup = 'CommandInteractionOptionNoSubcommandGroup',
AutocompleteInteractionOptionNoFocusedOption = 'AutocompleteInteractionOptionNoFocusedOption',
CommandInteractionOptionNotFound,
CommandInteractionOptionType,
CommandInteractionOptionEmpty,
CommandInteractionOptionNoSubcommand,
CommandInteractionOptionNoSubcommandGroup,
AutocompleteInteractionOptionNoFocusedOption,
ModalSubmitInteractionFieldNotFound = 'ModalSubmitInteractionFieldNotFound',
ModalSubmitInteractionFieldType = 'ModalSubmitInteractionFieldType',
ModalSubmitInteractionFieldNotFound,
ModalSubmitInteractionFieldType,
InvalidMissingScopes = 'InvalidMissingScopes',
InvalidMissingScopes,
NotImplemented = 'NotImplemented',
NotImplemented,
SweepFilterReturn = 'SweepFilterReturn',
SweepFilterReturn,
}
export interface DiscordjsErrorFields<Name extends string> {
readonly name: `${Name} [${DiscordjsErrorCodes}]`;
get code(): DiscordjsErrorCodes;
readonly name: `${Name} [${keyof typeof DiscordjsErrorCodes}]`;
get code(): keyof typeof DiscordjsErrorCodes;
}
export function DiscordjsErrorMixin<T, N extends string>(
@@ -3412,12 +3402,6 @@ export class GuildManager extends CachedManager<Snowflake, Guild, GuildResolvabl
public fetch(options?: FetchGuildsOptions): Promise<Collection<Snowflake, OAuth2Guild>>;
}
export interface AddOrRemoveGuildMemberRoleOptions {
user: GuildMemberResolvable;
role: RoleResolvable;
reason?: string;
}
export class GuildMemberManager extends CachedManager<Snowflake, GuildMember, GuildMemberResolvable> {
private constructor(guild: Guild, iterable?: Iterable<RawGuildMemberData>);
public guild: Guild;
@@ -3440,8 +3424,6 @@ export class GuildMemberManager extends CachedManager<Snowflake, GuildMember, Gu
public prune(options?: GuildPruneMembersOptions): Promise<number>;
public search(options: GuildSearchMembersOptions): Promise<Collection<Snowflake, GuildMember>>;
public unban(user: UserResolvable, reason?: string): Promise<User | null>;
public addRole(options: AddOrRemoveGuildMemberRoleOptions): Promise<GuildMember | User | Snowflake>;
public removeRole(options: AddOrRemoveGuildMemberRoleOptions): Promise<GuildMember | User | Snowflake>;
}
export class GuildBanManager extends CachedManager<Snowflake, GuildBan, GuildBanResolvable> {
@@ -3672,7 +3654,7 @@ export interface TextBasedChannelFields extends PartialTextBasedChannelFields {
bulkDelete(
messages: Collection<Snowflake, Message> | readonly MessageResolvable[] | number,
filterOld?: boolean,
): Promise<Collection<Snowflake, Message | PartialMessage | undefined>>;
): Promise<Collection<Snowflake, Message>>;
createMessageComponentCollector<T extends MessageComponentType>(
options?: MessageChannelCollectorOptionsParams<T, true>,
): InteractionCollector<MappedInteractionTypes[T]>;
@@ -3809,85 +3791,31 @@ export interface ApplicationCommandChannelOption extends BaseApplicationCommandO
channelTypes?: ChannelType[];
}
export interface ApplicationCommandRoleOptionData extends BaseApplicationCommandOptionsData {
type: ApplicationCommandOptionType.Role;
}
export interface ApplicationCommandRoleOption extends BaseApplicationCommandOptionsData {
type: ApplicationCommandOptionType.Role;
}
export interface ApplicationCommandUserOptionData extends BaseApplicationCommandOptionsData {
type: ApplicationCommandOptionType.User;
}
export interface ApplicationCommandUserOption extends BaseApplicationCommandOptionsData {
type: ApplicationCommandOptionType.User;
}
export interface ApplicationCommandMentionableOptionData extends BaseApplicationCommandOptionsData {
type: ApplicationCommandOptionType.Mentionable;
}
export interface ApplicationCommandMentionableOption extends BaseApplicationCommandOptionsData {
type: ApplicationCommandOptionType.Mentionable;
}
export interface ApplicationCommandAttachmentOption extends BaseApplicationCommandOptionsData {
type: ApplicationCommandOptionType.Attachment;
}
export interface ApplicationCommandAutocompleteNumericOption
extends Omit<BaseApplicationCommandOptionsData, 'autocomplete'> {
type: CommandOptionNumericResolvableType;
minValue?: number;
maxValue?: number;
export interface ApplicationCommandAutocompleteOption extends Omit<BaseApplicationCommandOptionsData, 'autocomplete'> {
type:
| ApplicationCommandOptionType.String
| ApplicationCommandOptionType.Number
| ApplicationCommandOptionType.Integer;
autocomplete: true;
}
export interface ApplicationCommandAutocompleteStringOption
extends Omit<BaseApplicationCommandOptionsData, 'autocomplete'> {
type: ApplicationCommandOptionType.String;
minLength?: number;
maxLength?: number;
autocomplete: true;
}
export interface ApplicationCommandAutocompleteNumericOptionData
extends Omit<BaseApplicationCommandOptionsData, 'autocomplete'> {
type: CommandOptionNumericResolvableType;
minValue?: number;
min_value?: number;
maxValue?: number;
max_value?: number;
autocomplete: true;
}
export interface ApplicationCommandAutocompleteStringOptionData
extends Omit<BaseApplicationCommandOptionsData, 'autocomplete'> {
type: ApplicationCommandOptionType.String;
minLength?: number;
min_length?: number;
maxLength?: number;
max_length?: number;
autocomplete: true;
}
export interface ApplicationCommandChoicesData<Type extends string | number = string | number>
extends Omit<BaseApplicationCommandOptionsData, 'autocomplete'> {
export interface ApplicationCommandChoicesData extends Omit<BaseApplicationCommandOptionsData, 'autocomplete'> {
type: CommandOptionChoiceResolvableType;
choices?: ApplicationCommandOptionChoiceData<Type>[];
choices?: ApplicationCommandOptionChoiceData[];
autocomplete?: false;
}
export interface ApplicationCommandChoicesOption<Type extends string | number = string | number>
extends Omit<BaseApplicationCommandOptionsData, 'autocomplete'> {
export interface ApplicationCommandChoicesOption extends Omit<BaseApplicationCommandOptionsData, 'autocomplete'> {
type: CommandOptionChoiceResolvableType;
choices?: ApplicationCommandOptionChoiceData<Type>[];
choices?: ApplicationCommandOptionChoiceData[];
autocomplete?: false;
}
export interface ApplicationCommandNumericOptionData extends ApplicationCommandChoicesData<number> {
export interface ApplicationCommandNumericOptionData extends ApplicationCommandChoicesData {
type: CommandOptionNumericResolvableType;
minValue?: number;
min_value?: number;
@@ -3895,7 +3823,7 @@ export interface ApplicationCommandNumericOptionData extends ApplicationCommandC
max_value?: number;
}
export interface ApplicationCommandStringOptionData extends ApplicationCommandChoicesData<string> {
export interface ApplicationCommandStringOptionData extends ApplicationCommandChoicesData {
type: ApplicationCommandOptionType.String;
minLength?: number;
min_length?: number;
@@ -3903,26 +3831,18 @@ export interface ApplicationCommandStringOptionData extends ApplicationCommandCh
max_length?: number;
}
export interface ApplicationCommandBooleanOptionData extends BaseApplicationCommandOptionsData {
type: ApplicationCommandOptionType.Boolean;
}
export interface ApplicationCommandNumericOption extends ApplicationCommandChoicesOption<number> {
export interface ApplicationCommandNumericOption extends ApplicationCommandChoicesOption {
type: CommandOptionNumericResolvableType;
minValue?: number;
maxValue?: number;
}
export interface ApplicationCommandStringOption extends ApplicationCommandChoicesOption<string> {
export interface ApplicationCommandStringOption extends ApplicationCommandChoicesOption {
type: ApplicationCommandOptionType.String;
minLength?: number;
maxLength?: number;
}
export interface ApplicationCommandBooleanOption extends BaseApplicationCommandOptionsData {
type: ApplicationCommandOptionType.Boolean;
}
export interface ApplicationCommandSubGroupData extends Omit<BaseApplicationCommandOptionsData, 'required'> {
type: ApplicationCommandOptionType.SubcommandGroup;
options?: ApplicationCommandSubCommandData[];
@@ -3935,12 +3855,19 @@ export interface ApplicationCommandSubGroup extends Omit<BaseApplicationCommandO
export interface ApplicationCommandSubCommandData extends Omit<BaseApplicationCommandOptionsData, 'required'> {
type: ApplicationCommandOptionType.Subcommand;
options?: Exclude<ApplicationCommandOptionData, ApplicationCommandSubGroupData | ApplicationCommandSubCommandData>[];
options?: (
| ApplicationCommandChoicesData
| ApplicationCommandNonOptionsData
| ApplicationCommandChannelOptionData
| ApplicationCommandAutocompleteOption
| ApplicationCommandNumericOptionData
| ApplicationCommandStringOptionData
)[];
}
export interface ApplicationCommandSubCommand extends Omit<BaseApplicationCommandOptionsData, 'required'> {
type: ApplicationCommandOptionType.Subcommand;
options?: Exclude<ApplicationCommandOption, ApplicationCommandSubGroup | ApplicationCommandSubCommand>[];
options?: (ApplicationCommandChoicesOption | ApplicationCommandNonOptions | ApplicationCommandChannelOption)[];
}
export interface ApplicationCommandNonOptionsData extends BaseApplicationCommandOptionsData {
@@ -3955,35 +3882,26 @@ export type ApplicationCommandOptionData =
| ApplicationCommandSubGroupData
| ApplicationCommandNonOptionsData
| ApplicationCommandChannelOptionData
| ApplicationCommandAutocompleteNumericOptionData
| ApplicationCommandAutocompleteStringOptionData
| ApplicationCommandChoicesData
| ApplicationCommandAutocompleteOption
| ApplicationCommandNumericOptionData
| ApplicationCommandStringOptionData
| ApplicationCommandRoleOptionData
| ApplicationCommandUserOptionData
| ApplicationCommandMentionableOptionData
| ApplicationCommandBooleanOptionData
| ApplicationCommandSubCommandData;
export type ApplicationCommandOption =
| ApplicationCommandSubGroup
| ApplicationCommandAutocompleteNumericOption
| ApplicationCommandAutocompleteStringOption
| ApplicationCommandNonOptions
| ApplicationCommandChannelOption
| ApplicationCommandChoicesOption
| ApplicationCommandNumericOption
| ApplicationCommandStringOption
| ApplicationCommandRoleOption
| ApplicationCommandUserOption
| ApplicationCommandMentionableOption
| ApplicationCommandBooleanOption
| ApplicationCommandAttachmentOption
| ApplicationCommandSubCommand;
export interface ApplicationCommandOptionChoiceData<Value extends string | number = string | number> {
export interface ApplicationCommandOptionChoiceData {
name: string;
nameLocalizations?: LocalizationMap;
value: Value;
value: string | number;
}
export interface ApplicationCommandPermissions {
@@ -4157,7 +4075,7 @@ export interface ChannelWebhookCreateOptions {
}
export interface WebhookCreateOptions extends ChannelWebhookCreateOptions {
channel: TextChannel | NewsChannel | VoiceChannel | Snowflake;
channel: GuildChannelResolvable;
}
export interface ClientEvents {
@@ -4201,7 +4119,7 @@ export interface ClientEvents {
reactions: Collection<string | Snowflake, MessageReaction>,
];
messageReactionRemoveEmoji: [reaction: MessageReaction | PartialMessageReaction];
messageDeleteBulk: [messages: Collection<Snowflake, Message | PartialMessage>, channel: GuildTextBasedChannel];
messageDeleteBulk: [messages: Collection<Snowflake, Message | PartialMessage>, channel: TextBasedChannel];
messageReactionAdd: [reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser];
messageReactionRemove: [reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser];
messageUpdate: [oldMessage: Message | PartialMessage, newMessage: Message | PartialMessage];
@@ -4738,7 +4656,7 @@ export interface GuildAuditLogsEntryExtraField {
[AuditLogEvent.StageInstanceCreate]: StageChannel | { id: Snowflake };
[AuditLogEvent.StageInstanceDelete]: StageChannel | { id: Snowflake };
[AuditLogEvent.StageInstanceUpdate]: StageChannel | { id: Snowflake };
[AuditLogEvent.ApplicationCommandPermissionUpdate]: { applicationId: Snowflake };
[AuditLogEvent.ApplicationCommandPermissionUpdate]: { applicationId: Snowflake; guild: Guild | { id: Snowflake } };
}
export interface GuildAuditLogsEntryTargetField<TActionType extends GuildAuditLogsActionType> {
@@ -4830,7 +4748,7 @@ export interface GuildCreateOptions {
export interface GuildWidgetSettings {
enabled: boolean;
channel: TextChannel | NewsChannel | VoiceBasedChannel | null;
channel: NonThreadGuildBasedChannel | null;
}
export interface GuildEditData {
@@ -4908,7 +4826,7 @@ export interface GuildPruneMembersOptions {
export interface GuildWidgetSettingsData {
enabled: boolean;
channel: TextChannel | NewsChannel | VoiceBasedChannel | Snowflake | null;
channel: GuildChannelResolvable | null;
}
export interface GuildSearchMembersOptions {
@@ -5702,4 +5620,4 @@ export type InternalDiscordGatewayAdapterCreator = (
// External
export * from 'discord-api-types/v10';
export * from '@discordjs/builders';
export * from '@discordjs/rest';
export { DiscordAPIError, HTTPError, RateLimitError } from '@discordjs/rest';

View File

@@ -134,8 +134,6 @@ import {
Webhook,
WebhookClient,
InteractionWebhook,
GuildAuditLogsActionType,
GuildAuditLogsTargetType,
} from '.';
import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd';
import type { ContextMenuCommandBuilder, SlashCommandBuilder } from '@discordjs/builders';
@@ -1102,7 +1100,6 @@ expectAssignable<'death'>(ShardEvents.Death);
expectAssignable<1>(Status.Connecting);
declare const applicationCommandData: ApplicationCommandData;
declare const applicationCommandOptionData: ApplicationCommandOptionData;
declare const applicationCommandResolvable: ApplicationCommandResolvable;
declare const applicationCommandManager: ApplicationCommandManager;
{
@@ -1122,24 +1119,6 @@ declare const applicationCommandManager: ApplicationCommandManager;
expectType<Promise<Collection<Snowflake, ApplicationCommand>>>(
applicationCommandManager.set([applicationCommandData], '0'),
);
// Test inference of choice values.
if ('choices' in applicationCommandOptionData) {
if (applicationCommandOptionData.type === ApplicationCommandOptionType.String) {
expectType<string>(applicationCommandOptionData.choices[0]!.value);
expectNotType<number>(applicationCommandOptionData.choices[0]!.value);
}
if (applicationCommandOptionData.type === ApplicationCommandOptionType.Integer) {
expectType<number>(applicationCommandOptionData.choices[0]!.value);
expectNotType<string>(applicationCommandOptionData.choices[0]!.value);
}
if (applicationCommandOptionData.type === ApplicationCommandOptionType.Number) {
expectType<number>(applicationCommandOptionData.choices[0]!.value);
expectNotType<string>(applicationCommandOptionData.choices[0]!.value);
}
}
}
declare const applicationNonChoiceOptionData: ApplicationCommandOptionData & {
@@ -1554,7 +1533,7 @@ expectType<Promise<GuildAuditLogs<AuditLogEvent.IntegrationUpdate>>>(
);
expectType<Promise<GuildAuditLogs<null>>>(guild.fetchAuditLogs({ type: null }));
expectType<Promise<GuildAuditLogs<AuditLogEvent>>>(guild.fetchAuditLogs());
expectType<Promise<GuildAuditLogs<null>>>(guild.fetchAuditLogs());
expectType<Promise<GuildAuditLogsEntry<AuditLogEvent.MemberKick, 'Delete', 'User'> | undefined>>(
guild.fetchAuditLogs({ type: AuditLogEvent.MemberKick }).then(al => al.entries.first()),
@@ -1563,10 +1542,10 @@ expectAssignable<Promise<GuildAuditLogsEntry<AuditLogEvent.MemberKick, 'Delete',
guild.fetchAuditLogs({ type: AuditLogEvent.MemberKick }).then(al => al.entries.first()),
);
expectType<Promise<GuildAuditLogsEntry<null, GuildAuditLogsActionType, GuildAuditLogsTargetType> | undefined>>(
expectType<Promise<GuildAuditLogsEntry<null, 'All', 'Unknown'> | undefined>>(
guild.fetchAuditLogs({ type: null }).then(al => al.entries.first()),
);
expectType<Promise<GuildAuditLogsEntry<null, GuildAuditLogsActionType, GuildAuditLogsTargetType> | undefined>>(
expectType<Promise<GuildAuditLogsEntry<null, 'All', 'Unknown'> | undefined>>(
guild.fetchAuditLogs().then(al => al.entries.first()),
);

View File

@@ -5,4 +5,5 @@ dist/
docs/**/*
!docs/index.yml
!docs/README.md
coverage/
coverage/
tsup.config.*.mjs

View File

@@ -1,9 +1,3 @@
import { createUnbuildConfig } from '../../build.config';
export default createUnbuildConfig({
entries: [
{ builder: 'rollup', input: 'src/index' },
{ builder: 'rollup', input: 'src/cli' },
],
minify: true,
});
export default createUnbuildConfig({ minify: true, externals: ['package.cjs', 'package.mjs'] });

View File

@@ -1,17 +1,17 @@
{
"name": "@discordjs/docgen",
"version": "0.12.1",
"version": "0.12.0",
"description": "The docs.json generator for discord.js and its related projects",
"scripts": {
"build": "unbuild",
"lint": "prettier --check . && TIMING=1 eslint src --ext mjs,js,ts",
"format": "prettier --write . && TIMING=1 eslint src --ext mjs,js,ts --fix",
"lint": "prettier --check . && eslint src --ext mjs,js,ts",
"format": "prettier --write . && eslint src --ext mjs,js,ts --fix",
"fmt": "yarn format",
"prepack": "yarn format && yarn build",
"prepack": "yarn lint && yarn test && yarn build",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/docgen/*'",
"release": "cliff-jumper"
},
"bin": "./dist/cli.cjs",
"bin": "./dist/index.cjs",
"directories": {
"lib": "src"
},
@@ -42,31 +42,24 @@
},
"homepage": "https://discord.js.org",
"dependencies": {
"@discordjs/collection": "workspace:^",
"commander": "^9.4.0",
"jsdoc-to-markdown": "^7.1.1",
"tslib": "^2.4.0",
"typedoc": "^0.23.10"
"typedoc": "^0.23.9"
},
"devDependencies": {
"@favware/cliff-jumper": "^1.8.7",
"@favware/cliff-jumper": "^1.8.5",
"@types/jsdoc-to-markdown": "^7.0.3",
"@types/node": "^16.11.52",
"@typescript-eslint/eslint-plugin": "^5.33.1",
"@typescript-eslint/parser": "^5.33.1",
"eslint": "^8.22.0",
"eslint-config-marine": "^9.4.1",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-typescript": "^3.4.2",
"eslint-plugin-import": "^2.26.0",
"@types/node": "^16.11.45",
"eslint": "^8.20.0",
"prettier": "^2.7.1",
"rollup-plugin-typescript2": "^0.33.0",
"rollup-plugin-typescript2": "0.32.1",
"tsup": "^6.2.0",
"typescript": "^4.7.4",
"unbuild": "^0.8.9"
"unbuild": "^0.7.6"
},
"engines": {
"node": ">=16.9.0"
},
"publishConfig": {
"access": "public"
}
}

View File

@@ -1,25 +0,0 @@
#!/usr/bin/env node
import { createCommand } from 'commander';
import { build } from './index.js';
import packageFile from '../package.json';
export interface CLIOptions {
input: string[];
custom: string;
root: string;
output: string;
typescript: boolean;
}
const command = createCommand()
.version(packageFile.version)
.option('-i, --input <string...>', 'Source directories to parse JSDocs in')
.option('-c, --custom <string>', 'Custom docs definition file to use')
.option('-r, --root [string]', 'Root directory of the project', '.')
.option('-o, --output <string>', 'Path to output file')
.option('--typescript', '', false);
const program = command.parse(process.argv);
const options = program.opts<CLIOptions>();
build(options);

View File

@@ -1,4 +1,5 @@
import { dirname, join, relative } from 'node:path';
import { Collection } from '@discordjs/collection';
import type { DeclarationReflection } from 'typedoc';
import type { ChildTypes, Class, Config, CustomDocs, RootTypes } from './interfaces/index.js';
import { DocumentedClass } from './types/class.js';
@@ -12,15 +13,15 @@ import { DocumentedTypeDef } from './types/typedef.js';
import packageFile from '../package.json';
export class Documentation {
public readonly classes = new Map<string, DocumentedClass>();
public readonly classes = new Collection<string, DocumentedClass>();
public readonly functions = new Map<string, DocumentedMethod>();
public readonly functions = new Collection<string, DocumentedMethod>();
public readonly interfaces = new Map<string, DocumentedInterface>();
public readonly interfaces = new Collection<string, DocumentedInterface>();
public readonly typedefs = new Map<string, DocumentedTypeDef>();
public readonly typedefs = new Collection<string, DocumentedTypeDef>();
public readonly externals = new Map<string, DocumentedExternal>();
public readonly externals = new Collection<string, DocumentedExternal>();
public constructor(
data: RootTypes[] | DeclarationReflection[],
@@ -243,11 +244,11 @@ export class Documentation {
format: Documentation.FORMAT_VERSION,
date: Date.now(),
},
classes: [...this.classes.values()].map((c) => c.serialize()),
functions: [...this.functions.values()].map((f) => f.serialize()),
interfaces: [...this.interfaces.values()].map((i) => i.serialize()),
typedefs: [...this.typedefs.values()].map((t) => t.serialize()),
externals: [...this.externals.values()].map((e) => e.serialize()),
classes: this.classes.map((c) => c.serialize()),
functions: this.functions.map((f) => f.serialize()),
interfaces: this.interfaces.map((i) => i.serialize()),
typedefs: this.typedefs.map((t) => t.serialize()),
externals: this.externals.map((e) => e.serialize()),
custom: this.custom,
};
}

View File

@@ -1,10 +1,20 @@
#!/usr/bin/env node
import { readFileSync, writeFileSync } from 'node:fs';
import { dirname, join, extname, basename, relative } from 'node:path';
import { join, basename, extname, dirname, relative } from 'node:path';
import { createCommand } from 'commander';
import jsdoc2md from 'jsdoc-to-markdown';
import { type DeclarationReflection, Application, TSConfigReader } from 'typedoc';
import type { CLIOptions } from './cli';
import { Documentation } from './documentation';
import type { RootTypes, ChildTypes, CustomDocs } from './interfaces';
import { Application, DeclarationReflection, TSConfigReader } from 'typedoc';
import { Documentation } from './documentation.js';
import type { ChildTypes, CustomDocs, RootTypes } from './interfaces/index.js';
import packageFile from '../package.json';
interface CLIOptions {
input: string[];
custom: string;
root: string;
output: string;
typescript: boolean;
}
interface CustomFiles {
id?: string;
@@ -17,70 +27,79 @@ interface CustomFiles {
}[];
}
export function build({ input, custom: customDocs, root, output, typescript }: CLIOptions) {
let data: (RootTypes & ChildTypes)[] | DeclarationReflection[] = [];
if (typescript) {
console.log('Parsing Typescript in source files...');
const app = new Application();
app.options.addReader(new TSConfigReader());
app.bootstrap({ entryPoints: input });
const project = app.convert();
if (project) {
// @ts-expect-error
data = app.serializer.toObject(project).children!;
console.log(`${data.length} items parsed.`);
}
} else {
console.log('Parsing JSDocs in source files...');
data = jsdoc2md.getTemplateDataSync({ files: input }) as (RootTypes & ChildTypes)[];
console.log(`${data.length} JSDoc items parsed.`);
const command = createCommand()
.version(packageFile.version)
.option('-i, --input <string...>', 'Source directories to parse JSDocs in')
.option('-c, --custom <string>', 'Custom docs definition file to use')
.option('-r, --root [string]', 'Root directory of the project', '.')
.option('-o, --output <string>', 'Path to output file')
.option('--typescript', '', false);
const program = command.parse(process.argv);
const options = program.opts<CLIOptions>();
let data: (RootTypes & ChildTypes)[] | DeclarationReflection[] = [];
if (options.typescript) {
console.log('Parsing Typescript in source files...');
const app = new Application();
app.options.addReader(new TSConfigReader());
app.bootstrap({ entryPoints: options.input });
const project = app.convert();
if (project) {
// @ts-expect-error
data = app.serializer.toObject(project).children!;
console.log(`${data.length} items parsed.`);
}
const custom: Record<string, CustomDocs> = {};
if (customDocs) {
console.log('Loading custom docs files...');
const customDir = dirname(customDocs);
const file = readFileSync(customDocs, 'utf-8');
const data = JSON.parse(file) as CustomFiles[];
for (const category of data) {
const categoryId = category.id ?? category.name.toLowerCase();
const dir = join(customDir, category.path ?? categoryId);
custom[categoryId] = {
name: category.name || category.id!,
files: {},
};
for (const f of category.files) {
const fileRootPath = join(dir, f.path);
const extension = extname(f.path);
const fileId = f.id ?? basename(f.path, extension);
const fileData = readFileSync(fileRootPath, 'utf-8');
custom[categoryId]!.files[fileId] = {
name: f.name,
type: extension.toLowerCase().replace(/^\./, ''),
content: fileData,
path: relative(root, fileRootPath).replace(/\\/g, '/'),
};
}
}
const fileCount = Object.keys(custom)
.map((k) => Object.keys(custom[k]!))
.reduce((prev, c) => prev + c.length, 0);
const categoryCount = Object.keys(custom).length;
console.log(
`${fileCount} custom docs file${fileCount === 1 ? '' : 's'} in ` +
`${categoryCount} categor${categoryCount === 1 ? 'y' : 'ies'} loaded.`,
);
}
console.log(`Serializing documentation with format version ${Documentation.FORMAT_VERSION}...`);
const docs = new Documentation(data, { input, custom: customDocs, root, output, typescript }, custom);
if (output) {
console.log(`Writing to ${output}...`);
writeFileSync(output, JSON.stringify(docs.serialize()));
}
console.log('Done!');
} else {
console.log('Parsing JSDocs in source files...');
data = jsdoc2md.getTemplateDataSync({ files: options.input }) as (RootTypes & ChildTypes)[];
console.log(`${data.length} JSDoc items parsed.`);
}
const custom: Record<string, CustomDocs> = {};
if (options.custom) {
console.log('Loading custom docs files...');
const customDir = dirname(options.custom);
const file = readFileSync(options.custom, 'utf-8');
const data = JSON.parse(file) as CustomFiles[];
for (const category of data) {
const categoryId = category.id ?? category.name.toLowerCase();
const dir = join(customDir, category.path ?? categoryId);
custom[categoryId] = {
name: category.name || category.id!,
files: {},
};
for (const f of category.files) {
const fileRootPath = join(dir, f.path);
const extension = extname(f.path);
const fileId = f.id ?? basename(f.path, extension);
const fileData = readFileSync(fileRootPath, 'utf-8');
custom[categoryId]!.files[fileId] = {
name: f.name,
type: extension.toLowerCase().replace(/^\./, ''),
content: fileData,
path: relative(options.root, fileRootPath).replace(/\\/g, '/'),
};
}
}
const fileCount = Object.keys(custom)
.map((k) => Object.keys(custom[k]!))
.reduce((prev, c) => prev + c.length, 0);
const categoryCount = Object.keys(custom).length;
console.log(
`${fileCount} custom docs file${fileCount === 1 ? '' : 's'} in ` +
`${categoryCount} categor${categoryCount === 1 ? 'y' : 'ies'} loaded.`,
);
}
console.log(`Serializing documentation with format version ${Documentation.FORMAT_VERSION}...`);
const docs = new Documentation(data, options, custom);
if (options.output) {
console.log(`Writing to ${options.output}...`);
writeFileSync(options.output, JSON.stringify(docs.serialize()));
}
console.log('Done!');

View File

@@ -1,7 +1,7 @@
import type { Type } from './index.js';
export interface Return {
type: Required<Type>;
type: Type;
nullable?: boolean;
description?: string;
}

View File

@@ -1,3 +1,3 @@
export interface Type {
names?: string[] | undefined;
names?: string[];
}

View File

@@ -1,7 +1,7 @@
import type { Type } from './index.js';
export interface VarType extends Type {
type?: Required<Type> | undefined;
description?: string | undefined;
nullable?: boolean | undefined;
type?: Required<Type>;
description?: string;
nullable?: boolean;
}

View File

@@ -1,4 +1,5 @@
import { parse } from 'node:path';
import { Collection } from '@discordjs/collection';
import type { DeclarationReflection } from 'typedoc';
import { DocumentedConstructor } from './constructor.js';
import { DocumentedEvent } from './event.js';
@@ -11,11 +12,11 @@ import type { Class, Config } from '../interfaces/index.js';
import { parseType } from '../util/parseType.js';
export class DocumentedClass extends DocumentedItem<Class | DeclarationReflection> {
public readonly props = new Map<string, DocumentedMember>();
public readonly props = new Collection<string, DocumentedMember>();
public readonly methods = new Map<string, DocumentedMethod>();
public readonly methods = new Collection<string, DocumentedMethod>();
public readonly events = new Map<string, DocumentedEvent>();
public readonly events = new Collection<string, DocumentedEvent>();
public construct: DocumentedConstructor | null = null;
@@ -119,9 +120,9 @@ export class DocumentedClass extends DocumentedItem<Class | DeclarationReflectio
.trim() ?? true
: undefined,
construct: this.construct?.serialize(),
props: this.props.size ? [...this.props.values()].map((p) => p.serialize()) : undefined,
methods: this.methods.size ? [...this.methods.values()].map((m) => m.serialize()) : undefined,
events: this.events.size ? [...this.events.values()].map((e) => e.serialize()) : undefined,
props: this.props.size ? this.props.map((p) => p.serialize()) : undefined,
methods: this.methods.size ? this.methods.map((m) => m.serialize()) : undefined,
events: this.events.size ? this.events.map((e) => e.serialize()) : undefined,
meta,
};
}
@@ -137,9 +138,9 @@ export class DocumentedClass extends DocumentedItem<Class | DeclarationReflectio
abstract: data.virtual,
deprecated: data.deprecated,
construct: this.construct?.serialize(),
props: this.props.size ? [...this.props.values()].map((p) => p.serialize()) : undefined,
methods: this.methods.size ? [...this.methods.values()].map((m) => m.serialize()) : undefined,
events: this.events.size ? [...this.events.values()].map((e) => e.serialize()) : undefined,
props: this.props.size ? this.props.map((p) => p.serialize()) : undefined,
methods: this.methods.size ? this.methods.map((m) => m.serialize()) : undefined,
events: this.events.size ? this.events.map((e) => e.serialize()) : undefined,
meta: new DocumentedItemMeta(data.meta, this.config).serialize(),
};
}

View File

@@ -0,0 +1,5 @@
import { createTsupConfig } from '../../tsup.config';
export default createTsupConfig({
minify: true,
});

View File

@@ -3,7 +3,7 @@ FROM node:16-alpine
WORKDIR /usr/proxy
# First copy over dependencies separate from src for better caching
COPY package.json yarn.lock tsconfig.json .yarnrc.yml build.config.ts ./
COPY package.json yarn.lock tsconfig.json .yarnrc.yml tsup.config.ts ./
COPY .yarn ./.yarn
COPY ./packages/proxy-container/package.json ./packages/proxy-container/

View File

@@ -60,5 +60,5 @@ filter_commits = true
tag_pattern = "@discordjs\\/proxy-container@.*"
skip_tags = "v[0-9]*|11|12"
ignore_tags = ""
date_order = true
topo_order = false
sort_commits = "newest"

View File

@@ -4,8 +4,8 @@
"description": "Lightweight HTTP proxy for Discord's API, brought to you as a container 📦",
"scripts": {
"build": "unbuild",
"lint": "prettier --check . && TIMING=1 eslint src --ext mjs,js,ts",
"format": "prettier --write . && TIMING=1 eslint src --ext mjs,js,ts --fix",
"lint": "prettier --check . && eslint src --ext mjs,js,ts",
"format": "prettier --write . && eslint src --ext mjs,js,ts --fix",
"fmt": "yarn format",
"prepack": "yarn lint && yarn test && yarn build",
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/proxy-container/*'"
@@ -49,18 +49,13 @@
"tslib": "^2.4.0"
},
"devDependencies": {
"@types/node": "^16.11.52",
"@typescript-eslint/eslint-plugin": "^5.33.1",
"@typescript-eslint/parser": "^5.33.1",
"eslint": "^8.22.0",
"eslint-config-marine": "^9.4.1",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-typescript": "^3.4.2",
"eslint-plugin-import": "^2.26.0",
"@types/node": "^16.11.45",
"eslint": "^8.20.0",
"prettier": "^2.7.1",
"rollup-plugin-typescript2": "^0.33.0",
"rollup-plugin-typescript2": "0.32.1",
"tsup": "^6.2.0",
"typescript": "^4.7.4",
"unbuild": "^0.8.9"
"unbuild": "^0.7.6"
},
"engines": {
"node": ">=16.9.0"

View File

@@ -0,0 +1,4 @@
import { createTsupConfig } from '../../tsup.config';
// TODO: Set options to bundle node_modules - making the Docker image smaller
export default createTsupConfig({ minify: true, dts: false });

View File

@@ -1,7 +1,3 @@
{
"extends": "../../.eslintrc.json",
"plugins": ["eslint-plugin-tsdoc"],
"rules": {
"tsdoc/syntax": "warn"
}
"extends": "../../.eslintrc.json"
}

View File

@@ -5,4 +5,5 @@ dist/
docs/**/*
!docs/index.yml
!docs/README.md
coverage/
coverage/
tsup.config.*.mjs

View File

@@ -2,7 +2,7 @@
All notable changes to this project will be documented in this file.
# [@discordjs/proxy@1.0.0](https://github.com/discordjs/discord.js/tree/@discordjs/proxy@1.1.0) - (2022-07-17)
# [@discordjs/proxy@1.1.0](https://github.com/discordjs/discord.js/tree/@discordjs/proxy@1.1.0) - (2022-07-17)
## Bug Fixes

View File

@@ -60,5 +60,5 @@ filter_commits = true
tag_pattern = "@discordjs\\/proxy@.*"
skip_tags = "v[0-9]*|11|12"
ignore_tags = ""
date_order = true
topo_order = false
sort_commits = "newest"

View File

@@ -1,12 +1,12 @@
{
"name": "@discordjs/proxy",
"version": "1.0.1",
"version": "1.0.0",
"description": "Tools for running an HTTP proxy for Discord's API",
"scripts": {
"test": "vitest run",
"build": "unbuild",
"lint": "prettier --check . && TIMING=1 eslint src __tests__ --ext mjs,js,ts",
"format": "prettier --write . && TIMING=1 eslint src __tests__ --ext mjs,js,ts --fix",
"lint": "prettier --check . && eslint src __tests__ --ext mjs,js,ts",
"format": "prettier --write . && eslint src __tests__ --ext mjs,js,ts --fix",
"fmt": "yarn format",
"docs": "downlevel-dts . docs --to=3.7 && docgen -i src/index.ts -c docs/index.json -o docs/docs.json --typescript && api-extractor run --local",
"prepack": "yarn lint && yarn test && yarn build",
@@ -56,29 +56,24 @@
"dependencies": {
"@discordjs/rest": "^1.0.0",
"tslib": "^2.4.0",
"undici": "^5.9.1"
"undici": "^5.8.0"
},
"devDependencies": {
"@discordjs/docgen": "workspace:^",
"@favware/cliff-jumper": "^1.8.7",
"@microsoft/api-extractor": "^7.29.3",
"@types/node": "^16.11.52",
"@favware/cliff-jumper": "^1.8.5",
"@microsoft/api-extractor": "^7.28.6",
"@types/node": "^16.11.45",
"@types/supertest": "^2.0.12",
"@typescript-eslint/eslint-plugin": "^5.33.1",
"@typescript-eslint/parser": "^5.33.1",
"@vitest/coverage-c8": "^0.22.1",
"c8": "^7.12.0",
"downlevel-dts": "^0.10.0",
"eslint": "^8.22.0",
"eslint-config-marine": "^9.4.1",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-typescript": "^3.4.2",
"eslint-plugin-import": "^2.26.0",
"eslint": "^8.20.0",
"prettier": "^2.7.1",
"rollup-plugin-typescript2": "^0.33.0",
"rollup-plugin-typescript2": "0.32.1",
"supertest": "^6.2.4",
"tsup": "^6.2.0",
"typescript": "^4.7.4",
"unbuild": "^0.8.9",
"vitest": "^0.22.1"
"unbuild": "^0.7.6",
"vitest": "^0.19.1"
},
"engines": {
"node": ">=16.9.0"

View File

@@ -19,7 +19,7 @@ export function proxyRequests(rest: REST): RequestHandler {
if (!method || !url) {
throw new TypeError(
'Invalid request. Missing method and/or url, implying that this is not a Server IncomingMessage',
'Invalid request. Missing method and/or url, implying that this is not a Server IncomingMesage',
);
}

View File

@@ -1,4 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"exactOptionalPropertyTypes": false
},
"include": ["src/**/*.ts"]
}

View File

@@ -0,0 +1,3 @@
import { createTsupConfig } from '../../tsup.config';
export default createTsupConfig();

View File

@@ -1,7 +1,3 @@
{
"extends": "../../.eslintrc.json",
"plugins": ["eslint-plugin-tsdoc"],
"rules": {
"tsdoc/syntax": "warn"
}
"extends": "../../.eslintrc.json"
}

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