Skip to content

Commit 4f97f04

Browse files
committed
docs(ratelimit): refine jsdoc coverage
1 parent d1909a9 commit 4f97f04

34 files changed

Lines changed: 1191 additions & 128 deletions

packages/ratelimit/spec/algorithms.test.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
// Algorithm integration tests.
2-
//
3-
// Fake timers keep limiter math deterministic and avoid flakiness.
1+
/**
2+
* Algorithm integration tests.
3+
*
4+
* Fake timers keep limiter math deterministic and avoid flakiness.
5+
*/
46

57
import { afterEach, describe, expect, test, vi } from 'vitest';
68
import { MemoryRateLimitStorage } from '../src/storage/memory';
@@ -13,6 +15,11 @@ import type { RateLimitStorage } from '../src/types';
1315
const scope = 'user' as const;
1416
const delay = (ms = 0) => new Promise<void>((resolve) => setTimeout(resolve, ms));
1517

18+
/**
19+
* Test storage that delays sorted-set calls to simulate contention.
20+
*
21+
* @implements RateLimitStorage
22+
*/
1623
class DelayedSlidingWindowStorage implements RateLimitStorage {
1724
private readonly kv = new Map<string, unknown>();
1825
private readonly zset = new MemoryRateLimitStorage();
@@ -60,6 +67,11 @@ class DelayedSlidingWindowStorage implements RateLimitStorage {
6067
}
6168
}
6269

70+
/**
71+
* Test storage that delays key/value calls for fixed-window tests.
72+
*
73+
* @implements RateLimitStorage
74+
*/
6375
class DelayedFixedWindowStorage implements RateLimitStorage {
6476
private readonly kv = new Map<string, unknown>();
6577

packages/ratelimit/spec/api.test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
// API helper tests.
2-
//
3-
// Uses in-memory storage to keep exemption/reset tests isolated.
1+
/**
2+
* API helper tests.
3+
*
4+
* Uses in-memory storage to keep exemption/reset tests isolated.
5+
*/
46

57
import { afterEach, describe, expect, test } from 'vitest';
68
import { MemoryRateLimitStorage } from '../src/storage/memory';

packages/ratelimit/spec/engine.test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
// Engine escalation tests.
2-
//
3-
// Fake timers keep violation cooldowns deterministic.
1+
/**
2+
* Engine escalation tests.
3+
*
4+
* Fake timers keep violation cooldowns deterministic.
5+
*/
46

57
import { afterEach, describe, expect, test, vi } from 'vitest';
68
import { RateLimitEngine } from '../src/engine/RateLimitEngine';

packages/ratelimit/spec/helpers.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
// Test helpers for ratelimit specs.
2-
//
3-
// Provides lightweight stubs for Discord and CommandKit so tests stay focused
4-
// on rate limit behavior without a live client.
1+
/**
2+
* Test helpers for ratelimit specs.
3+
*
4+
* Provides lightweight stubs for Discord and CommandKit so tests stay focused
5+
* on rate limit behavior without a live client.
6+
*/
57

68
import { Collection, Message } from 'discord.js';
79
import { vi } from 'vitest';
@@ -19,7 +21,11 @@ export interface InteractionStubOptions {
1921

2022
/**
2123
* Build an Interaction-like stub with only the fields the plugin reads.
24+
*
2225
* Keeps tests fast without a live Discord client.
26+
*
27+
* @param options - Overrides for interaction fields used in tests.
28+
* @returns Interaction stub matching the minimal plugin contract.
2329
*/
2430
export function createInteractionStub(options: InteractionStubOptions = {}) {
2531
const interaction = {
@@ -61,6 +67,9 @@ export interface MessageStubOptions {
6167

6268
/**
6369
* Build a Message-like stub with minimal fields used by rate limit logic.
70+
*
71+
* @param options - Overrides for message fields used in tests.
72+
* @returns Message stub matching the minimal plugin contract.
6473
*/
6574
export function createMessageStub(options: MessageStubOptions = {}) {
6675
const message = Object.create(Message.prototype) as Message & {
@@ -87,6 +96,9 @@ export function createMessageStub(options: MessageStubOptions = {}) {
8796

8897
/**
8998
* Create a minimal CommandKit env with a store for plugin results.
99+
*
100+
* @param commandName - Command name to seed into the context.
101+
* @returns Minimal CommandKit environment for plugin tests.
90102
*/
91103
export function createEnv(commandName = 'ping') {
92104
return {
@@ -97,6 +109,9 @@ export function createEnv(commandName = 'ping') {
97109

98110
/**
99111
* Create a runtime context with stubbed analytics and capture hooks.
112+
*
113+
* @param overrides - Optional overrides for command arrays.
114+
* @returns Runtime context and stubbed helpers.
100115
*/
101116
export function createRuntimeContext(
102117
overrides: {
@@ -129,6 +144,9 @@ export function createRuntimeContext(
129144

130145
/**
131146
* Build a prepared command shape for plugin tests.
147+
*
148+
* @param options - Command metadata overrides.
149+
* @returns Prepared command payload for plugin tests.
132150
*/
133151
export function createPreparedCommand(options: {
134152
name?: string;

packages/ratelimit/spec/plugin.test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
// Plugin integration tests.
2-
//
3-
// Uses stubs to keep plugin tests fast and offline.
1+
/**
2+
* Plugin integration tests.
3+
*
4+
* Uses stubs to keep plugin tests fast and offline.
5+
*/
46

57
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
68
import { MessageFlags } from 'discord.js';

packages/ratelimit/spec/setup.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
// Vitest setup for ratelimit specs.
2-
//
3-
// Restores the Console constructor so logging helpers behave consistently.
1+
/**
2+
* Vitest setup for ratelimit specs.
3+
*
4+
* Restores the Console constructor so logging helpers behave consistently.
5+
*/
46

57
import { Console } from 'node:console';
68

packages/ratelimit/src/api.ts

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
// Public rate limit helpers.
2-
//
3-
// Used by handlers and admin tools to inspect, reset, and manage exemptions.
1+
/**
2+
* Public rate limit helpers.
3+
*
4+
* Used by handlers and admin tools to inspect, reset, and manage exemptions.
5+
*/
46

57
import type { CommandKitEnvironment, Context } from 'commandkit';
68
import { RATELIMIT_STORE_KEY } from './constants';
@@ -51,6 +53,9 @@ export interface ResetAllRateLimitsParams {
5153

5254
/**
5355
* Read aggregated rate limit info stored on a CommandKit env or context.
56+
*
57+
* @param envOrCtx - CommandKit environment or context holding the rate-limit store.
58+
* @returns Aggregated rate-limit info or null when no store is present.
5459
*/
5560
export function getRateLimitInfo(
5661
envOrCtx: CommandKitEnvironment | Context | null | undefined,
@@ -61,10 +66,22 @@ export function getRateLimitInfo(
6166
return (store.get(RATELIMIT_STORE_KEY) as RateLimitStoreValue) ?? null;
6267
}
6368

69+
/**
70+
* Resolve the active storage or throw when none is configured.
71+
*
72+
* @returns Configured rate-limit storage.
73+
* @throws Error when storage is not configured.
74+
*/
6475
function getRequiredStorage(): RateLimitStorage {
6576
return getRuntimeStorage().storage;
6677
}
6778

79+
/**
80+
* Resolve runtime context plus the effective storage to use.
81+
*
82+
* @returns Runtime context (if any) and the resolved storage.
83+
* @throws Error when storage is not configured.
84+
*/
6885
function getRuntimeStorage(): {
6986
runtime: ReturnType<typeof getRateLimitRuntime>;
7087
storage: RateLimitStorage;
@@ -77,12 +94,22 @@ function getRuntimeStorage(): {
7794
return { runtime, storage };
7895
}
7996

97+
/**
98+
* Normalize a prefix to include the window suffix marker.
99+
*
100+
* @param prefix - Base key prefix.
101+
* @returns Prefix guaranteed to end with `w:`.
102+
*/
80103
function toWindowPrefix(prefix: string): string {
81104
return prefix.endsWith(':') ? `${prefix}w:` : `${prefix}:w:`;
82105
}
83106

84107
/**
85108
* Reset a single key and its violation/window variants to keep state consistent.
109+
*
110+
* @param params - Reset parameters for a single key or scope-derived key.
111+
* @returns Resolves when deletes and reset hooks (if any) complete.
112+
* @throws Error when required scope identifiers are missing.
86113
*/
87114
export async function resetRateLimit(
88115
params: ResetRateLimitParams,
@@ -127,6 +154,11 @@ export async function resetRateLimit(
127154

128155
/**
129156
* Reset multiple keys by scope, command name, prefix, or pattern for bulk cleanup.
157+
*
158+
* @param params - Batch reset parameters, defaulting to an empty config.
159+
* @returns Resolves when all matching keys are deleted.
160+
* @throws Error when the storage backend lacks required delete helpers.
161+
* @throws Error when scope identifiers are missing for scope-based resets.
130162
*/
131163
export async function resetAllRateLimits(
132164
params: ResetAllRateLimitsParams = {},
@@ -196,6 +228,10 @@ export async function resetAllRateLimits(
196228

197229
/**
198230
* Grant a temporary exemption for a scope/id pair.
231+
*
232+
* @param params - Exemption scope, id, and duration.
233+
* @returns Resolves when the exemption key is written.
234+
* @throws Error when duration is missing or non-positive.
199235
*/
200236
export async function grantRateLimitExemption(
201237
params: RateLimitExemptionGrantParams,
@@ -214,6 +250,9 @@ export async function grantRateLimitExemption(
214250

215251
/**
216252
* Revoke a temporary exemption for a scope/id pair.
253+
*
254+
* @param params - Exemption scope and id to revoke.
255+
* @returns Resolves when the exemption key is removed.
217256
*/
218257
export async function revokeRateLimitExemption(
219258
params: RateLimitExemptionRevokeParams,
@@ -226,6 +265,10 @@ export async function revokeRateLimitExemption(
226265

227266
/**
228267
* List exemptions by scope and/or id for admin/reporting.
268+
*
269+
* @param params - Optional scope/id filters and limits.
270+
* @returns Exemption info entries that match the requested filters.
271+
* @throws Error when scope is required but missing or listing is unsupported.
229272
*/
230273
export async function listRateLimitExemptions(
231274
params: RateLimitExemptionListParams = {},
@@ -281,6 +324,13 @@ export async function listRateLimitExemptions(
281324
return results;
282325
}
283326

327+
/**
328+
* Delete windowed variants for a base key using available storage helpers.
329+
*
330+
* @param storage - Storage driver to delete from.
331+
* @param key - Base key to delete window variants for.
332+
* @returns Resolves after window variants are removed.
333+
*/
284334
async function deleteWindowVariants(
285335
storage: RateLimitStorage,
286336
key: string,

packages/ratelimit/src/augmentation.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
// CommandKit metadata augmentation.
2-
//
3-
// Extends CommandKit metadata so commands can declare per-command limits.
1+
/**
2+
* CommandKit metadata augmentation.
3+
*
4+
* Extends CommandKit metadata so commands can declare per-command limits.
5+
*/
46

57
import type { RateLimitCommandConfig } from './types';
68

packages/ratelimit/src/configure.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
// Runtime configuration for the rate limit plugin.
2-
//
3-
// Mirrors configureAI so runtime options can be set outside commandkit.config
4-
// before the plugin evaluates commands.
1+
/**
2+
* Runtime configuration for the rate limit plugin.
3+
*
4+
* Mirrors configureAI so runtime options can be set outside commandkit.config
5+
* before the plugin evaluates commands.
6+
*/
57

68
import { DEFAULT_LIMITER } from './utils/config';
79
import {
@@ -19,6 +21,12 @@ import type {
1921
const rateLimitConfig: RateLimitPluginOptions = {};
2022
let configured = false;
2123

24+
/**
25+
* Normalize a storage config into a storage driver instance.
26+
*
27+
* @param config - Storage config or driver.
28+
* @returns Storage driver instance or null when not configured.
29+
*/
2230
function resolveStorage(
2331
config: RateLimitStorageConfig,
2432
): RateLimitStorage | null {
@@ -29,6 +37,12 @@ function resolveStorage(
2937
return config;
3038
}
3139

40+
/**
41+
* Apply updated config to the active runtime context.
42+
*
43+
* @param config - Runtime configuration updates.
44+
* @returns Nothing; mutates the active runtime context when present.
45+
*/
3246
function updateRuntime(config: RateLimitPluginOptions): void {
3347
const runtime = getRateLimitRuntime();
3448
const storageOverride = config.storage
@@ -57,21 +71,29 @@ function updateRuntime(config: RateLimitPluginOptions): void {
5771

5872
/**
5973
* Returns true once configureRatelimit has been called.
74+
*
75+
* @returns True when runtime configuration has been initialized.
6076
*/
6177
export function isRateLimitConfigured(): boolean {
6278
return configured;
6379
}
6480

6581
/**
6682
* Retrieves the current rate limit configuration.
83+
*
84+
* @returns The current in-memory rate limit config object.
6785
*/
6886
export function getRateLimitConfig(): RateLimitPluginOptions {
6987
return rateLimitConfig;
7088
}
7189

7290
/**
7391
* Configures the rate limit plugin runtime options.
92+
*
7493
* Call this once during startup (for example in src/ratelimit.ts).
94+
*
95+
* @param config - Runtime options to merge into the active configuration.
96+
* @returns Nothing; updates runtime state in place.
7597
*/
7698
export function configureRatelimit(
7799
config: RateLimitPluginOptions = {},
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1-
// Rate limit constants shared across runtime and tests.
2-
//
3-
// Keeps key names consistent across storage, runtime, and docs.
1+
/**
2+
* Rate limit constants shared across runtime and tests.
3+
*
4+
* Keeps key names consistent across storage, runtime, and docs.
5+
*/
46

57
/**
68
* Store key used to stash aggregated results in CommandKit envs.
9+
*
10+
* @default 'ratelimit'
711
*/
812
export const RATELIMIT_STORE_KEY = 'ratelimit';
913

1014
/**
1115
* Default prefix for storage keys; can be overridden per config.
16+
*
17+
* @default 'rl:'
1218
*/
1319
export const DEFAULT_KEY_PREFIX = 'rl:';

0 commit comments

Comments
 (0)