mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-13 18:13:29 +01:00
ci: api-extractor support for docs
This commit is contained in:
376
packages/rest/api-extractor.json
Normal file
376
packages/rest/api-extractor.json
Normal file
@@ -0,0 +1,376 @@
|
||||
/**
|
||||
* Config file for API Extractor. For more info, please visit: https://api-extractor.com
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
||||
|
||||
/**
|
||||
* Optionally specifies another JSON config file that this file extends from. This provides a way for
|
||||
* standard settings to be shared across multiple projects.
|
||||
*
|
||||
* If the path starts with "./" or "../", the path is resolved relative to the folder of the file that contains
|
||||
* the "extends" field. Otherwise, the first path segment is interpreted as an NPM package name, and will be
|
||||
* resolved using NodeJS require().
|
||||
*
|
||||
* SUPPORTED TOKENS: none
|
||||
* DEFAULT VALUE: ""
|
||||
*/
|
||||
// "extends": "./shared/api-extractor-base.json"
|
||||
// "extends": "my-package/include/api-extractor-base.json"
|
||||
|
||||
/**
|
||||
* Determines the "<projectFolder>" token that can be used with other config file settings. The project folder
|
||||
* typically contains the tsconfig.json and package.json config files, but the path is user-defined.
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting.
|
||||
*
|
||||
* The default value for "projectFolder" is the token "<lookup>", which means the folder is determined by traversing
|
||||
* parent folders, starting from the folder containing api-extractor.json, and stopping at the first folder
|
||||
* that contains a tsconfig.json file. If a tsconfig.json file cannot be found in this way, then an error
|
||||
* will be reported.
|
||||
*
|
||||
* SUPPORTED TOKENS: <lookup>
|
||||
* DEFAULT VALUE: "<lookup>"
|
||||
*/
|
||||
// "projectFolder": "..",
|
||||
|
||||
/**
|
||||
* (REQUIRED) Specifies the .d.ts file to be used as the starting point for analysis. API Extractor
|
||||
* analyzes the symbols exported by this module.
|
||||
*
|
||||
* The file extension must be ".d.ts" and not ".ts".
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
*/
|
||||
"mainEntryPointFilePath": "<projectFolder>/dist/index.d.ts",
|
||||
|
||||
/**
|
||||
* A list of NPM package names whose exports should be treated as part of this package.
|
||||
*
|
||||
* For example, suppose that Webpack is used to generate a distributed bundle for the project "library1",
|
||||
* and another NPM package "library2" is embedded in this bundle. Some types from library2 may become part
|
||||
* of the exported API for library1, but by default API Extractor would generate a .d.ts rollup that explicitly
|
||||
* imports library2. To avoid this, we can specify:
|
||||
*
|
||||
* "bundledPackages": [ "library2" ],
|
||||
*
|
||||
* This would direct API Extractor to embed those types directly in the .d.ts rollup, as if they had been
|
||||
* local files for library1.
|
||||
*/
|
||||
"bundledPackages": [],
|
||||
|
||||
/**
|
||||
* Determines how the TypeScript compiler engine will be invoked by API Extractor.
|
||||
*/
|
||||
"compiler": {
|
||||
/**
|
||||
* Specifies the path to the tsconfig.json file to be used by API Extractor when analyzing the project.
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* Note: This setting will be ignored if "overrideTsconfig" is used.
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: "<projectFolder>/tsconfig.json"
|
||||
*/
|
||||
// "tsconfigFilePath": "<projectFolder>/tsconfig.json",
|
||||
/**
|
||||
* Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk.
|
||||
* The object must conform to the TypeScript tsconfig schema:
|
||||
*
|
||||
* http://json.schemastore.org/tsconfig
|
||||
*
|
||||
* If omitted, then the tsconfig.json file will be read from the "projectFolder".
|
||||
*
|
||||
* DEFAULT VALUE: no overrideTsconfig section
|
||||
*/
|
||||
// "overrideTsconfig": {
|
||||
// . . .
|
||||
// }
|
||||
/**
|
||||
* This option causes the compiler to be invoked with the --skipLibCheck option. This option is not recommended
|
||||
* and may cause API Extractor to produce incomplete or incorrect declarations, but it may be required when
|
||||
* dependencies contain declarations that are incompatible with the TypeScript engine that API Extractor uses
|
||||
* for its analysis. Where possible, the underlying issue should be fixed rather than relying on skipLibCheck.
|
||||
*
|
||||
* DEFAULT VALUE: false
|
||||
*/
|
||||
// "skipLibCheck": true,
|
||||
},
|
||||
|
||||
/**
|
||||
* Configures how the API report file (*.api.md) will be generated.
|
||||
*/
|
||||
"apiReport": {
|
||||
/**
|
||||
* (REQUIRED) Whether to generate an API report.
|
||||
*/
|
||||
"enabled": false
|
||||
|
||||
/**
|
||||
* The filename for the API report files. It will be combined with "reportFolder" or "reportTempFolder" to produce
|
||||
* a full file path.
|
||||
*
|
||||
* The file extension should be ".api.md", and the string should not contain a path separator such as "\" or "/".
|
||||
*
|
||||
* SUPPORTED TOKENS: <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: "<unscopedPackageName>.api.md"
|
||||
*/
|
||||
// "reportFileName": "<unscopedPackageName>.api.md",
|
||||
|
||||
/**
|
||||
* Specifies the folder where the API report file is written. The file name portion is determined by
|
||||
* the "reportFileName" setting.
|
||||
*
|
||||
* The API report file is normally tracked by Git. Changes to it can be used to trigger a branch policy,
|
||||
* e.g. for an API review.
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: "<projectFolder>/temp/"
|
||||
*/
|
||||
// "reportFolder": "<projectFolder>/temp/",
|
||||
|
||||
/**
|
||||
* Specifies the folder where the temporary report file is written. The file name portion is determined by
|
||||
* the "reportFileName" setting.
|
||||
*
|
||||
* After the temporary file is written to disk, it is compared with the file in the "reportFolder".
|
||||
* If they are different, a production build will fail.
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: "<projectFolder>/temp/"
|
||||
*/
|
||||
// "reportTempFolder": "<projectFolder>/temp/"
|
||||
},
|
||||
|
||||
/**
|
||||
* Configures how the doc model file (*.api.json) will be generated.
|
||||
*/
|
||||
"docModel": {
|
||||
/**
|
||||
* (REQUIRED) Whether to generate a doc model file.
|
||||
*/
|
||||
"enabled": true,
|
||||
|
||||
/**
|
||||
* The output path for the doc model file. The file extension should be ".api.json".
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: "<projectFolder>/temp/<unscopedPackageName>.api.json"
|
||||
*/
|
||||
"apiJsonFilePath": "<projectFolder>/docs/docs.api.json"
|
||||
},
|
||||
|
||||
/**
|
||||
* Configures how the .d.ts rollup file will be generated.
|
||||
*/
|
||||
"dtsRollup": {
|
||||
/**
|
||||
* (REQUIRED) Whether to generate the .d.ts rollup file.
|
||||
*/
|
||||
"enabled": false
|
||||
|
||||
/**
|
||||
* Specifies the output path for a .d.ts rollup file to be generated without any trimming.
|
||||
* This file will include all declarations that are exported by the main entry point.
|
||||
*
|
||||
* If the path is an empty string, then this file will not be written.
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: "<projectFolder>/dist/<unscopedPackageName>.d.ts"
|
||||
*/
|
||||
// "untrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>.d.ts",
|
||||
|
||||
/**
|
||||
* Specifies the output path for a .d.ts rollup file to be generated with trimming for an "alpha" release.
|
||||
* This file will include only declarations that are marked as "@public", "@beta", or "@alpha".
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: ""
|
||||
*/
|
||||
// "alphaTrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>-alpha.d.ts",
|
||||
|
||||
/**
|
||||
* Specifies the output path for a .d.ts rollup file to be generated with trimming for a "beta" release.
|
||||
* This file will include only declarations that are marked as "@public" or "@beta".
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: ""
|
||||
*/
|
||||
// "betaTrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>-beta.d.ts",
|
||||
|
||||
/**
|
||||
* Specifies the output path for a .d.ts rollup file to be generated with trimming for a "public" release.
|
||||
* This file will include only declarations that are marked as "@public".
|
||||
*
|
||||
* If the path is an empty string, then this file will not be written.
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: ""
|
||||
*/
|
||||
// "publicTrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>-public.d.ts",
|
||||
|
||||
/**
|
||||
* When a declaration is trimmed, by default it will be replaced by a code comment such as
|
||||
* "Excluded from this release type: exampleMember". Set "omitTrimmingComments" to true to remove the
|
||||
* declaration completely.
|
||||
*
|
||||
* DEFAULT VALUE: false
|
||||
*/
|
||||
// "omitTrimmingComments": true
|
||||
},
|
||||
|
||||
/**
|
||||
* Configures how the tsdoc-metadata.json file will be generated.
|
||||
*/
|
||||
"tsdocMetadata": {
|
||||
/**
|
||||
* Whether to generate the tsdoc-metadata.json file.
|
||||
*
|
||||
* DEFAULT VALUE: true
|
||||
*/
|
||||
// "enabled": true,
|
||||
/**
|
||||
* Specifies where the TSDoc metadata file should be written.
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* The default value is "<lookup>", which causes the path to be automatically inferred from the "tsdocMetadata",
|
||||
* "typings" or "main" fields of the project's package.json. If none of these fields are set, the lookup
|
||||
* falls back to "tsdoc-metadata.json" in the package folder.
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: "<lookup>"
|
||||
*/
|
||||
// "tsdocMetadataFilePath": "<projectFolder>/dist/tsdoc-metadata.json"
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies what type of newlines API Extractor should use when writing output files. By default, the output files
|
||||
* will be written with Windows-style newlines. To use POSIX-style newlines, specify "lf" instead.
|
||||
* To use the OS's default newline kind, specify "os".
|
||||
*
|
||||
* DEFAULT VALUE: "crlf"
|
||||
*/
|
||||
"newlineKind": "lf",
|
||||
|
||||
/**
|
||||
* Configures how API Extractor reports error and warning messages produced during analysis.
|
||||
*
|
||||
* There are three sources of messages: compiler messages, API Extractor messages, and TSDoc messages.
|
||||
*/
|
||||
"messages": {
|
||||
/**
|
||||
* Configures handling of diagnostic messages reported by the TypeScript compiler engine while analyzing
|
||||
* the input .d.ts files.
|
||||
*
|
||||
* TypeScript message identifiers start with "TS" followed by an integer. For example: "TS2551"
|
||||
*
|
||||
* DEFAULT VALUE: A single "default" entry with logLevel=warning.
|
||||
*/
|
||||
"compilerMessageReporting": {
|
||||
/**
|
||||
* Configures the default routing for messages that don't match an explicit rule in this table.
|
||||
*/
|
||||
"default": {
|
||||
/**
|
||||
* Specifies whether the message should be written to the the tool's output log. Note that
|
||||
* the "addToApiReportFile" property may supersede this option.
|
||||
*
|
||||
* Possible values: "error", "warning", "none"
|
||||
*
|
||||
* Errors cause the build to fail and return a nonzero exit code. Warnings cause a production build fail
|
||||
* and return a nonzero exit code. For a non-production build (e.g. when "api-extractor run" includes
|
||||
* the "--local" option), the warning is displayed but the build will not fail.
|
||||
*
|
||||
* DEFAULT VALUE: "warning"
|
||||
*/
|
||||
"logLevel": "warning"
|
||||
|
||||
/**
|
||||
* When addToApiReportFile is true: If API Extractor is configured to write an API report file (.api.md),
|
||||
* then the message will be written inside that file; otherwise, the message is instead logged according to
|
||||
* the "logLevel" option.
|
||||
*
|
||||
* DEFAULT VALUE: false
|
||||
*/
|
||||
// "addToApiReportFile": false
|
||||
}
|
||||
|
||||
// "TS2551": {
|
||||
// "logLevel": "warning",
|
||||
// "addToApiReportFile": true
|
||||
// },
|
||||
//
|
||||
// . . .
|
||||
},
|
||||
|
||||
/**
|
||||
* Configures handling of messages reported by API Extractor during its analysis.
|
||||
*
|
||||
* API Extractor message identifiers start with "ae-". For example: "ae-extra-release-tag"
|
||||
*
|
||||
* DEFAULT VALUE: See api-extractor-defaults.json for the complete table of extractorMessageReporting mappings
|
||||
*/
|
||||
"extractorMessageReporting": {
|
||||
"default": {
|
||||
"logLevel": "warning"
|
||||
// "addToApiReportFile": false
|
||||
}
|
||||
|
||||
// "ae-extra-release-tag": {
|
||||
// "logLevel": "warning",
|
||||
// "addToApiReportFile": true
|
||||
// },
|
||||
//
|
||||
// . . .
|
||||
},
|
||||
|
||||
/**
|
||||
* Configures handling of messages reported by the TSDoc parser when analyzing code comments.
|
||||
*
|
||||
* TSDoc message identifiers start with "tsdoc-". For example: "tsdoc-link-tag-unescaped-text"
|
||||
*
|
||||
* DEFAULT VALUE: A single "default" entry with logLevel=warning.
|
||||
*/
|
||||
"tsdocMessageReporting": {
|
||||
"default": {
|
||||
"logLevel": "warning"
|
||||
// "addToApiReportFile": false
|
||||
}
|
||||
|
||||
// "tsdoc-link-tag-unescaped-text": {
|
||||
// "logLevel": "warning",
|
||||
// "addToApiReportFile": true
|
||||
// },
|
||||
//
|
||||
// . . .
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
"build": "tsup",
|
||||
"lint": "prettier --cache --check . && eslint src __tests__ --ext mjs,js,ts --cache",
|
||||
"format": "prettier --cache --write . && eslint src __tests__ --ext mjs,js,ts --fix --cache",
|
||||
"docs": "docgen -i src/index.ts -c docs/index.json -o docs/docs.json --typescript",
|
||||
"docs": "docgen -i src/index.ts -c docs/index.json -o docs/docs.json --typescript && api-extractor run --local",
|
||||
"prepack": "yarn build && yarn lint",
|
||||
"changelog": "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/rest/*'",
|
||||
"release": "cliff-jumper"
|
||||
@@ -61,6 +61,7 @@
|
||||
"@discordjs/docgen": "workspace:^",
|
||||
"@discordjs/scripts": "workspace:^",
|
||||
"@favware/cliff-jumper": "^1.8.3",
|
||||
"@microsoft/api-extractor": "^7.28.2",
|
||||
"eslint": "^8.18.0",
|
||||
"prettier": "^2.7.1",
|
||||
"tsup": "^6.1.2",
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
export interface BaseImageURLOptions {
|
||||
/**
|
||||
* The extension to use for the image URL
|
||||
*
|
||||
* @default 'webp'
|
||||
*/
|
||||
extension?: ImageExtension;
|
||||
@@ -39,6 +40,7 @@ export interface ImageURLOptions extends BaseImageURLOptions {
|
||||
export interface MakeURLOptions {
|
||||
/**
|
||||
* The extension to use for the image URL
|
||||
*
|
||||
* @default 'webp'
|
||||
*/
|
||||
extension?: string | undefined;
|
||||
@@ -60,9 +62,10 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates an app asset URL for a client's asset.
|
||||
* @param clientId The client id that has the asset
|
||||
* @param assetHash The hash provided by Discord for this asset
|
||||
* @param options Optional options for the asset
|
||||
*
|
||||
* @param clientId - The client id that has the asset
|
||||
* @param assetHash - The hash provided by Discord for this asset
|
||||
* @param options - Optional options for the asset
|
||||
*/
|
||||
public appAsset(clientId: string, assetHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/app-assets/${clientId}/${assetHash}`, options);
|
||||
@@ -70,9 +73,10 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates an app icon URL for a client's icon.
|
||||
* @param clientId The client id that has the icon
|
||||
* @param iconHash The hash provided by Discord for this icon
|
||||
* @param options Optional options for the icon
|
||||
*
|
||||
* @param clientId - The client id that has the icon
|
||||
* @param iconHash - The hash provided by Discord for this icon
|
||||
* @param options - Optional options for the icon
|
||||
*/
|
||||
public appIcon(clientId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/app-icons/${clientId}/${iconHash}`, options);
|
||||
@@ -80,9 +84,10 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates an avatar URL, e.g. for a user or a webhook.
|
||||
* @param id The id that has the icon
|
||||
* @param avatarHash The hash provided by Discord for this avatar
|
||||
* @param options Optional options for the avatar
|
||||
*
|
||||
* @param id - The id that has the icon
|
||||
* @param avatarHash - The hash provided by Discord for this avatar
|
||||
* @param options - Optional options for the avatar
|
||||
*/
|
||||
public avatar(id: string, avatarHash: string, options?: Readonly<ImageURLOptions>): string {
|
||||
return this.dynamicMakeURL(`/avatars/${id}/${avatarHash}`, avatarHash, options);
|
||||
@@ -90,9 +95,10 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates a banner URL, e.g. for a user or a guild.
|
||||
* @param id The id that has the banner splash
|
||||
* @param bannerHash The hash provided by Discord for this banner
|
||||
* @param options Optional options for the banner
|
||||
*
|
||||
* @param id - The id that has the banner splash
|
||||
* @param bannerHash - The hash provided by Discord for this banner
|
||||
* @param options - Optional options for the banner
|
||||
*/
|
||||
public banner(id: string, bannerHash: string, options?: Readonly<ImageURLOptions>): string {
|
||||
return this.dynamicMakeURL(`/banners/${id}/${bannerHash}`, bannerHash, options);
|
||||
@@ -100,9 +106,10 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates an icon URL for a channel, e.g. a group DM.
|
||||
* @param channelId The channel id that has the icon
|
||||
* @param iconHash The hash provided by Discord for this channel
|
||||
* @param options Optional options for the icon
|
||||
*
|
||||
* @param channelId - The channel id that has the icon
|
||||
* @param iconHash - The hash provided by Discord for this channel
|
||||
* @param options - Optional options for the icon
|
||||
*/
|
||||
public channelIcon(channelId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/channel-icons/${channelId}/${iconHash}`, options);
|
||||
@@ -110,7 +117,8 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates the default avatar URL for a discriminator.
|
||||
* @param discriminator The discriminator modulo 5
|
||||
*
|
||||
* @param discriminator - The discriminator modulo 5
|
||||
*/
|
||||
public defaultAvatar(discriminator: number): string {
|
||||
return this.makeURL(`/embed/avatars/${discriminator}`, { extension: 'png' });
|
||||
@@ -118,9 +126,10 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates a discovery splash URL for a guild's discovery splash.
|
||||
* @param guildId The guild id that has the discovery splash
|
||||
* @param splashHash The hash provided by Discord for this splash
|
||||
* @param options Optional options for the splash
|
||||
*
|
||||
* @param guildId - The guild id that has the discovery splash
|
||||
* @param splashHash - The hash provided by Discord for this splash
|
||||
* @param options - Optional options for the splash
|
||||
*/
|
||||
public discoverySplash(guildId: string, splashHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/discovery-splashes/${guildId}/${splashHash}`, options);
|
||||
@@ -128,8 +137,9 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates an emoji's URL for an emoji.
|
||||
* @param emojiId The emoji id
|
||||
* @param extension The extension of the emoji
|
||||
*
|
||||
* @param emojiId - The emoji id
|
||||
* @param extension - The extension of the emoji
|
||||
*/
|
||||
public emoji(emojiId: string, extension?: ImageExtension): string {
|
||||
return this.makeURL(`/emojis/${emojiId}`, { extension });
|
||||
@@ -137,10 +147,11 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates a guild member avatar URL.
|
||||
* @param guildId The id of the guild
|
||||
* @param userId The id of the user
|
||||
* @param avatarHash The hash provided by Discord for this avatar
|
||||
* @param options Optional options for the avatar
|
||||
*
|
||||
* @param guildId - The id of the guild
|
||||
* @param userId - The id of the user
|
||||
* @param avatarHash - The hash provided by Discord for this avatar
|
||||
* @param options - Optional options for the avatar
|
||||
*/
|
||||
public guildMemberAvatar(
|
||||
guildId: string,
|
||||
@@ -153,10 +164,11 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates a guild member banner URL.
|
||||
* @param guildId The id of the guild
|
||||
* @param userId The id of the user
|
||||
* @param bannerHash The hash provided by Discord for this banner
|
||||
* @param options Optional options for the banner
|
||||
*
|
||||
* @param guildId - The id of the guild
|
||||
* @param userId - The id of the user
|
||||
* @param bannerHash - The hash provided by Discord for this banner
|
||||
* @param options - Optional options for the banner
|
||||
*/
|
||||
public guildMemberBanner(
|
||||
guildId: string,
|
||||
@@ -169,9 +181,10 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates an icon URL, e.g. for a guild.
|
||||
* @param id The id that has the icon splash
|
||||
* @param iconHash The hash provided by Discord for this icon
|
||||
* @param options Optional options for the icon
|
||||
*
|
||||
* @param id - The id that has the icon splash
|
||||
* @param iconHash - The hash provided by Discord for this icon
|
||||
* @param options - Optional options for the icon
|
||||
*/
|
||||
public icon(id: string, iconHash: string, options?: Readonly<ImageURLOptions>): string {
|
||||
return this.dynamicMakeURL(`/icons/${id}/${iconHash}`, iconHash, options);
|
||||
@@ -179,9 +192,9 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates a URL for the icon of a role
|
||||
* @param roleId The id of the role that has the icon
|
||||
* @param roleIconHash The hash provided by Discord for this role icon
|
||||
* @param options Optional options for the role icon
|
||||
* @param roleId - The id of the role that has the icon
|
||||
* @param roleIconHash - The hash provided by Discord for this role icon
|
||||
* @param options - Optional options for the role icon
|
||||
*/
|
||||
public roleIcon(roleId: string, roleIconHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/role-icons/${roleId}/${roleIconHash}`, options);
|
||||
@@ -189,9 +202,10 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates a guild invite splash URL for a guild's invite splash.
|
||||
* @param guildId The guild id that has the invite splash
|
||||
* @param splashHash The hash provided by Discord for this splash
|
||||
* @param options Optional options for the splash
|
||||
*
|
||||
* @param guildId - The guild id that has the invite splash
|
||||
* @param splashHash - The hash provided by Discord for this splash
|
||||
* @param options - Optional options for the splash
|
||||
*/
|
||||
public splash(guildId: string, splashHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/splashes/${guildId}/${splashHash}`, options);
|
||||
@@ -199,8 +213,9 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates a sticker URL.
|
||||
* @param stickerId The sticker id
|
||||
* @param extension The extension of the sticker
|
||||
*
|
||||
* @param stickerId - The sticker id
|
||||
* @param extension - The extension of the sticker
|
||||
*/
|
||||
public sticker(stickerId: string, extension?: StickerExtension): string {
|
||||
return this.makeURL(`/stickers/${stickerId}`, {
|
||||
@@ -211,8 +226,9 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates a sticker pack banner URL.
|
||||
* @param bannerId The banner id
|
||||
* @param options Optional options for the banner
|
||||
*
|
||||
* @param bannerId - The banner id
|
||||
* @param options - Optional options for the banner
|
||||
*/
|
||||
public stickerPackBanner(bannerId: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/app-assets/710982414301790216/store/${bannerId}`, options);
|
||||
@@ -220,9 +236,10 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates a team icon URL for a team's icon.
|
||||
* @param teamId The team id that has the icon
|
||||
* @param iconHash The hash provided by Discord for this icon
|
||||
* @param options Optional options for the icon
|
||||
*
|
||||
* @param teamId - The team id that has the icon
|
||||
* @param iconHash - The hash provided by Discord for this icon
|
||||
* @param options - Optional options for the icon
|
||||
*/
|
||||
public teamIcon(teamId: string, iconHash: string, options?: Readonly<BaseImageURLOptions>): string {
|
||||
return this.makeURL(`/team-icons/${teamId}/${iconHash}`, options);
|
||||
@@ -230,9 +247,10 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Generates a cover image for a guild scheduled event.
|
||||
* @param scheduledEventId The scheduled event id
|
||||
* @param coverHash The hash provided by discord for this cover image
|
||||
* @param options Optional options for the cover image
|
||||
*
|
||||
* @param scheduledEventId - The scheduled event id
|
||||
* @param coverHash - The hash provided by discord for this cover image
|
||||
* @param options - Optional options for the cover image
|
||||
*/
|
||||
public guildScheduledEventCover(
|
||||
scheduledEventId: string,
|
||||
@@ -244,9 +262,10 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Constructs the URL for the resource, checking whether or not `hash` starts with `a_` if `dynamic` is set to `true`.
|
||||
* @param route The base cdn route
|
||||
* @param hash The hash provided by Discord for this icon
|
||||
* @param options Optional options for the link
|
||||
*
|
||||
* @param route - The base cdn route
|
||||
* @param hash - The hash provided by Discord for this icon
|
||||
* @param options - Optional options for the link
|
||||
*/
|
||||
private dynamicMakeURL(
|
||||
route: string,
|
||||
@@ -258,8 +277,9 @@ export class CDN {
|
||||
|
||||
/**
|
||||
* Constructs the URL for the resource
|
||||
* @param route The base cdn route
|
||||
* @param options The extension/size options for the link
|
||||
*
|
||||
* @param route - The base cdn route
|
||||
* @param options - The extension/size options for the link
|
||||
*/
|
||||
private makeURL(
|
||||
route: string,
|
||||
|
||||
@@ -31,32 +31,38 @@ export interface RESTOptions {
|
||||
/**
|
||||
* The authorization prefix to use for requests, useful if you want to use
|
||||
* bearer tokens
|
||||
*
|
||||
* @default 'Bot'
|
||||
*/
|
||||
authPrefix: 'Bot' | 'Bearer';
|
||||
/**
|
||||
* The cdn path
|
||||
*
|
||||
* @default 'https://cdn.discordapp.com'
|
||||
*/
|
||||
cdn: string;
|
||||
/**
|
||||
* Additional headers to send for all API requests
|
||||
*
|
||||
* @default {}
|
||||
*/
|
||||
headers: Record<string, string>;
|
||||
/**
|
||||
* The number of invalid REST requests (those that return 401, 403, or 429) in a 10 minute window between emitted warnings (0 for no warnings).
|
||||
* That is, if set to 500, warnings will be emitted at invalid request number 500, 1000, 1500, and so on.
|
||||
*
|
||||
* @default 0
|
||||
*/
|
||||
invalidRequestWarningInterval: number;
|
||||
/**
|
||||
* How many requests to allow sending per second (Infinity for unlimited, 50 for the standard global limit used by Discord)
|
||||
*
|
||||
* @default 50
|
||||
*/
|
||||
globalRequestsPerSecond: number;
|
||||
/**
|
||||
* The extra offset to add to rate limits in milliseconds
|
||||
*
|
||||
* @default 50
|
||||
*/
|
||||
offset: number;
|
||||
@@ -65,42 +71,50 @@ export interface RESTOptions {
|
||||
* When an array of strings, each element is treated as a prefix for the request route
|
||||
* (e.g. `/channels` to match any route starting with `/channels` such as `/channels/:id/messages`)
|
||||
* for which to throw {@link RateLimitError}s. All other request routes will be queued normally
|
||||
*
|
||||
* @default null
|
||||
*/
|
||||
rejectOnRateLimit: string[] | RateLimitQueueFilter | null;
|
||||
/**
|
||||
* The number of retries for errors with the 500 code, or errors
|
||||
* that timeout
|
||||
*
|
||||
* @default 3
|
||||
*/
|
||||
retries: number;
|
||||
/**
|
||||
* The time to wait in milliseconds before a request is aborted
|
||||
*
|
||||
* @default 15_000
|
||||
*/
|
||||
timeout: number;
|
||||
/**
|
||||
* Extra information to add to the user agent
|
||||
*
|
||||
* @default `Node.js ${process.version}`
|
||||
*/
|
||||
userAgentAppendix: string;
|
||||
/**
|
||||
* The version of the API to use
|
||||
*
|
||||
* @default '10'
|
||||
*/
|
||||
version: string;
|
||||
/**
|
||||
* The amount of time in milliseconds that passes between each hash sweep. (defaults to 4h)
|
||||
*
|
||||
* @default 14_400_000
|
||||
*/
|
||||
hashSweepInterval: number;
|
||||
/**
|
||||
* The maximum amount of time a hash can exist in milliseconds without being hit with a request (defaults to 24h)
|
||||
*
|
||||
* @default 86_400_000
|
||||
*/
|
||||
hashLifetime: number;
|
||||
/**
|
||||
* The amount of time in milliseconds that passes between each hash sweep. (defaults to 1h)
|
||||
*
|
||||
* @default 3_600_000
|
||||
*/
|
||||
handlerSweepInterval: number;
|
||||
@@ -250,7 +264,8 @@ export class REST extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Sets the default agent to use for requests performed by this instance
|
||||
* @param agent Sets the agent to use
|
||||
*
|
||||
* @param agent - Sets the agent to use
|
||||
*/
|
||||
public setAgent(agent: Dispatcher) {
|
||||
this.requestManager.setAgent(agent);
|
||||
@@ -259,7 +274,8 @@ export class REST extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Sets the authorization token that should be used for requests
|
||||
* @param token The authorization token to use
|
||||
*
|
||||
* @param token - The authorization token to use
|
||||
*/
|
||||
public setToken(token: string) {
|
||||
this.requestManager.setToken(token);
|
||||
@@ -268,8 +284,9 @@ export class REST extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Runs a get request from the api
|
||||
* @param fullRoute The full route to query
|
||||
* @param options Optional request options
|
||||
*
|
||||
* @param fullRoute - The full route to query
|
||||
* @param options - Optional request options
|
||||
*/
|
||||
public get(fullRoute: RouteLike, options: RequestData = {}) {
|
||||
return this.request({ ...options, fullRoute, method: RequestMethod.Get });
|
||||
@@ -277,8 +294,9 @@ export class REST extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Runs a delete request from the api
|
||||
* @param fullRoute The full route to query
|
||||
* @param options Optional request options
|
||||
*
|
||||
* @param fullRoute - The full route to query
|
||||
* @param options - Optional request options
|
||||
*/
|
||||
public delete(fullRoute: RouteLike, options: RequestData = {}) {
|
||||
return this.request({ ...options, fullRoute, method: RequestMethod.Delete });
|
||||
@@ -286,8 +304,9 @@ export class REST extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Runs a post request from the api
|
||||
* @param fullRoute The full route to query
|
||||
* @param options Optional request options
|
||||
*
|
||||
* @param fullRoute - The full route to query
|
||||
* @param options - Optional request options
|
||||
*/
|
||||
public post(fullRoute: RouteLike, options: RequestData = {}) {
|
||||
return this.request({ ...options, fullRoute, method: RequestMethod.Post });
|
||||
@@ -295,8 +314,9 @@ export class REST extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Runs a put request from the api
|
||||
* @param fullRoute The full route to query
|
||||
* @param options Optional request options
|
||||
*
|
||||
* @param fullRoute - The full route to query
|
||||
* @param options - Optional request options
|
||||
*/
|
||||
public put(fullRoute: RouteLike, options: RequestData = {}) {
|
||||
return this.request({ ...options, fullRoute, method: RequestMethod.Put });
|
||||
@@ -304,8 +324,9 @@ export class REST extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Runs a patch request from the api
|
||||
* @param fullRoute The full route to query
|
||||
* @param options Optional request options
|
||||
*
|
||||
* @param fullRoute - The full route to query
|
||||
* @param options - Optional request options
|
||||
*/
|
||||
public patch(fullRoute: RouteLike, options: RequestData = {}) {
|
||||
return this.request({ ...options, fullRoute, method: RequestMethod.Patch });
|
||||
@@ -313,7 +334,8 @@ export class REST extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Runs a request from the api
|
||||
* @param options Request options
|
||||
*
|
||||
* @param options - Request options
|
||||
*/
|
||||
public async request(options: InternalRequest) {
|
||||
const response = await this.raw(options);
|
||||
@@ -322,7 +344,8 @@ export class REST extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Runs a request from the API, yielding the raw Response object
|
||||
* @param options Request options
|
||||
*
|
||||
* @param options - Request options
|
||||
*/
|
||||
public raw(options: InternalRequest) {
|
||||
return this.requestManager.queueRequest(options);
|
||||
|
||||
@@ -39,11 +39,13 @@ export interface RequestData {
|
||||
appendToFormData?: boolean;
|
||||
/**
|
||||
* If this request needs the `Authorization` header
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
auth?: boolean;
|
||||
/**
|
||||
* The authorization prefix to use for this request, useful if you use this with bearer tokens
|
||||
*
|
||||
* @default 'Bot'
|
||||
*/
|
||||
authPrefix?: 'Bot' | 'Bearer';
|
||||
@@ -79,6 +81,7 @@ export interface RequestData {
|
||||
reason?: string;
|
||||
/**
|
||||
* If this request should be versioned
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
versioned?: boolean;
|
||||
@@ -273,7 +276,8 @@ export class RequestManager extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Sets the default agent to use for requests performed by this manager
|
||||
* @param agent The agent to use
|
||||
*
|
||||
* @param agent - The agent to use
|
||||
*/
|
||||
public setAgent(agent: Dispatcher) {
|
||||
this.agent = agent;
|
||||
@@ -282,7 +286,8 @@ export class RequestManager extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Sets the authorization token that should be used for requests
|
||||
* @param token The authorization token to use
|
||||
*
|
||||
* @param token - The authorization token to use
|
||||
*/
|
||||
public setToken(token: string) {
|
||||
this.#token = token;
|
||||
@@ -291,7 +296,9 @@ export class RequestManager extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Queues a request to be sent
|
||||
* @param request All the information needed to make a request
|
||||
*
|
||||
* @param request - All the information needed to make a request
|
||||
*
|
||||
* @returns The response from the api request
|
||||
*/
|
||||
public async queueRequest(request: InternalRequest): Promise<Dispatcher.ResponseData> {
|
||||
@@ -321,8 +328,10 @@ export class RequestManager extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Creates a new rate limit handler from a hash, based on the hash and the major parameter
|
||||
* @param hash The hash for the route
|
||||
* @param majorParameter The major parameter for this handler
|
||||
*
|
||||
* @param hash - The hash for the route
|
||||
* @param majorParameter - The major parameter for this handler
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private createHandler(hash: string, majorParameter: string) {
|
||||
@@ -336,7 +345,8 @@ export class RequestManager extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Formats the request data to a usable format for fetch
|
||||
* @param request The request data
|
||||
*
|
||||
* @param request - The request data
|
||||
*/
|
||||
private async resolveRequest(request: InternalRequest): Promise<{ url: string; fetchOptions: RequestOptions }> {
|
||||
const { options } = this;
|
||||
@@ -460,8 +470,10 @@ export class RequestManager extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Generates route data for an endpoint:method
|
||||
* @param endpoint The raw endpoint to generalize
|
||||
* @param method The HTTP method this endpoint is called without
|
||||
*
|
||||
* @param endpoint - The raw endpoint to generalize
|
||||
* @param method - The HTTP method this endpoint is called without
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private static generateRouteData(endpoint: RouteLike, method: RequestMethod): RouteData {
|
||||
|
||||
@@ -43,12 +43,12 @@ export class DiscordAPIError extends Error {
|
||||
public requestBody: RequestBody;
|
||||
|
||||
/**
|
||||
* @param rawError The error reported by Discord
|
||||
* @param code The error code reported by Discord
|
||||
* @param status The status code of the response
|
||||
* @param method The method of the request that erred
|
||||
* @param url The url of the request that erred
|
||||
* @param bodyData The unparsed data for the request that errored
|
||||
* @param rawError - The error reported by Discord
|
||||
* @param code - The error code reported by Discord
|
||||
* @param status - The status code of the response
|
||||
* @param method - The method of the request that erred
|
||||
* @param url - The url of the request that erred
|
||||
* @param bodyData - The unparsed data for the request that errored
|
||||
*/
|
||||
public constructor(
|
||||
public rawError: DiscordErrorData | OAuthErrorData,
|
||||
|
||||
@@ -8,11 +8,11 @@ export class HTTPError extends Error {
|
||||
public requestBody: RequestBody;
|
||||
|
||||
/**
|
||||
* @param name The name of the error
|
||||
* @param status The status code of the response
|
||||
* @param method The method of the request that erred
|
||||
* @param url The url of the request that erred
|
||||
* @param bodyData The unparsed data for the request that errored
|
||||
* @param name - The name of the error
|
||||
* @param status - The status code of the response
|
||||
* @param method - The method of the request that erred
|
||||
* @param url - The url of the request that erred
|
||||
* @param bodyData - The unparsed data for the request that errored
|
||||
*/
|
||||
public constructor(
|
||||
public override name: string,
|
||||
|
||||
@@ -10,7 +10,8 @@ import { RateLimitError } from '../errors/RateLimitError';
|
||||
import { RESTEvents } from '../utils/constants';
|
||||
import { hasSublimit, parseHeader, parseResponse } from '../utils/utils';
|
||||
|
||||
/* Invalid request limiting is done on a per-IP basis, not a per-token basis.
|
||||
/**
|
||||
* Invalid request limiting is done on a per-IP basis, not a per-token basis.
|
||||
* The best we can do is track invalid counts process-wide (on the theory that
|
||||
* users could have multiple bots run from one process) rather than per-bot.
|
||||
* Therefore, store these at file scope here rather than in the client's
|
||||
@@ -73,9 +74,9 @@ export class SequentialHandler implements IHandler {
|
||||
#shiftSublimit = false;
|
||||
|
||||
/**
|
||||
* @param manager The request manager
|
||||
* @param hash The hash that this RequestHandler handles
|
||||
* @param majorParameter The major parameter for this handler
|
||||
* @param manager - The request manager
|
||||
* @param hash - The hash that this RequestHandler handles
|
||||
* @param majorParameter - The major parameter for this handler
|
||||
*/
|
||||
public constructor(
|
||||
private readonly manager: RequestManager,
|
||||
@@ -126,7 +127,8 @@ export class SequentialHandler implements IHandler {
|
||||
|
||||
/**
|
||||
* Emits a debug message
|
||||
* @param message The message to debug
|
||||
*
|
||||
* @param message - The message to debug
|
||||
*/
|
||||
private debug(message: string) {
|
||||
this.manager.emit(RESTEvents.Debug, `[REST ${this.id}] ${message}`);
|
||||
@@ -134,8 +136,8 @@ export class SequentialHandler implements IHandler {
|
||||
|
||||
/**
|
||||
* Delay all requests for the specified amount of time, handling global rate limits
|
||||
* @param time The amount of time to delay all requests for
|
||||
* @returns
|
||||
*
|
||||
* @param time - The amount of time to delay all requests for
|
||||
*/
|
||||
private async globalDelayFor(time: number): Promise<void> {
|
||||
await sleep(time, undefined, { ref: false });
|
||||
@@ -160,10 +162,11 @@ export class SequentialHandler implements IHandler {
|
||||
|
||||
/**
|
||||
* Queues a request to be sent
|
||||
* @param routeId The generalized api route with literal ids for major parameters
|
||||
* @param url The url to do the request on
|
||||
* @param options All the information needed to make a request
|
||||
* @param requestData Extra data from the user's request needed for errors and additional processing
|
||||
*
|
||||
* @param routeId - The generalized api route with literal ids for major parameters
|
||||
* @param url - The url to do the request on
|
||||
* @param options - All the information needed to make a request
|
||||
* @param requestData - Extra data from the user's request needed for errors and additional processing
|
||||
*/
|
||||
public async queueRequest(
|
||||
routeId: RouteData,
|
||||
@@ -216,11 +219,12 @@ export class SequentialHandler implements IHandler {
|
||||
|
||||
/**
|
||||
* The method that actually makes the request to the api, and updates info about the bucket accordingly
|
||||
* @param routeId The generalized api route with literal ids for major parameters
|
||||
* @param url The fully resolved url to make the request to
|
||||
* @param options The fetch options needed to make the request
|
||||
* @param requestData Extra data from the user's request needed for errors and additional processing
|
||||
* @param retries The number of retries this request has already attempted (recursion)
|
||||
*
|
||||
* @param routeId - The generalized api route with literal ids for major parameters
|
||||
* @param url - The fully resolved url to make the request to
|
||||
* @param options - The fetch options needed to make the request
|
||||
* @param requestData - Extra data from the user's request needed for errors and additional processing
|
||||
* @param retries - The number of retries this request has already attempted (recursion)
|
||||
*/
|
||||
private async runRequest(
|
||||
routeId: RouteData,
|
||||
|
||||
@@ -40,7 +40,9 @@ function serializeSearchParam(value: unknown): string | null {
|
||||
/**
|
||||
* Creates and populates an URLSearchParams instance from an object, stripping
|
||||
* out null and undefined values, while also coercing non-strings to strings.
|
||||
* @param options The options to use
|
||||
*
|
||||
* @param options - The options to use
|
||||
*
|
||||
* @returns A populated URLSearchParams instance
|
||||
*/
|
||||
export function makeURLSearchParams(options?: Record<string, unknown>) {
|
||||
@@ -57,7 +59,8 @@ export function makeURLSearchParams(options?: Record<string, unknown>) {
|
||||
|
||||
/**
|
||||
* Converts the response to usable data
|
||||
* @param res The fetch response
|
||||
*
|
||||
* @param res - The fetch response
|
||||
*/
|
||||
export function parseResponse(res: Dispatcher.ResponseData): Promise<unknown> {
|
||||
const header = parseHeader(res.headers['content-type']);
|
||||
@@ -70,9 +73,11 @@ export function parseResponse(res: Dispatcher.ResponseData): Promise<unknown> {
|
||||
|
||||
/**
|
||||
* Check whether a request falls under a sublimit
|
||||
* @param bucketRoute The buckets route identifier
|
||||
* @param body The options provided as JSON data
|
||||
* @param method The HTTP method that will be used to make the request
|
||||
*
|
||||
* @param bucketRoute - The buckets route identifier
|
||||
* @param body - The options provided as JSON data
|
||||
* @param method - The HTTP method that will be used to make the request
|
||||
*
|
||||
* @returns Whether the request falls under a sublimit
|
||||
*/
|
||||
export function hasSublimit(bucketRoute: string, body?: unknown, method?: string): boolean {
|
||||
|
||||
Reference in New Issue
Block a user