diff --git a/src/adapter/basic.ts b/src/adapter/basic.ts index 350d9c34..555348b7 100644 --- a/src/adapter/basic.ts +++ b/src/adapter/basic.ts @@ -315,7 +315,11 @@ 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..ded257d4 100644 --- a/test/rate-limit-config.test.ts +++ b/test/rate-limit-config.test.ts @@ -187,6 +187,53 @@ 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',