From b8ac007f141ee3a9f9d388d0879c412ecc79a4c6 Mon Sep 17 00:00:00 2001 From: Karen Stepanyan Date: Wed, 15 Oct 2025 17:32:15 +0400 Subject: [PATCH 1/2] add option to require rate limit selection --- src/adapter/basic.ts | 2 +- src/adapter/types.ts | 1 + src/rate-limiting/index.ts | 7 ++++++ test/rate-limit-config.test.ts | 46 ++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/adapter/basic.ts b/src/adapter/basic.ts index 350d9c34..60cf8d10 100644 --- a/src/adapter/basic.ts +++ b/src/adapter/basic.ts @@ -315,7 +315,7 @@ export class Adapter { export interface AdapterRateLimitingConfig { /** Adapter rate limits, gotten from the specific tier requested */ tiers: Record + requireTierSelection?: boolean } /** diff --git a/src/rate-limiting/index.ts b/src/rate-limiting/index.ts index 174c0f58..5241802e 100644 --- a/src/rate-limiting/index.ts +++ b/src/rate-limiting/index.ts @@ -94,6 +94,7 @@ export const lowestTierLimit = (limits?: AdapterRateLimitTier) => { export const getRateLimitingTier = ( adapterSettings: AdapterSettings, tiers?: Record, + requireTierSelection?: boolean, ): AdapterRateLimitTier | undefined => { if ( adapterSettings.RATE_LIMIT_CAPACITY || @@ -124,6 +125,12 @@ export const getRateLimitingTier = ( } if (!selectedTier) { + if (requireTierSelection) { + throw new Error( + `This adapter requires you to specify a rate limit tier via the RATE_LIMIT_API_TIER environment variable`, + ) + } + // Default to the lowest tier if none is specified // Sort the tiers by most to least restrictive const sortedTiers = Object.entries(tiers).sort( ([_, t1], [__, t2]) => lowestTierLimit(t1) - lowestTierLimit(t2), diff --git a/test/rate-limit-config.test.ts b/test/rate-limit-config.test.ts index 5504ab90..2601e633 100644 --- a/test/rate-limit-config.test.ts +++ b/test/rate-limit-config.test.ts @@ -187,6 +187,52 @@ test('throws error if explicit allocation exceeds 100%', async (t) => { ) }) +test('throws error if requireTierSelection is true and no tier is specified in settings', async (t) => { + const adapter = new Adapter({ + name: 'TEST', + endpoints: [ + new AdapterEndpoint({ + name: 'test', + transport: new (class extends NopTransport { + override async initialize(dependencies: AdapterDependencies): Promise { + t.true(dependencies.rateLimiter instanceof BurstRateLimiter) + t.is( + (dependencies.rateLimiter as unknown as Record)['perSecondLimit'], + 123, + ) + } + })(), + }), + ], + config: new AdapterConfig( + {}, + { + envDefaultOverrides: { + RATE_LIMITING_STRATEGY: 'burst', + }, + }, + ), + rateLimiting: { + tiers: { + asd: { + rateLimit1s: 5234, + }, + free: { + rateLimit1s: 123, + }, + pro: { + rateLimit1m: 1234 * 60, + }, + }, + requireTierSelection: true, + }, + }) + + await t.throwsAsync(async () => start(adapter), { + message: 'This adapter requires you to specify a rate limit tier via the RATE_LIMIT_API_TIER environment variable', + }) +}) + test('uses most restrictive tier if none is specified in settings', async (t) => { const adapter = new Adapter({ name: 'TEST', From ec2ae6a2718841d4eac09bb2e943f5d03f31aaa5 Mon Sep 17 00:00:00 2001 From: Karen Stepanyan Date: Wed, 15 Oct 2025 17:39:23 +0400 Subject: [PATCH 2/2] fix lint --- src/adapter/basic.ts | 6 +++++- test/rate-limit-config.test.ts | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/adapter/basic.ts b/src/adapter/basic.ts index 60cf8d10..555348b7 100644 --- a/src/adapter/basic.ts +++ b/src/adapter/basic.ts @@ -315,7 +315,11 @@ export class Adapter start(adapter), { - message: 'This adapter requires you to specify a rate limit tier via the RATE_LIMIT_API_TIER environment variable', + message: + 'This adapter requires you to specify a rate limit tier via the RATE_LIMIT_API_TIER environment variable', }) })