@jamesaphoenix/tx-api-server 0.1.1
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/__tests__/api.test.d.ts +7 -0
- package/dist/__tests__/api.test.d.ts.map +1 -0
- package/dist/__tests__/api.test.js +184 -0
- package/dist/__tests__/api.test.js.map +1 -0
- package/dist/__tests__/auth.test.d.ts +7 -0
- package/dist/__tests__/auth.test.d.ts.map +1 -0
- package/dist/__tests__/auth.test.js +174 -0
- package/dist/__tests__/auth.test.js.map +1 -0
- package/dist/__tests__/body-limit.test.d.ts +7 -0
- package/dist/__tests__/body-limit.test.d.ts.map +1 -0
- package/dist/__tests__/body-limit.test.js +60 -0
- package/dist/__tests__/body-limit.test.js.map +1 -0
- package/dist/__tests__/health.test.d.ts.map +1 -0
- package/dist/__tests__/health.test.js.map +1 -0
- package/dist/__tests__/log-reader.test.d.ts +8 -0
- package/dist/__tests__/log-reader.test.d.ts.map +1 -0
- package/dist/__tests__/log-reader.test.js +55 -0
- package/dist/__tests__/log-reader.test.js.map +1 -0
- package/dist/__tests__/rate-limit.test.d.ts.map +1 -0
- package/dist/__tests__/rate-limit.test.js.map +1 -0
- package/dist/__tests__/server-lib.test.d.ts +10 -0
- package/dist/__tests__/server-lib.test.d.ts.map +1 -0
- package/dist/__tests__/server-lib.test.js +145 -0
- package/dist/__tests__/server-lib.test.js.map +1 -0
- package/dist/api.d.ts +1616 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +566 -0
- package/dist/api.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/auth.d.ts +31 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +65 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/body-limit.d.ts +33 -0
- package/dist/middleware/body-limit.d.ts.map +1 -0
- package/dist/middleware/body-limit.js +50 -0
- package/dist/middleware/body-limit.js.map +1 -0
- package/dist/middleware/cors.d.ts +15 -0
- package/dist/middleware/cors.d.ts.map +1 -0
- package/dist/middleware/cors.js +31 -0
- package/dist/middleware/cors.js.map +1 -0
- package/dist/middleware/error.d.ts +26 -0
- package/dist/middleware/error.d.ts.map +1 -0
- package/dist/middleware/error.js +84 -0
- package/dist/middleware/error.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +59 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +296 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/routes/attempts.d.ts +9 -0
- package/dist/routes/attempts.d.ts.map +1 -0
- package/dist/routes/attempts.js +26 -0
- package/dist/routes/attempts.js.map +1 -0
- package/dist/routes/claims.d.ts +9 -0
- package/dist/routes/claims.d.ts.map +1 -0
- package/dist/routes/claims.js +42 -0
- package/dist/routes/claims.js.map +1 -0
- package/dist/routes/docs.d.ts +9 -0
- package/dist/routes/docs.d.ts.map +1 -0
- package/dist/routes/docs.js +80 -0
- package/dist/routes/docs.js.map +1 -0
- package/dist/routes/health.d.ts +8 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +101 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/invariants.d.ts +9 -0
- package/dist/routes/invariants.d.ts.map +1 -0
- package/dist/routes/invariants.js +64 -0
- package/dist/routes/invariants.js.map +1 -0
- package/dist/routes/learnings.d.ts +8 -0
- package/dist/routes/learnings.d.ts.map +1 -0
- package/dist/routes/learnings.js +93 -0
- package/dist/routes/learnings.js.map +1 -0
- package/dist/routes/runs.d.ts +8 -0
- package/dist/routes/runs.d.ts.map +1 -0
- package/dist/routes/runs.js +195 -0
- package/dist/routes/runs.js.map +1 -0
- package/dist/routes/sync.d.ts +8 -0
- package/dist/routes/sync.d.ts.map +1 -0
- package/dist/routes/sync.js +67 -0
- package/dist/routes/sync.js.map +1 -0
- package/dist/routes/tasks.d.ts +9 -0
- package/dist/routes/tasks.d.ts.map +1 -0
- package/dist/routes/tasks.js +167 -0
- package/dist/routes/tasks.js.map +1 -0
- package/dist/runtime.d.ts +10 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +10 -0
- package/dist/runtime.js.map +1 -0
- package/dist/server-lib.d.ts +26 -0
- package/dist/server-lib.d.ts.map +1 -0
- package/dist/server-lib.js +123 -0
- package/dist/server-lib.js.map +1 -0
- package/dist/server.d.ts +14 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +15 -0
- package/dist/server.js.map +1 -0
- package/dist/utils/log-reader.d.ts +26 -0
- package/dist/utils/log-reader.d.ts.map +1 -0
- package/dist/utils/log-reader.js +52 -0
- package/dist/utils/log-reader.js.map +1 -0
- package/dist/utils/transcript-parser.d.ts +40 -0
- package/dist/utils/transcript-parser.d.ts.map +1 -0
- package/dist/utils/transcript-parser.js +216 -0
- package/dist/utils/transcript-parser.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,iCAAiC;AACjC,OAAO,EACL,KAAK,EACL,QAAQ,EACR,UAAU,EACV,aAAa,EACb,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,UAAU,EACV,cAAc,EACd,SAAS,EACT,SAAS,GACV,MAAM,UAAU,CAAA;AAEjB,uBAAuB;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,uBAAuB;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication Middleware
|
|
3
|
+
*
|
|
4
|
+
* Provides optional API key authentication for securing endpoints.
|
|
5
|
+
* Authentication is disabled by default; enable by setting TX_API_KEY env var.
|
|
6
|
+
*/
|
|
7
|
+
import { HttpServerRequest, HttpServerResponse } from "@effect/platform";
|
|
8
|
+
import { Effect } from "effect";
|
|
9
|
+
/**
|
|
10
|
+
* Check if authentication is enabled.
|
|
11
|
+
*/
|
|
12
|
+
export declare const isAuthEnabled: () => boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Extract API key from request headers.
|
|
15
|
+
* Supports both Authorization header (Bearer token) and X-Api-Key header.
|
|
16
|
+
* @internal Exported for testing.
|
|
17
|
+
*/
|
|
18
|
+
export declare const extractApiKey: (headers: Record<string, string | undefined>) => string | null;
|
|
19
|
+
/**
|
|
20
|
+
* Constant-time string comparison to prevent timing attacks.
|
|
21
|
+
* Uses Node.js crypto.timingSafeEqual for proper constant-time comparison.
|
|
22
|
+
* @internal Exported for testing.
|
|
23
|
+
*/
|
|
24
|
+
export declare const timingSafeEqual: (provided: string, expected: string) => boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Effect HTTP authentication middleware.
|
|
27
|
+
* Only validates if TX_API_KEY environment variable is set.
|
|
28
|
+
* If not set, all requests pass through.
|
|
29
|
+
*/
|
|
30
|
+
export declare const authMiddleware: <E, R>(httpApp: import("@effect/platform/HttpApp").Default<E, R>) => Effect.Effect<HttpServerResponse.HttpServerResponse, E, R | HttpServerRequest.HttpServerRequest>;
|
|
31
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAkB,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACxF,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B;;GAEG;AACH,eAAO,MAAM,aAAa,QAAO,OAAmC,CAAA;AAEpE;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,KAAG,MAAM,GAAG,IAQpF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,UAAU,MAAM,EAAE,UAAU,MAAM,KAAG,OAQpE,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,uKA+B1B,CAAA"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication Middleware
|
|
3
|
+
*
|
|
4
|
+
* Provides optional API key authentication for securing endpoints.
|
|
5
|
+
* Authentication is disabled by default; enable by setting TX_API_KEY env var.
|
|
6
|
+
*/
|
|
7
|
+
import { timingSafeEqual as cryptoTimingSafeEqual, createHash } from "node:crypto";
|
|
8
|
+
import { HttpMiddleware, HttpServerRequest, HttpServerResponse } from "@effect/platform";
|
|
9
|
+
import { Effect } from "effect";
|
|
10
|
+
/**
|
|
11
|
+
* Check if authentication is enabled.
|
|
12
|
+
*/
|
|
13
|
+
export const isAuthEnabled = () => !!process.env.TX_API_KEY;
|
|
14
|
+
/**
|
|
15
|
+
* Extract API key from request headers.
|
|
16
|
+
* Supports both Authorization header (Bearer token) and X-Api-Key header.
|
|
17
|
+
* @internal Exported for testing.
|
|
18
|
+
*/
|
|
19
|
+
export const extractApiKey = (headers) => {
|
|
20
|
+
const xApiKey = headers["x-api-key"];
|
|
21
|
+
if (xApiKey)
|
|
22
|
+
return xApiKey;
|
|
23
|
+
const authHeader = headers["authorization"];
|
|
24
|
+
if (authHeader?.startsWith("Bearer "))
|
|
25
|
+
return authHeader.slice(7);
|
|
26
|
+
return null;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Constant-time string comparison to prevent timing attacks.
|
|
30
|
+
* Uses Node.js crypto.timingSafeEqual for proper constant-time comparison.
|
|
31
|
+
* @internal Exported for testing.
|
|
32
|
+
*/
|
|
33
|
+
export const timingSafeEqual = (provided, expected) => {
|
|
34
|
+
// Hash both inputs to fixed-length buffers to prevent leaking length information.
|
|
35
|
+
// This avoids the timing difference between the length-mismatch path
|
|
36
|
+
// (comparing expectedBuf against itself) and the normal comparison path.
|
|
37
|
+
const providedHash = createHash("sha256").update(provided).digest();
|
|
38
|
+
const expectedHash = createHash("sha256").update(expected).digest();
|
|
39
|
+
return cryptoTimingSafeEqual(providedHash, expectedHash);
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Effect HTTP authentication middleware.
|
|
43
|
+
* Only validates if TX_API_KEY environment variable is set.
|
|
44
|
+
* If not set, all requests pass through.
|
|
45
|
+
*/
|
|
46
|
+
export const authMiddleware = HttpMiddleware.make((httpApp) => Effect.gen(function* () {
|
|
47
|
+
const requiredKey = process.env.TX_API_KEY;
|
|
48
|
+
// Skip auth if no API key is configured
|
|
49
|
+
if (!requiredKey)
|
|
50
|
+
return yield* httpApp;
|
|
51
|
+
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
52
|
+
const url = request.url;
|
|
53
|
+
// Only require auth for /api routes
|
|
54
|
+
if (!url.startsWith("/api"))
|
|
55
|
+
return yield* httpApp;
|
|
56
|
+
const providedKey = extractApiKey(request.headers);
|
|
57
|
+
if (!providedKey) {
|
|
58
|
+
return yield* HttpServerResponse.json({ error: { code: "UNAUTHORIZED", message: "Missing API key. Provide via X-Api-Key header or Authorization: Bearer <key>" } }, { status: 401 }).pipe(Effect.orDie);
|
|
59
|
+
}
|
|
60
|
+
if (!timingSafeEqual(providedKey, requiredKey)) {
|
|
61
|
+
return yield* HttpServerResponse.json({ error: { code: "FORBIDDEN", message: "Invalid API key" } }, { status: 403 }).pipe(Effect.orDie);
|
|
62
|
+
}
|
|
63
|
+
return yield* httpApp;
|
|
64
|
+
}));
|
|
65
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,IAAI,qBAAqB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAClF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACxF,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAY,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAA;AAEpE;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAA2C,EAAiB,EAAE;IAC1F,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IACpC,IAAI,OAAO;QAAE,OAAO,OAAO,CAAA;IAE3B,MAAM,UAAU,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;IAC3C,IAAI,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAEjE,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,QAAgB,EAAE,QAAgB,EAAW,EAAE;IAC7E,kFAAkF;IAClF,qEAAqE;IACrE,yEAAyE;IACzE,MAAM,YAAY,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAA;IACnE,MAAM,YAAY,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAA;IAEnE,OAAO,qBAAqB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;AAC1D,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAC5D,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAA;IAE1C,wCAAwC;IACxC,IAAI,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC,CAAC,OAAO,CAAA;IAEvC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC,iBAAiB,CAAA;IAC1D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAA;IAEvB,oCAAoC;IACpC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,OAAO,CAAA;IAElD,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,OAAwD,CAAC,CAAA;IAEnG,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,KAAK,CAAC,CAAC,kBAAkB,CAAC,IAAI,CACnC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,8EAA8E,EAAE,EAAE,EAC5H,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACtB,CAAC;IAED,IAAI,CAAC,eAAe,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;QAC/C,OAAO,KAAK,CAAC,CAAC,kBAAkB,CAAC,IAAI,CACnC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,iBAAiB,EAAE,EAAE,EAC5D,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACtB,CAAC;IAED,OAAO,KAAK,CAAC,CAAC,OAAO,CAAA;AACvB,CAAC,CAAC,CACH,CAAA"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Body Size Limit Middleware
|
|
3
|
+
*
|
|
4
|
+
* Prevents DoS via memory exhaustion by enforcing request body size limits.
|
|
5
|
+
* - 1MB for standard API endpoints (tasks, learnings, runs)
|
|
6
|
+
* - 10MB for sync endpoints (bulk data import/export)
|
|
7
|
+
*
|
|
8
|
+
* Uses two mechanisms:
|
|
9
|
+
* 1. Content-Length header check for early rejection (fast path)
|
|
10
|
+
* 2. MaxBodySize context for safety during body parsing (handles chunked encoding)
|
|
11
|
+
*/
|
|
12
|
+
import { HttpServerRequest, HttpServerResponse } from "@effect/platform";
|
|
13
|
+
import { Effect } from "effect";
|
|
14
|
+
/** Default body size limit: 1MB */
|
|
15
|
+
export declare const DEFAULT_MAX_BYTES: number;
|
|
16
|
+
/** Sync endpoint body size limit: 10MB */
|
|
17
|
+
export declare const SYNC_MAX_BYTES: number;
|
|
18
|
+
/**
|
|
19
|
+
* Get the max body size limit based on the request path.
|
|
20
|
+
* Sync endpoints get a higher limit (10MB) since they handle bulk data.
|
|
21
|
+
* All other endpoints get 1MB.
|
|
22
|
+
* @internal Exported for testing.
|
|
23
|
+
*/
|
|
24
|
+
export declare const getMaxBytes: (url: string) => number;
|
|
25
|
+
/**
|
|
26
|
+
* Body size limit middleware.
|
|
27
|
+
*
|
|
28
|
+
* Rejects requests with Content-Length exceeding the limit with 413 Payload Too Large.
|
|
29
|
+
* Also sets MaxBodySize context as a safety net during body parsing
|
|
30
|
+
* (handles chunked transfer encoding where Content-Length is absent).
|
|
31
|
+
*/
|
|
32
|
+
export declare const bodyLimitMiddleware: <E, R>(httpApp: import("@effect/platform/HttpApp").Default<E, R>) => Effect.Effect<HttpServerResponse.HttpServerResponse, E, HttpServerRequest.HttpServerRequest | R>;
|
|
33
|
+
//# sourceMappingURL=body-limit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body-limit.d.ts","sourceRoot":"","sources":["../../src/middleware/body-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAkB,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAExF,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAA;AAEvC,mCAAmC;AACnC,eAAO,MAAM,iBAAiB,QAAkB,CAAA;AAEhD,0CAA0C;AAC1C,eAAO,MAAM,cAAc,QAAmB,CAAA;AAE9C;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,MAGzC,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,uKAmB/B,CAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Body Size Limit Middleware
|
|
3
|
+
*
|
|
4
|
+
* Prevents DoS via memory exhaustion by enforcing request body size limits.
|
|
5
|
+
* - 1MB for standard API endpoints (tasks, learnings, runs)
|
|
6
|
+
* - 10MB for sync endpoints (bulk data import/export)
|
|
7
|
+
*
|
|
8
|
+
* Uses two mechanisms:
|
|
9
|
+
* 1. Content-Length header check for early rejection (fast path)
|
|
10
|
+
* 2. MaxBodySize context for safety during body parsing (handles chunked encoding)
|
|
11
|
+
*/
|
|
12
|
+
import { HttpMiddleware, HttpServerRequest, HttpServerResponse } from "@effect/platform";
|
|
13
|
+
import * as IncomingMessage from "@effect/platform/HttpIncomingMessage";
|
|
14
|
+
import { Effect, Option } from "effect";
|
|
15
|
+
/** Default body size limit: 1MB */
|
|
16
|
+
export const DEFAULT_MAX_BYTES = 1 * 1024 * 1024;
|
|
17
|
+
/** Sync endpoint body size limit: 10MB */
|
|
18
|
+
export const SYNC_MAX_BYTES = 10 * 1024 * 1024;
|
|
19
|
+
/**
|
|
20
|
+
* Get the max body size limit based on the request path.
|
|
21
|
+
* Sync endpoints get a higher limit (10MB) since they handle bulk data.
|
|
22
|
+
* All other endpoints get 1MB.
|
|
23
|
+
* @internal Exported for testing.
|
|
24
|
+
*/
|
|
25
|
+
export const getMaxBytes = (url) => {
|
|
26
|
+
if (url.startsWith("/api/sync"))
|
|
27
|
+
return SYNC_MAX_BYTES;
|
|
28
|
+
return DEFAULT_MAX_BYTES;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Body size limit middleware.
|
|
32
|
+
*
|
|
33
|
+
* Rejects requests with Content-Length exceeding the limit with 413 Payload Too Large.
|
|
34
|
+
* Also sets MaxBodySize context as a safety net during body parsing
|
|
35
|
+
* (handles chunked transfer encoding where Content-Length is absent).
|
|
36
|
+
*/
|
|
37
|
+
export const bodyLimitMiddleware = HttpMiddleware.make((httpApp) => Effect.gen(function* () {
|
|
38
|
+
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
39
|
+
const maxBytes = getMaxBytes(request.url);
|
|
40
|
+
const contentLength = request.headers["content-length"];
|
|
41
|
+
if (contentLength) {
|
|
42
|
+
const size = parseInt(contentLength, 10);
|
|
43
|
+
if (!isNaN(size) && size > maxBytes) {
|
|
44
|
+
return yield* HttpServerResponse.json({ error: { code: "PAYLOAD_TOO_LARGE", message: `Request body exceeds maximum size of ${maxBytes} bytes` } }, { status: 413 }).pipe(Effect.orDie);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Set MaxBodySize for safety during body parsing (handles chunked transfer encoding)
|
|
48
|
+
return yield* IncomingMessage.withMaxBodySize(httpApp, Option.some(maxBytes));
|
|
49
|
+
}));
|
|
50
|
+
//# sourceMappingURL=body-limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body-limit.js","sourceRoot":"","sources":["../../src/middleware/body-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACxF,OAAO,KAAK,eAAe,MAAM,sCAAsC,CAAA;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEvC,mCAAmC;AACnC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAA;AAEhD,0CAA0C;AAC1C,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;AAE9C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAW,EAAU,EAAE;IACjD,IAAI,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,cAAc,CAAA;IACtD,OAAO,iBAAiB,CAAA;AAC1B,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CACjE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC,iBAAiB,CAAA;IAC1D,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAEzC,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACvD,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC,CAAA;QACxC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,QAAQ,EAAE,CAAC;YACpC,OAAO,KAAK,CAAC,CAAC,kBAAkB,CAAC,IAAI,CACnC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,wCAAwC,QAAQ,QAAQ,EAAE,EAAE,EAC3G,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;IAED,qFAAqF;IACrF,OAAO,KAAK,CAAC,CAAC,eAAe,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;AAC/E,CAAC,CAAC,CACH,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CORS Configuration
|
|
3
|
+
*
|
|
4
|
+
* Provides CORS configuration for the API server.
|
|
5
|
+
* Default: localhost-only origins. Set TX_API_CORS_ORIGIN="*" for wildcard (not recommended in production).
|
|
6
|
+
*/
|
|
7
|
+
export declare const getCorsConfig: () => {
|
|
8
|
+
allowedOrigins: string[];
|
|
9
|
+
allowedMethods: readonly ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"];
|
|
10
|
+
allowedHeaders: string[];
|
|
11
|
+
exposedHeaders: string[];
|
|
12
|
+
maxAge: number;
|
|
13
|
+
credentials: boolean;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=cors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,eAAO,MAAM,aAAa;;;;;;;CAczB,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CORS Configuration
|
|
3
|
+
*
|
|
4
|
+
* Provides CORS configuration for the API server.
|
|
5
|
+
* Default: localhost-only origins. Set TX_API_CORS_ORIGIN="*" for wildcard (not recommended in production).
|
|
6
|
+
*/
|
|
7
|
+
/** Default CORS origins: localhost on common dev ports. Never wildcard by default. */
|
|
8
|
+
const DEFAULT_CORS_ORIGINS = [
|
|
9
|
+
"http://localhost:3000",
|
|
10
|
+
"http://localhost:3001",
|
|
11
|
+
"http://localhost:5173",
|
|
12
|
+
"http://127.0.0.1:3000",
|
|
13
|
+
"http://127.0.0.1:3001",
|
|
14
|
+
"http://127.0.0.1:5173",
|
|
15
|
+
];
|
|
16
|
+
export const getCorsConfig = () => {
|
|
17
|
+
const originEnv = process.env.TX_API_CORS_ORIGIN;
|
|
18
|
+
return {
|
|
19
|
+
allowedOrigins: originEnv
|
|
20
|
+
? originEnv === "*"
|
|
21
|
+
? ["*"]
|
|
22
|
+
: originEnv.split(",").map((o) => o.trim())
|
|
23
|
+
: DEFAULT_CORS_ORIGINS,
|
|
24
|
+
allowedMethods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
|
|
25
|
+
allowedHeaders: ["Content-Type", "Authorization", "X-Api-Key"],
|
|
26
|
+
exposedHeaders: ["X-Total-Count", "X-Next-Cursor"],
|
|
27
|
+
maxAge: 86400,
|
|
28
|
+
credentials: process.env.TX_API_CORS_CREDENTIALS === "true",
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=cors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,sFAAsF;AACtF,MAAM,oBAAoB,GAAG;IAC3B,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;CACxB,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,EAAE;IAChC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAA;IAChD,OAAO;QACL,cAAc,EAAE,SAAS;YACvB,CAAC,CAAC,SAAS,KAAK,GAAG;gBACjB,CAAC,CAAC,CAAC,GAAY,CAAC;gBAChB,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC7C,CAAC,CAAC,oBAAoB;QACxB,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAU;QAC7E,cAAc,EAAE,CAAC,cAAc,EAAE,eAAe,EAAE,WAAW,CAAC;QAC9D,cAAc,EAAE,CAAC,eAAe,EAAE,eAAe,CAAC;QAClD,MAAM,EAAE,KAAK;QACb,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,MAAM;KAC5D,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Handling Middleware
|
|
3
|
+
*
|
|
4
|
+
* Provides consistent error responses across all API endpoints.
|
|
5
|
+
*/
|
|
6
|
+
import type { Context, Next } from "hono";
|
|
7
|
+
/**
|
|
8
|
+
* Standard API error response format.
|
|
9
|
+
*/
|
|
10
|
+
export interface ApiError {
|
|
11
|
+
error: {
|
|
12
|
+
code: string;
|
|
13
|
+
message: string;
|
|
14
|
+
details?: unknown;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Global error handling middleware.
|
|
19
|
+
* Catches all errors and returns consistent JSON responses.
|
|
20
|
+
*/
|
|
21
|
+
export declare const errorHandler: (c: Context, next: Next) => Promise<Response>;
|
|
22
|
+
/**
|
|
23
|
+
* Not found handler for undefined routes.
|
|
24
|
+
*/
|
|
25
|
+
export declare const notFoundHandler: (c: Context) => Response;
|
|
26
|
+
//# sourceMappingURL=error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/middleware/error.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAIzC;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,CAAC,EAAE,OAAO,CAAA;KAClB,CAAA;CACF;AA6CD;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAU,GAAG,OAAO,EAAE,MAAM,IAAI,KAAG,OAAO,CAAC,QAAQ,CAyB3E,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,GAAG,OAAO,KAAG,QAU5C,CAAA"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Handling Middleware
|
|
3
|
+
*
|
|
4
|
+
* Provides consistent error responses across all API endpoints.
|
|
5
|
+
*/
|
|
6
|
+
import { HTTPException } from "hono/http-exception";
|
|
7
|
+
/**
|
|
8
|
+
* Map error types to HTTP status codes.
|
|
9
|
+
*/
|
|
10
|
+
const getStatusCode = (error) => {
|
|
11
|
+
if (error instanceof HTTPException) {
|
|
12
|
+
return error.status;
|
|
13
|
+
}
|
|
14
|
+
// Handle tx-core errors by name
|
|
15
|
+
if (error && typeof error === "object" && "_tag" in error) {
|
|
16
|
+
const tag = error._tag;
|
|
17
|
+
switch (tag) {
|
|
18
|
+
case "TaskNotFoundError":
|
|
19
|
+
case "LearningNotFoundError":
|
|
20
|
+
case "FileLearningNotFoundError":
|
|
21
|
+
case "AttemptNotFoundError":
|
|
22
|
+
return 404;
|
|
23
|
+
case "ValidationError":
|
|
24
|
+
case "CircularDependencyError":
|
|
25
|
+
return 400;
|
|
26
|
+
case "DatabaseError":
|
|
27
|
+
return 500;
|
|
28
|
+
case "EmbeddingUnavailableError":
|
|
29
|
+
return 503;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return 500;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Extract error code from various error types.
|
|
36
|
+
*/
|
|
37
|
+
const getErrorCode = (error) => {
|
|
38
|
+
if (error && typeof error === "object" && "_tag" in error) {
|
|
39
|
+
return error._tag;
|
|
40
|
+
}
|
|
41
|
+
if (error instanceof HTTPException) {
|
|
42
|
+
return `HTTP_${error.status}`;
|
|
43
|
+
}
|
|
44
|
+
return "INTERNAL_ERROR";
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Global error handling middleware.
|
|
48
|
+
* Catches all errors and returns consistent JSON responses.
|
|
49
|
+
*/
|
|
50
|
+
export const errorHandler = async (c, next) => {
|
|
51
|
+
try {
|
|
52
|
+
await next();
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
const status = getStatusCode(error);
|
|
56
|
+
const code = getErrorCode(error);
|
|
57
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
58
|
+
const body = {
|
|
59
|
+
error: {
|
|
60
|
+
code,
|
|
61
|
+
message
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
// Include details for validation errors
|
|
65
|
+
if (error && typeof error === "object" && "details" in error) {
|
|
66
|
+
body.error.details = error.details;
|
|
67
|
+
}
|
|
68
|
+
return c.json(body, status);
|
|
69
|
+
}
|
|
70
|
+
// If no response was set by handler, return the response from context
|
|
71
|
+
return c.res;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Not found handler for undefined routes.
|
|
75
|
+
*/
|
|
76
|
+
export const notFoundHandler = (c) => {
|
|
77
|
+
return c.json({
|
|
78
|
+
error: {
|
|
79
|
+
code: "NOT_FOUND",
|
|
80
|
+
message: `Route ${c.req.method} ${c.req.path} not found`
|
|
81
|
+
}
|
|
82
|
+
}, 404);
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/middleware/error.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAanD;;GAEG;AACH,MAAM,aAAa,GAAG,CAAC,KAAc,EAAwB,EAAE;IAC7D,IAAI,KAAK,YAAY,aAAa,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC,MAA8B,CAAA;IAC7C,CAAC;IAED,gCAAgC;IAChC,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;QAC1D,MAAM,GAAG,GAAI,KAA0B,CAAC,IAAI,CAAA;QAC5C,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,mBAAmB,CAAC;YACzB,KAAK,uBAAuB,CAAC;YAC7B,KAAK,2BAA2B,CAAC;YACjC,KAAK,sBAAsB;gBACzB,OAAO,GAAG,CAAA;YACZ,KAAK,iBAAiB,CAAC;YACvB,KAAK,yBAAyB;gBAC5B,OAAO,GAAG,CAAA;YACZ,KAAK,eAAe;gBAClB,OAAO,GAAG,CAAA;YACZ,KAAK,2BAA2B;gBAC9B,OAAO,GAAG,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,YAAY,GAAG,CAAC,KAAc,EAAU,EAAE;IAC9C,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;QAC1D,OAAQ,KAA0B,CAAC,IAAI,CAAA;IACzC,CAAC;IACD,IAAI,KAAK,YAAY,aAAa,EAAE,CAAC;QACnC,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAA;IAC/B,CAAC;IACD,OAAO,gBAAgB,CAAA;AACzB,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,CAAU,EAAE,IAAU,EAAqB,EAAE;IAC9E,IAAI,CAAC;QACH,MAAM,IAAI,EAAE,CAAA;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CAAA;QACnC,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;QAChC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAEtE,MAAM,IAAI,GAAa;YACrB,KAAK,EAAE;gBACL,IAAI;gBACJ,OAAO;aACR;SACF,CAAA;QAED,wCAAwC;QACxC,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;YAC7D,IAAI,CAAC,KAAK,CAAC,OAAO,GAAI,KAA8B,CAAC,OAAO,CAAA;QAC9D,CAAC;QAED,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IAC7B,CAAC;IAED,sEAAsE;IACtE,OAAO,CAAC,CAAC,GAAG,CAAA;AACd,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAU,EAAY,EAAE;IACtD,OAAO,CAAC,CAAC,IAAI,CACX;QACE,KAAK,EAAE;YACL,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,SAAS,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,YAAY;SACzD;KACiB,EACpB,GAAG,CACJ,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate Limiting Middleware
|
|
3
|
+
*
|
|
4
|
+
* Provides configurable rate limiting to protect the API from abuse.
|
|
5
|
+
* Uses a sliding window algorithm with in-memory storage.
|
|
6
|
+
*
|
|
7
|
+
* Rate limiting is disabled by default; enable by setting TX_API_RATE_LIMIT env var.
|
|
8
|
+
*
|
|
9
|
+
* SECURITY NOTE: By default, proxy headers (X-Forwarded-For, X-Real-IP) are NOT trusted.
|
|
10
|
+
* Set TX_API_TRUST_PROXY=true ONLY when running behind a trusted reverse proxy.
|
|
11
|
+
* Otherwise, attackers can bypass rate limiting by spoofing these headers.
|
|
12
|
+
*/
|
|
13
|
+
import type { Context, Next } from "hono";
|
|
14
|
+
/**
|
|
15
|
+
* Rate limit configuration options.
|
|
16
|
+
*/
|
|
17
|
+
export interface RateLimitConfig {
|
|
18
|
+
/** Maximum requests per window (default: 100) */
|
|
19
|
+
max: number;
|
|
20
|
+
/** Window size in seconds (default: 60) */
|
|
21
|
+
windowSec: number;
|
|
22
|
+
/** Message to return when rate limited */
|
|
23
|
+
message: string;
|
|
24
|
+
/** Whether to skip rate limiting for health endpoints */
|
|
25
|
+
skipHealthEndpoints: boolean;
|
|
26
|
+
/** Whether to trust proxy headers like X-Forwarded-For (default: false for security) */
|
|
27
|
+
trustProxy: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if rate limiting is enabled.
|
|
31
|
+
*/
|
|
32
|
+
export declare const isRateLimitEnabled: () => boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Check if proxy headers should be trusted.
|
|
35
|
+
* Only enable this when running behind a trusted reverse proxy.
|
|
36
|
+
*/
|
|
37
|
+
export declare const isTrustProxyEnabled: () => boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Rate limiting middleware.
|
|
40
|
+
* Only applies rate limiting if TX_API_RATE_LIMIT environment variable is set.
|
|
41
|
+
* If not set, all requests are allowed through.
|
|
42
|
+
*/
|
|
43
|
+
export declare const rateLimitMiddleware: (c: Context, next: Next) => Promise<void | Response>;
|
|
44
|
+
/**
|
|
45
|
+
* Create rate limit middleware with custom configuration.
|
|
46
|
+
* Useful for applying different limits to specific routes.
|
|
47
|
+
*/
|
|
48
|
+
export declare const createRateLimitMiddleware: (customConfig: Partial<RateLimitConfig>) => (c: Context, next: Next) => Promise<void | Response>;
|
|
49
|
+
/**
|
|
50
|
+
* Reset rate limit for a specific client.
|
|
51
|
+
* Useful for testing or administrative purposes.
|
|
52
|
+
*/
|
|
53
|
+
export declare const resetRateLimit: (clientId: string) => void;
|
|
54
|
+
/**
|
|
55
|
+
* Clear all rate limit entries.
|
|
56
|
+
* Useful for testing.
|
|
57
|
+
*/
|
|
58
|
+
export declare const clearAllRateLimits: () => void;
|
|
59
|
+
//# sourceMappingURL=rate-limit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAIzC;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAA;IACX,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAA;IACjB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAA;IACf,yDAAyD;IACzD,mBAAmB,EAAE,OAAO,CAAA;IAC5B,wFAAwF;IACxF,UAAU,EAAE,OAAO,CAAA;CACpB;AA6DD;;GAEG;AACH,eAAO,MAAM,kBAAkB,QAAO,OAErC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,QAAO,OAEtC,CAAA;AA0JD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAU,GAAG,OAAO,EAAE,MAAM,IAAI,KAAG,OAAO,CAAC,IAAI,GAAG,QAAQ,CA2CzF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB,GAAI,cAAc,OAAO,CAAC,eAAe,CAAC,MAGhE,GAAG,OAAO,EAAE,MAAM,IAAI,KAAG,OAAO,CAAC,IAAI,GAAG,QAAQ,CAqD/D,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,UAAU,MAAM,KAAG,IAEjD,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,IAErC,CAAA"}
|