@cqrs-ddd/pipeline-rate-limit 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/errors/rate-limit-exceeded.error.d.ts +3 -2
- package/dist/errors/rate-limit-exceeded.error.d.ts.map +1 -1
- package/dist/errors/rate-limit-exceeded.error.js +3 -2
- package/dist/errors/rate-limit-exceeded.error.js.map +1 -1
- package/dist/helpers/partitioned-key.d.ts +10 -2
- package/dist/helpers/partitioned-key.d.ts.map +1 -1
- package/dist/helpers/partitioned-key.js +8 -3
- package/dist/helpers/partitioned-key.js.map +1 -1
- package/dist/http.d.ts +3 -6
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +2 -1
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/rate-limit.behavior.d.ts +6 -22
- package/dist/rate-limit.behavior.d.ts.map +1 -1
- package/dist/rate-limit.behavior.js +44 -74
- package/dist/rate-limit.behavior.js.map +1 -1
- package/package.json +5 -5
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* Thrown by {@link RateLimitBehavior} when a request exceeds its allotted
|
|
3
3
|
* points for the current window.
|
|
4
4
|
*
|
|
5
|
-
* Map it to HTTP `429 Too Many Requests` with
|
|
6
|
-
* which also
|
|
5
|
+
* Map it to HTTP `429 Too Many Requests` with `toHttpResponse` of
|
|
6
|
+
* `@cqrs-ddd/pipeline-rate-limit/http`, which also gives a `Retry-After` header
|
|
7
|
+
* from {@link retryAfterSeconds}.
|
|
7
8
|
*/
|
|
8
9
|
export declare class RateLimitExceededError extends Error {
|
|
9
10
|
/** The rate-limit bucket key that was exhausted. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit-exceeded.error.d.ts","sourceRoot":"","sources":["../../src/errors/rate-limit-exceeded.error.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"rate-limit-exceeded.error.d.ts","sourceRoot":"","sources":["../../src/errors/rate-limit-exceeded.error.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,oDAAoD;IACpD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,+CAA+C;IAC/C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,wDAAwD;IACxD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEzB,YAAY,MAAM,EAAE;QAClB,GAAG,EAAE,MAAM,CAAC;QACZ,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,EAiBA;CACF"}
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
* Thrown by {@link RateLimitBehavior} when a request exceeds its allotted
|
|
4
4
|
* points for the current window.
|
|
5
5
|
*
|
|
6
|
-
* Map it to HTTP `429 Too Many Requests` with
|
|
7
|
-
* which also
|
|
6
|
+
* Map it to HTTP `429 Too Many Requests` with `toHttpResponse` of
|
|
7
|
+
* `@cqrs-ddd/pipeline-rate-limit/http`, which also gives a `Retry-After` header
|
|
8
|
+
* from {@link retryAfterSeconds}.
|
|
8
9
|
*/
|
|
9
10
|
export class RateLimitExceededError extends Error {
|
|
10
11
|
/** The rate-limit bucket key that was exhausted. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit-exceeded.error.js","sourceRoot":"","sources":["../../src/errors/rate-limit-exceeded.error.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE
|
|
1
|
+
{"version":3,"file":"rate-limit-exceeded.error.js","sourceRoot":"","sources":["../../src/errors/rate-limit-exceeded.error.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE;;;;;;;GAOG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,oDAAoD;IAC3C,GAAG,CAAS;IACrB,gEAAgE;IACvD,WAAW,CAAS;IAC7B,+CAA+C;IACtC,YAAY,CAAS;IAC9B,0EAA0E;IACjE,iBAAiB,CAAS;IACnC,2DAA2D;IAClD,eAAe,CAAS;IACjC,wDAAwD;IAC/C,KAAK,CAAU;IACxB;;;OAGG;IACM,MAAM,CAAU;IAEzB,YAAY,MAOX;QACC,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAChC,CAAC,EACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,CACtC,CAAC;QACF,KAAK,CACH,2BAA2B,MAAM,CAAC,WAAW,GAAG;YAC9C,SAAS,MAAM,CAAC,GAAG,kBAAkB,iBAAiB,GAAG,CAC5D,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACtC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;QAC9C,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;CACF"}
|
|
@@ -6,8 +6,11 @@ import type { RateLimitKeyFactory } from '../interfaces/rate-limit-options.inter
|
|
|
6
6
|
*
|
|
7
7
|
* Typical values are an authenticated user ID, account ID, API-client ID, or a
|
|
8
8
|
* trusted transport identity copied into `context.items` by an earlier behavior.
|
|
9
|
+
*
|
|
10
|
+
* @typeParam TRequest - The request class the handler receives, which types
|
|
11
|
+
* `context.request`. The factory does not check it at run time.
|
|
9
12
|
*/
|
|
10
|
-
export type RateLimitPartitionFactory = (context: IPipelineContext) => string | undefined;
|
|
13
|
+
export type RateLimitPartitionFactory<TRequest = unknown> = (context: IPipelineContext<TRequest>) => string | undefined;
|
|
11
14
|
/** Options for {@link createPartitionedRateLimitKeyFactory}. */
|
|
12
15
|
export interface PartitionedRateLimitKeyOptions extends TenantPartitionOptions {
|
|
13
16
|
/**
|
|
@@ -51,6 +54,11 @@ export interface PartitionedRateLimitKeyOptions extends TenantPartitionOptions {
|
|
|
51
54
|
* }
|
|
52
55
|
* ```
|
|
53
56
|
*
|
|
57
|
+
* @example Per value of the request, typed by the request class
|
|
58
|
+
* ```ts
|
|
59
|
+
* createPartitionedRateLimitKeyFactory<LoginCommand>((ctx) => ctx.request.clientIp);
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
54
62
|
* @example Single-tenant deployment — say so explicitly
|
|
55
63
|
* ```ts
|
|
56
64
|
* createPartitionedRateLimitKeyFactory(readUserId, { includeTenant: false });
|
|
@@ -61,5 +69,5 @@ export interface PartitionedRateLimitKeyOptions extends TenantPartitionOptions {
|
|
|
61
69
|
* createPartitionedRateLimitKeyFactory(readAccountId, { includeTenant: true });
|
|
62
70
|
* ```
|
|
63
71
|
*/
|
|
64
|
-
export declare function createPartitionedRateLimitKeyFactory(partitionFactory: RateLimitPartitionFactory
|
|
72
|
+
export declare function createPartitionedRateLimitKeyFactory<TRequest = unknown>(partitionFactory: RateLimitPartitionFactory<TRequest>, options?: PartitionedRateLimitKeyOptions): RateLimitKeyFactory;
|
|
65
73
|
//# sourceMappingURL=partitioned-key.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"partitioned-key.d.ts","sourceRoot":"","sources":["../../src/helpers/partitioned-key.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,gBAAgB,
|
|
1
|
+
{"version":3,"file":"partitioned-key.d.ts","sourceRoot":"","sources":["../../src/helpers/partitioned-key.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,gBAAgB,EAErB,KAAK,sBAAsB,EAE5B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AAEzF;;;;;;;;;GASG;AACH,MAAM,MAAM,yBAAyB,CAAC,QAAQ,GAAG,OAAO,IAAI,CAC1D,OAAO,EAAE,gBAAgB,CAAC,QAAQ,CAAC,KAChC,MAAM,GAAG,SAAS,CAAC;AAExB,gEAAgE;AAChE,MAAM,WAAW,8BAA+B,SAAQ,sBAAsB;IAC5E;;;;;;;;;OASG;IACH,kBAAkB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC1C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,oCAAoC,CAAC,QAAQ,GAAG,OAAO,EACrE,gBAAgB,EAAE,yBAAyB,CAAC,QAAQ,CAAC,EACrD,OAAO,GAAE,8BAAmC,GAC3C,mBAAmB,CAgCrB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
-
import { tenantSegments, } from '@cqrs-ddd/pipeline';
|
|
2
|
+
import { principalSegments, tenantSegments, } from '@cqrs-ddd/pipeline';
|
|
3
3
|
import { joinKeySegments } from '@cqrs-ddd/safe-stringify';
|
|
4
4
|
import { MissingRateLimitPartitionError } from '../errors/missing-partition.error.js';
|
|
5
5
|
/**
|
|
@@ -31,6 +31,11 @@ import { MissingRateLimitPartitionError } from '../errors/missing-partition.erro
|
|
|
31
31
|
* }
|
|
32
32
|
* ```
|
|
33
33
|
*
|
|
34
|
+
* @example Per value of the request, typed by the request class
|
|
35
|
+
* ```ts
|
|
36
|
+
* createPartitionedRateLimitKeyFactory<LoginCommand>((ctx) => ctx.request.clientIp);
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
34
39
|
* @example Single-tenant deployment — say so explicitly
|
|
35
40
|
* ```ts
|
|
36
41
|
* createPartitionedRateLimitKeyFactory(readUserId, { includeTenant: false });
|
|
@@ -46,7 +51,7 @@ export function createPartitionedRateLimitKeyFactory(partitionFactory, options =
|
|
|
46
51
|
const keyFor = (context) => {
|
|
47
52
|
const tenant = tenantSegments(context, options, MissingRateLimitPartitionError);
|
|
48
53
|
const resolved = partitionFactory(context);
|
|
49
|
-
const partition = typeof resolved === 'string' ? resolved
|
|
54
|
+
const partition = principalSegments(typeof resolved === 'string' ? resolved : undefined);
|
|
50
55
|
if (!partition) {
|
|
51
56
|
if (onMissingPartition === 'throw') {
|
|
52
57
|
throw new MissingRateLimitPartitionError(context.requestName, 'caller', "Return a stable caller/account identifier, or configure onMissingPartition: 'request'.");
|
|
@@ -55,7 +60,7 @@ export function createPartitionedRateLimitKeyFactory(partitionFactory, options =
|
|
|
55
60
|
// so an anonymous caller in one tenant cannot exhaust another tenant's quota.
|
|
56
61
|
return joinKeySegments([...tenant, context.requestName]);
|
|
57
62
|
}
|
|
58
|
-
return joinKeySegments([...tenant, partition, context.requestName]);
|
|
63
|
+
return joinKeySegments([...tenant, ...partition, context.requestName]);
|
|
59
64
|
};
|
|
60
65
|
return keyFor;
|
|
61
66
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"partitioned-key.js","sourceRoot":"","sources":["../../src/helpers/partitioned-key.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,
|
|
1
|
+
{"version":3,"file":"partitioned-key.js","sourceRoot":"","sources":["../../src/helpers/partitioned-key.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAEL,iBAAiB,EAEjB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,8BAA8B,EAAE,MAAM,sCAAsC,CAAC;AAgCtF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,MAAM,UAAU,oCAAoC,CAClD,gBAAqD,EACrD,OAAO,GAAmC,EAAE;IAE5C,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,IAAI,OAAO,CAAC;IAEjE,MAAM,MAAM,GAAwB,CAAC,OAAO,EAAE,EAAE;QAC9C,MAAM,MAAM,GAAG,cAAc,CAC3B,OAAO,EACP,OAAO,EACP,8BAA8B,CAC/B,CAAC;QAEF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAqC,CAAC,CAAC;QACzE,MAAM,SAAS,GAAG,iBAAiB,CACjC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CACpD,CAAC;QAEF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,IAAI,kBAAkB,KAAK,OAAO,EAAE,CAAC;gBACnC,MAAM,IAAI,8BAA8B,CACtC,OAAO,CAAC,WAAW,EACnB,QAAQ,EACR,wFAAwF,CACzF,CAAC;YACJ,CAAC;YACD,yEAAyE;YACzE,8EAA8E;YAC9E,OAAO,eAAe,CAAC,CAAC,GAAG,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,eAAe,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IACzE,CAAC,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/http.d.ts
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
+
import type { HttpResponse } from '@cqrs-ddd/pipeline';
|
|
1
2
|
import { RateLimitExceededError } from './errors/rate-limit-exceeded.error.js';
|
|
2
|
-
|
|
3
|
-
export interface HttpResponse {
|
|
4
|
-
status: number;
|
|
5
|
-
body: Record<string, unknown>;
|
|
6
|
-
headers: Record<string, string>;
|
|
7
|
-
}
|
|
3
|
+
export type { HttpResponse };
|
|
8
4
|
/**
|
|
9
5
|
* The HTTP answer for a {@link RateLimitExceededError}: `429 Too Many Requests` with a
|
|
10
6
|
* `Retry-After` header. Framework filters and Express handlers reply with it.
|
|
7
|
+
* The body never carries the bucket key, which holds the tenant and the caller.
|
|
11
8
|
*
|
|
12
9
|
* @example
|
|
13
10
|
* ```ts
|
package/dist/http.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAE/E,YAAY,EAAE,YAAY,EAAE,CAAC;AAE7B;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,sBAAsB,GAAG,YAAY,CAW1E"}
|
package/dist/http.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* The HTTP answer for a {@link RateLimitExceededError}: `429 Too Many Requests` with a
|
|
4
4
|
* `Retry-After` header. Framework filters and Express handlers reply with it.
|
|
5
|
+
* The body never carries the bucket key, which holds the tenant and the caller.
|
|
5
6
|
*
|
|
6
7
|
* @example
|
|
7
8
|
* ```ts
|
|
@@ -18,7 +19,7 @@ export function toHttpResponse(error) {
|
|
|
18
19
|
body: {
|
|
19
20
|
statusCode: 429,
|
|
20
21
|
error: 'Too Many Requests',
|
|
21
|
-
message: error.
|
|
22
|
+
message: `Rate limit exceeded; retry after ${error.retryAfterSeconds}s`,
|
|
22
23
|
retryAfter: error.retryAfterSeconds,
|
|
23
24
|
},
|
|
24
25
|
headers: { 'Retry-After': String(error.retryAfterSeconds) },
|
package/dist/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,sEAAsE;
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAOtE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAAC,KAA6B;IAC1D,OAAO;QACL,MAAM,EAAE,GAAG;QACX,IAAI,EAAE;YACJ,UAAU,EAAE,GAAG;YACf,KAAK,EAAE,mBAAmB;YAC1B,OAAO,EAAE,oCAAoC,KAAK,CAAC,iBAAiB,GAAG;YACvE,UAAU,EAAE,KAAK,CAAC,iBAAiB;SACpC;QACD,OAAO,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE;KAC5D,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,5 +11,5 @@ export { createPartitionedRateLimitKeyFactory, type PartitionedRateLimitKeyOptio
|
|
|
11
11
|
export { type RateLimitIntentOptions, rateLimit, } from './helpers/rate-limit.intent.js';
|
|
12
12
|
export type { RateLimitBehaviorOptions, RateLimitCostFactory, RateLimitKeyFactory, } from './interfaces/rate-limit-options.interface.js';
|
|
13
13
|
export type { RateLimiterLike, RateLimiterResLike, } from './interfaces/rate-limiter.interface.js';
|
|
14
|
-
export {
|
|
14
|
+
export { RATE_LIMIT_ITEM_TOKEN, RATE_LIMIT_KEY_ITEM_TOKEN, RateLimitBehavior, } from './rate-limit.behavior.js';
|
|
15
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,OAAO,EACL,8BAA8B,EAC9B,KAAK,2BAA2B,GACjC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EACL,oCAAoC,EACpC,KAAK,8BAA8B,EACnC,KAAK,yBAAyB,GAC/B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,KAAK,sBAAsB,EAC3B,SAAS,GACV,MAAM,gCAAgC,CAAC;AACxC,YAAY,EACV,wBAAwB,EACxB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,8CAA8C,CAAC;AACtD,YAAY,EACV,eAAe,EACf,kBAAkB,GACnB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,OAAO,EACL,8BAA8B,EAC9B,KAAK,2BAA2B,GACjC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EACL,oCAAoC,EACpC,KAAK,8BAA8B,EACnC,KAAK,yBAAyB,GAC/B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,KAAK,sBAAsB,EAC3B,SAAS,GACV,MAAM,gCAAgC,CAAC;AACxC,YAAY,EACV,wBAAwB,EACxB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,8CAA8C,CAAC;AACtD,YAAY,EACV,eAAe,EACf,kBAAkB,GACnB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -10,5 +10,5 @@ export { buildRateLimitAttributes } from './helpers/build-attributes.js';
|
|
|
10
10
|
export { buildRateLimitKey } from './helpers/build-key.js';
|
|
11
11
|
export { createPartitionedRateLimitKeyFactory, } from './helpers/partitioned-key.js';
|
|
12
12
|
export { rateLimit, } from './helpers/rate-limit.intent.js';
|
|
13
|
-
export {
|
|
13
|
+
export { RATE_LIMIT_ITEM_TOKEN, RATE_LIMIT_KEY_ITEM_TOKEN, RateLimitBehavior, } from './rate-limit.behavior.js';
|
|
14
14
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE;;;;GAIG;AAEH,OAAO,EACL,8BAA8B,GAE/B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EACL,oCAAoC,GAGrC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAEL,SAAS,GACV,MAAM,gCAAgC,CAAC;AAUxC,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE;;;;GAIG;AAEH,OAAO,EACL,8BAA8B,GAE/B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EACL,oCAAoC,GAGrC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAEL,SAAS,GACV,MAAM,gCAAgC,CAAC;AAUxC,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC"}
|
|
@@ -2,31 +2,15 @@ import { type IPipelineBehavior, type IPipelineBehaviorContract, type IPipelineB
|
|
|
2
2
|
import type { RateLimitBehaviorOptions } from './interfaces/rate-limit-options.interface.js';
|
|
3
3
|
import type { RateLimiterLike, RateLimiterResLike } from './interfaces/rate-limiter.interface.js';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* The `context.items` entry containing the result of a rate-limit check (or rejection payload).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* ```ts
|
|
9
|
-
* const result = context.items.get(RATE_LIMIT_ITEM);
|
|
10
|
-
* ```
|
|
11
|
-
*/
|
|
12
|
-
export declare const RATE_LIMIT_ITEM: unique symbol;
|
|
13
|
-
/**
|
|
14
|
-
* Typed token for {@link RATE_LIMIT_ITEM}: the rate-limit result. Reads and writes the same
|
|
15
|
-
* `context.items` entry through `getPipelineItem` / `requirePipelineItem`.
|
|
7
|
+
* Read it with `getPipelineItem` or `requirePipelineItem`.
|
|
16
8
|
*/
|
|
17
9
|
export declare const RATE_LIMIT_ITEM_TOKEN: PipelineItemToken<RateLimiterResLike>;
|
|
18
10
|
/**
|
|
19
|
-
*
|
|
11
|
+
* The `context.items` entry containing the resolved rate limit bucket key string.
|
|
20
12
|
*
|
|
21
|
-
*
|
|
22
|
-
* ```ts
|
|
23
|
-
* const key = context.items.get(RATE_LIMIT_KEY_ITEM) as string | undefined;
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
export declare const RATE_LIMIT_KEY_ITEM: unique symbol;
|
|
27
|
-
/**
|
|
28
|
-
* Typed token for {@link RATE_LIMIT_KEY_ITEM}: the resolved rate-limit key. Reads and writes the same
|
|
29
|
-
* `context.items` entry through `getPipelineItem` / `requirePipelineItem`.
|
|
13
|
+
* Read it with `getPipelineItem` or `requirePipelineItem`.
|
|
30
14
|
*/
|
|
31
15
|
export declare const RATE_LIMIT_KEY_ITEM_TOKEN: PipelineItemToken<string>;
|
|
32
16
|
/**
|
|
@@ -66,8 +50,8 @@ export declare class RateLimitBehavior implements IPipelineBehavior, IPipelineBe
|
|
|
66
50
|
private readonly defaults;
|
|
67
51
|
constructor(limiter: RateLimiterLike, defaults?: RateLimitBehaviorOptions, logger?: PipelineLogger);
|
|
68
52
|
handle(context: IPipelineContext, next: NextDelegate): Promise<unknown>;
|
|
69
|
-
/**
|
|
70
|
-
private
|
|
53
|
+
/** Logs a failure of the backing store, and rethrows it unless failing open (default). */
|
|
54
|
+
private reportStoreError;
|
|
71
55
|
/** Shallow-merges pipeline-level options over the constructor defaults. */
|
|
72
56
|
resolveEffectiveOptions(options?: RateLimitBehaviorOptions): RateLimitBehaviorOptions;
|
|
73
57
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.behavior.d.ts","sourceRoot":"","sources":["../src/rate-limit.behavior.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"rate-limit.behavior.d.ts","sourceRoot":"","sources":["../src/rate-limit.behavior.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,gCAAgC,EACrC,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,0BAA0B,EAC1B,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8CAA8C,CAAC;AAC7F,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EACnB,MAAM,wCAAwC,CAAC;AAEhD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,iBAAiB,CAAC,kBAAkB,CACb,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,iBAAiB,CAAC,MAAM,CACb,CAAC;AAmBpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,iBACX,YACE,iBAAiB,EACjB,gCAAgC,CAAC,wBAAwB,CAAC;IA0C1D,OAAO,CAAC,QAAQ,CAAC,OAAO;IAxC1B,MAAM,CAAC,QAAQ,CAAC,CAAC,0BAA0B,CAAC,EAAE,yBAAyB,CAkCrE;IAEF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;IAEpD,YACmB,OAAO,EAAE,eAAe,EACzC,QAAQ,CAAC,EAAE,wBAAwB,EACnC,MAAM,CAAC,EAAE,cAAc,EAUxB;IAEK,MAAM,CACV,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,OAAO,CAAC,CA+BlB;IAED,0FAA0F;IAC1F,OAAO,CAAC,gBAAgB;IAaxB,2EAA2E;IAC3E,uBAAuB,CACrB,OAAO,CAAC,EAAE,wBAAwB,GACjC,wBAAwB,CAG1B;CACF"}
|
|
@@ -1,35 +1,19 @@
|
|
|
1
1
|
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
-
import { createPipelineItem, PIPELINE_BEHAVIOR_CONTRACT, setPipelineItem, } from '@cqrs-ddd/pipeline';
|
|
2
|
+
import { behaviorDiagnostic, createPipelineItem, PIPELINE_BEHAVIOR_CONTRACT, setPipelineItem, } from '@cqrs-ddd/pipeline';
|
|
3
3
|
import { RateLimitExceededError } from './errors/rate-limit-exceeded.error.js';
|
|
4
4
|
import { buildRateLimitKey } from './helpers/build-key.js';
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* The `context.items` entry containing the result of a rate-limit check (or rejection payload).
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
* ```ts
|
|
10
|
-
* const result = context.items.get(RATE_LIMIT_ITEM);
|
|
11
|
-
* ```
|
|
12
|
-
*/
|
|
13
|
-
export const RATE_LIMIT_ITEM = Symbol('RATE_LIMIT_ITEM');
|
|
14
|
-
/**
|
|
15
|
-
* Typed token for {@link RATE_LIMIT_ITEM}: the rate-limit result. Reads and writes the same
|
|
16
|
-
* `context.items` entry through `getPipelineItem` / `requirePipelineItem`.
|
|
8
|
+
* Read it with `getPipelineItem` or `requirePipelineItem`.
|
|
17
9
|
*/
|
|
18
|
-
export const RATE_LIMIT_ITEM_TOKEN = createPipelineItem('RATE_LIMIT_ITEM'
|
|
10
|
+
export const RATE_LIMIT_ITEM_TOKEN = createPipelineItem('RATE_LIMIT_ITEM');
|
|
19
11
|
/**
|
|
20
|
-
*
|
|
12
|
+
* The `context.items` entry containing the resolved rate limit bucket key string.
|
|
21
13
|
*
|
|
22
|
-
*
|
|
23
|
-
* ```ts
|
|
24
|
-
* const key = context.items.get(RATE_LIMIT_KEY_ITEM) as string | undefined;
|
|
25
|
-
* ```
|
|
26
|
-
*/
|
|
27
|
-
export const RATE_LIMIT_KEY_ITEM = Symbol('RATE_LIMIT_KEY_ITEM');
|
|
28
|
-
/**
|
|
29
|
-
* Typed token for {@link RATE_LIMIT_KEY_ITEM}: the resolved rate-limit key. Reads and writes the same
|
|
30
|
-
* `context.items` entry through `getPipelineItem` / `requirePipelineItem`.
|
|
14
|
+
* Read it with `getPipelineItem` or `requirePipelineItem`.
|
|
31
15
|
*/
|
|
32
|
-
export const RATE_LIMIT_KEY_ITEM_TOKEN = createPipelineItem('RATE_LIMIT_KEY_ITEM'
|
|
16
|
+
export const RATE_LIMIT_KEY_ITEM_TOKEN = createPipelineItem('RATE_LIMIT_KEY_ITEM');
|
|
33
17
|
/** Whether a rejection value is a `rate-limiter-flexible` result (a limit hit). */
|
|
34
18
|
function isRateLimiterRes(value) {
|
|
35
19
|
return (typeof value === 'object' &&
|
|
@@ -73,38 +57,27 @@ export class RateLimitBehavior {
|
|
|
73
57
|
validate: (context) => {
|
|
74
58
|
const options = context.effectiveOptions;
|
|
75
59
|
if (!options?.keyFactory) {
|
|
76
|
-
return
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
fix: 'Provide keyFactory in the [RateLimitBehavior, { keyFactory: ... }] entry, ' +
|
|
82
|
-
'the constructor defaults, or use createPartitionedRateLimitKeyFactory(...).',
|
|
83
|
-
},
|
|
84
|
-
];
|
|
60
|
+
return behaviorDiagnostic(context, RateLimitBehavior.name, {
|
|
61
|
+
message: 'Active RateLimitBehavior requires an explicit `keyFactory`',
|
|
62
|
+
fix: 'Provide keyFactory in the [RateLimitBehavior, { keyFactory: ... }] entry, ' +
|
|
63
|
+
'the constructor defaults, or use createPartitionedRateLimitKeyFactory(...).',
|
|
64
|
+
});
|
|
85
65
|
}
|
|
86
66
|
if (typeof options.keyFactory !== 'function') {
|
|
87
|
-
return
|
|
88
|
-
{
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
message: `RateLimitBehavior keyFactory must be a callable function, received ${typeof options.keyFactory}`,
|
|
92
|
-
fix: 'Pass a valid function (ctx) => string to the keyFactory option of the [RateLimitBehavior, { keyFactory: ... }] entry.',
|
|
93
|
-
},
|
|
94
|
-
];
|
|
67
|
+
return behaviorDiagnostic(context, RateLimitBehavior.name, {
|
|
68
|
+
message: `RateLimitBehavior keyFactory must be a callable function, received ${typeof options.keyFactory}`,
|
|
69
|
+
fix: 'Pass a valid function (ctx) => string to the keyFactory option of the [RateLimitBehavior, { keyFactory: ... }] entry.',
|
|
70
|
+
});
|
|
95
71
|
}
|
|
96
72
|
const { points } = options;
|
|
97
|
-
|
|
73
|
+
const isInvalidPoints = points !== undefined &&
|
|
98
74
|
typeof points !== 'function' &&
|
|
99
|
-
!isValidPoints(points)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
fix: 'Pass an integer from 0 up (0 charges nothing) or a function (ctx) => number as the points option.',
|
|
106
|
-
},
|
|
107
|
-
];
|
|
75
|
+
!isValidPoints(points);
|
|
76
|
+
if (isInvalidPoints) {
|
|
77
|
+
return behaviorDiagnostic(context, RateLimitBehavior.name, {
|
|
78
|
+
message: `RateLimitBehavior points must be a non-negative safe integer or a function, received ${String(points)}`,
|
|
79
|
+
fix: 'Pass an integer from 0 up (0 charges nothing) or a function (ctx) => number as the points option.',
|
|
80
|
+
});
|
|
108
81
|
}
|
|
109
82
|
return undefined;
|
|
110
83
|
},
|
|
@@ -127,39 +100,36 @@ export class RateLimitBehavior {
|
|
|
127
100
|
const limiter = options.limiter ?? this.limiter;
|
|
128
101
|
const key = buildRateLimitKey(context, options);
|
|
129
102
|
setPipelineItem(context, RATE_LIMIT_KEY_ITEM_TOKEN, key);
|
|
130
|
-
let result;
|
|
131
103
|
try {
|
|
132
|
-
result = await limiter.consume(key, points);
|
|
104
|
+
const result = await limiter.consume(key, points);
|
|
105
|
+
setPipelineItem(context, RATE_LIMIT_ITEM_TOKEN, result);
|
|
133
106
|
}
|
|
134
107
|
catch (error) {
|
|
135
|
-
if (isRateLimiterRes(error)) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
key,
|
|
139
|
-
requestName: context.requestName,
|
|
140
|
-
msBeforeNext: error.msBeforeNext,
|
|
141
|
-
remainingPoints: error.remainingPoints,
|
|
142
|
-
limit: limiter.points,
|
|
143
|
-
points,
|
|
144
|
-
});
|
|
108
|
+
if (!isRateLimiterRes(error)) {
|
|
109
|
+
this.reportStoreError(error, { context, options, key });
|
|
110
|
+
return next();
|
|
145
111
|
}
|
|
146
|
-
|
|
112
|
+
setPipelineItem(context, RATE_LIMIT_ITEM_TOKEN, error);
|
|
113
|
+
throw new RateLimitExceededError({
|
|
114
|
+
key,
|
|
115
|
+
requestName: context.requestName,
|
|
116
|
+
msBeforeNext: error.msBeforeNext,
|
|
117
|
+
remainingPoints: error.remainingPoints,
|
|
118
|
+
limit: limiter.points,
|
|
119
|
+
points,
|
|
120
|
+
});
|
|
147
121
|
}
|
|
148
|
-
setPipelineItem(context, RATE_LIMIT_ITEM_TOKEN, result);
|
|
149
122
|
return next();
|
|
150
123
|
}
|
|
151
|
-
/**
|
|
152
|
-
|
|
124
|
+
/** Logs a failure of the backing store, and rethrows it unless failing open (default). */
|
|
125
|
+
reportStoreError(error, check) {
|
|
153
126
|
const { context, options, key } = check;
|
|
154
127
|
const message = error instanceof Error ? error.message : String(error);
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
this.logger.error?.(`Rate limiter store error for ${context.requestName} ` +
|
|
161
|
-
`(key: ${key}); failing closed: ${message}`, RateLimitBehavior.name);
|
|
162
|
-
throw error;
|
|
128
|
+
const failOpen = options.failOpen ?? true;
|
|
129
|
+
this.logger[failOpen ? 'warn' : 'error']?.(`Rate limiter store error for ${context.requestName} ` +
|
|
130
|
+
`(key: ${key}); failing ${failOpen ? 'open' : 'closed'}: ${message}`, RateLimitBehavior.name);
|
|
131
|
+
if (!failOpen)
|
|
132
|
+
throw error;
|
|
163
133
|
}
|
|
164
134
|
/** Shallow-merges pipeline-level options over the constructor defaults. */
|
|
165
135
|
resolveEffectiveOptions(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.behavior.js","sourceRoot":"","sources":["../src/rate-limit.behavior.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EACL,kBAAkB,EAMlB,0BAA0B,
|
|
1
|
+
{"version":3,"file":"rate-limit.behavior.js","sourceRoot":"","sources":["../src/rate-limit.behavior.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cqrs-ddd/pipeline-rate-limit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Rate limiting for @cqrs-ddd/pipeline, with keys partitioned by tenant, principal and operation",
|
|
5
5
|
"author": "Aristotelis",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -50,16 +50,16 @@
|
|
|
50
50
|
"access": "public"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"@cqrs-ddd/pipeline": "^0.
|
|
53
|
+
"@cqrs-ddd/pipeline": "^0.6.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
+
"@cqrs-ddd/pipeline": "0.6.0",
|
|
56
57
|
"@vitest/coverage-v8": "^5.0.5",
|
|
57
58
|
"rate-limiter-flexible": "^11.2.3",
|
|
58
|
-
"vitest": "^5.0.5"
|
|
59
|
-
"@cqrs-ddd/pipeline": "0.5.1"
|
|
59
|
+
"vitest": "^5.0.5"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@cqrs-ddd/safe-stringify": "^0.
|
|
62
|
+
"@cqrs-ddd/safe-stringify": "^0.6.0"
|
|
63
63
|
},
|
|
64
64
|
"scripts": {
|
|
65
65
|
"build": "tsc -p tsconfig.build.json",
|