@farm.js/core 0.1.0-beta.16 → 0.1.0-beta.17
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/after.d.mts +25 -0
- package/dist/after.d.ts +25 -0
- package/dist/agent-runtime.d.mts +96 -0
- package/dist/agent-runtime.d.ts +96 -0
- package/dist/api/route-manager.d.mts +66 -0
- package/dist/api/route-manager.d.ts +66 -0
- package/dist/api/runtime.d.mts +3 -0
- package/dist/api/runtime.d.ts +3 -0
- package/dist/api.d.mts +48 -0
- package/dist/api.d.ts +48 -0
- package/dist/app-B0tE1I3o.d.ts +306 -0
- package/dist/app-Dv2JJb7X.d.mts +306 -0
- package/dist/app-markdown.d.mts +24 -0
- package/dist/app-markdown.d.ts +24 -0
- package/dist/cache.d.mts +192 -0
- package/dist/cache.d.ts +192 -0
- package/dist/{chunk-AN3PQVKH.mjs → chunk-2FLBZFPG.mjs} +9 -7
- package/dist/chunk-2FLBZFPG.mjs.map +1 -0
- package/dist/chunk-E257KFBU.mjs +227 -0
- package/dist/chunk-E257KFBU.mjs.map +1 -0
- package/dist/{chunk-SLDBGSC3.mjs → chunk-JAEAE27K.mjs} +2 -2
- package/dist/{chunk-T2KL7VEL.mjs → chunk-PZXBQKCH.mjs} +13 -4
- package/dist/chunk-PZXBQKCH.mjs.map +1 -0
- package/dist/{chunk-UXUAWNO5.mjs → chunk-RIXKJPGI.mjs} +117 -55
- package/dist/chunk-RIXKJPGI.mjs.map +1 -0
- package/dist/{chunk-OSWV5IJB.mjs → chunk-T2M5QANG.mjs} +32 -9
- package/dist/chunk-T2M5QANG.mjs.map +1 -0
- package/dist/{chunk-BWJC5ZOD.mjs → chunk-VFDBC3W7.mjs} +2 -2
- package/dist/{chunk-BWJC5ZOD.mjs.map → chunk-VFDBC3W7.mjs.map} +1 -1
- package/dist/chunk-recovery-lnQFzcQP.d.mts +26 -0
- package/dist/chunk-recovery-lnQFzcQP.d.ts +26 -0
- package/dist/client-BT1mFQas.d.mts +447 -0
- package/dist/client-Nn0q4eO4.d.ts +447 -0
- package/dist/client-cache-CIlyBlmx.d.ts +6 -0
- package/dist/client-cache-D-EZ7XVW.d.mts +6 -0
- package/dist/client-plugins-278AvYHE.d.mts +2021 -0
- package/dist/client-plugins-CTQAkr7R.d.ts +2021 -0
- package/dist/client-plugins.d.mts +24 -0
- package/dist/client-plugins.d.ts +24 -0
- package/dist/client.d.mts +452 -0
- package/dist/client.d.ts +452 -0
- package/dist/config.d.mts +31 -0
- package/dist/config.d.ts +31 -0
- package/dist/cron.d.mts +78 -0
- package/dist/cron.d.ts +78 -0
- package/dist/deferred.d.mts +42 -0
- package/dist/deferred.d.ts +42 -0
- package/dist/deployment.d.mts +36 -0
- package/dist/deployment.d.ts +36 -0
- package/dist/{devtools-E4YNCY5J.mjs → devtools-K2ERKGNI.mjs} +3 -3
- package/dist/docs.cjs.map +1 -1
- package/dist/docs.d.mts +80 -0
- package/dist/docs.d.ts +80 -0
- package/dist/docs.mjs +3 -3
- package/dist/env-types.d.mts +12 -0
- package/dist/env-types.d.ts +12 -0
- package/dist/env.d.mts +45 -0
- package/dist/env.d.ts +45 -0
- package/dist/environment/vite.d.mts +22 -0
- package/dist/environment/vite.d.ts +22 -0
- package/dist/environment.d.mts +18 -0
- package/dist/environment.d.ts +18 -0
- package/dist/font.d.mts +95 -0
- package/dist/font.d.ts +95 -0
- package/dist/headers.d.mts +22 -0
- package/dist/headers.d.ts +22 -0
- package/dist/i18n/client.d.mts +32 -0
- package/dist/i18n/client.d.ts +32 -0
- package/dist/i18n/index.d.mts +20 -0
- package/dist/i18n/index.d.ts +20 -0
- package/dist/i18n/server.d.mts +30 -0
- package/dist/i18n/server.d.ts +30 -0
- package/dist/image/server.d.mts +37 -0
- package/dist/image/server.d.ts +37 -0
- package/dist/image/sharp.d.mts +7 -0
- package/dist/image/sharp.d.ts +7 -0
- package/dist/image-config-Duob7wER.d.mts +50 -0
- package/dist/image-config-Duob7wER.d.ts +50 -0
- package/dist/image.d.mts +39 -0
- package/dist/image.d.ts +39 -0
- package/dist/index.cjs +293 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +477 -0
- package/dist/index.d.ts +477 -0
- package/dist/index.mjs +22 -18
- package/dist/index.mjs.map +1 -1
- package/dist/integration-api-CHT2OKAf.d.mts +93 -0
- package/dist/integration-api-CHT2OKAf.d.ts +93 -0
- package/dist/integrations.d.mts +24 -0
- package/dist/integrations.d.ts +24 -0
- package/dist/internal/build-runtime.cjs +306 -137
- package/dist/internal/build-runtime.cjs.map +1 -1
- package/dist/internal/build-runtime.d.mts +41 -0
- package/dist/internal/build-runtime.d.ts +41 -0
- package/dist/internal/build-runtime.mjs +7 -7
- package/dist/internal/client-runtime.d.mts +17 -0
- package/dist/internal/client-runtime.d.ts +17 -0
- package/dist/internal/config-runtime.cjs +140 -1
- package/dist/internal/config-runtime.cjs.map +1 -1
- package/dist/internal/config-runtime.d.mts +41 -0
- package/dist/internal/config-runtime.d.ts +41 -0
- package/dist/internal/config-runtime.mjs +2 -2
- package/dist/internal/metadata-image-runtime.d.mts +25 -0
- package/dist/internal/metadata-image-runtime.d.ts +25 -0
- package/dist/internal/production-node-env.d.mts +12 -0
- package/dist/internal/production-node-env.d.ts +12 -0
- package/dist/internal/production-runtime.d.mts +44 -0
- package/dist/internal/production-runtime.d.ts +44 -0
- package/dist/island-CfGru1MO.d.mts +9 -0
- package/dist/island-CfGru1MO.d.ts +9 -0
- package/dist/markdown.d.mts +60 -0
- package/dist/markdown.d.ts +60 -0
- package/dist/metadata-DmCudMw_.d.mts +22 -0
- package/dist/metadata-xghtOlbR.d.ts +22 -0
- package/dist/middleware.cjs +116 -98
- package/dist/middleware.cjs.map +1 -1
- package/dist/middleware.d.mts +171 -0
- package/dist/middleware.d.ts +171 -0
- package/dist/middleware.mjs +5 -2
- package/dist/navigation-errors-Dvwpzaer.d.mts +13 -0
- package/dist/navigation-errors-Dvwpzaer.d.ts +13 -0
- package/dist/navigation.d.mts +14 -0
- package/dist/navigation.d.ts +14 -0
- package/dist/observability.d.mts +335 -0
- package/dist/observability.d.ts +335 -0
- package/dist/params-BALtrRim.d.ts +15 -0
- package/dist/params-ry-lxqmy.d.mts +15 -0
- package/dist/plugin-BJDf43dc.d.mts +165 -0
- package/dist/plugin-BJDf43dc.d.ts +165 -0
- package/dist/plugin.cjs +132 -0
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.mts +24 -0
- package/dist/plugin.d.ts +24 -0
- package/dist/plugin.mjs +4 -4
- package/dist/production-runtime-BLxSv9cU.d.ts +79 -0
- package/dist/production-runtime-DFN2_RXq.d.mts +79 -0
- package/dist/query/client.d.mts +61 -0
- package/dist/query/client.d.ts +61 -0
- package/dist/query/index.d.mts +90 -0
- package/dist/query/index.d.ts +90 -0
- package/dist/query/parsers.d.mts +25 -0
- package/dist/query/parsers.d.ts +25 -0
- package/dist/query/server.d.mts +55 -0
- package/dist/query/server.d.ts +55 -0
- package/dist/request-Cq5d6qmE.d.mts +6 -0
- package/dist/request-LoxDW3lp.d.ts +6 -0
- package/dist/request.d.mts +25 -0
- package/dist/request.d.ts +25 -0
- package/dist/resolver-DJqjLMg_.d.mts +14 -0
- package/dist/resolver-IH4RmPEl.d.ts +14 -0
- package/dist/route-runtime-DoOHzCAD.d.mts +38 -0
- package/dist/route-runtime-DoOHzCAD.d.ts +38 -0
- package/dist/router.d.mts +36 -0
- package/dist/router.d.ts +36 -0
- package/dist/routes.d.mts +226 -0
- package/dist/routes.d.ts +226 -0
- package/dist/runtime-BA9TOSu1.d.mts +231 -0
- package/dist/runtime-Cxpq6xZN.d.mts +27 -0
- package/dist/runtime-DTAQ2HDv.d.ts +231 -0
- package/dist/runtime-bv63eUiO.d.ts +27 -0
- package/dist/server-action-security.d.mts +45 -0
- package/dist/server-action-security.d.ts +45 -0
- package/dist/server-fn-client.d.mts +33 -0
- package/dist/server-fn-client.d.ts +33 -0
- package/dist/server-fn-error-DDh14a0V.d.mts +26 -0
- package/dist/server-fn-error-DDh14a0V.d.ts +26 -0
- package/dist/server-fn.d.mts +121 -0
- package/dist/server-fn.d.ts +121 -0
- package/dist/server-plugins.d.mts +57 -0
- package/dist/server-plugins.d.ts +57 -0
- package/dist/server-query-client.d.mts +51 -0
- package/dist/server-query-client.d.ts +51 -0
- package/dist/server-query.d.mts +37 -0
- package/dist/server-query.d.ts +37 -0
- package/dist/server.cjs +170 -3
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.mts +51 -0
- package/dist/server.d.ts +51 -0
- package/dist/server.mjs +6 -6
- package/dist/storage.d.mts +52 -0
- package/dist/storage.d.ts +52 -0
- package/dist/testing.d.mts +103 -0
- package/dist/testing.d.ts +103 -0
- package/dist/transport-BmbGTXA5.d.mts +49 -0
- package/dist/transport-BmbGTXA5.d.ts +49 -0
- package/dist/types-BMxWr97v.d.mts +81 -0
- package/dist/types-BMxWr97v.d.ts +81 -0
- package/dist/types-D1A6-XvH.d.mts +73 -0
- package/dist/types-D1A6-XvH.d.ts +73 -0
- package/dist/types-DTzm4TCl.d.mts +78 -0
- package/dist/types-DTzm4TCl.d.ts +78 -0
- package/dist/utils-B6GaYNJL.d.ts +23 -0
- package/dist/utils-CKSHiip6.d.mts +23 -0
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.mts +3 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.mjs +1 -1
- package/dist/vite.cjs +140 -2
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.mts +24 -0
- package/dist/vite.d.ts +24 -0
- package/dist/vite.mjs +4 -4
- package/dist/workflows.d.mts +110 -0
- package/dist/workflows.d.ts +110 -0
- package/package.json +1 -1
- package/types/middleware.d.ts +36 -11
- package/dist/chunk-AN3PQVKH.mjs.map +0 -1
- package/dist/chunk-I4CUBGVF.mjs +0 -93
- package/dist/chunk-I4CUBGVF.mjs.map +0 -1
- package/dist/chunk-OSWV5IJB.mjs.map +0 -1
- package/dist/chunk-T2KL7VEL.mjs.map +0 -1
- package/dist/chunk-UXUAWNO5.mjs.map +0 -1
- /package/dist/{chunk-SLDBGSC3.mjs.map → chunk-JAEAE27K.mjs.map} +0 -0
- /package/dist/{devtools-E4YNCY5J.mjs.map → devtools-K2ERKGNI.mjs.map} +0 -0
package/dist/middleware.cjs
CHANGED
|
@@ -32,6 +32,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
32
32
|
var middleware_exports = {};
|
|
33
33
|
__export(middleware_exports, {
|
|
34
34
|
MiddlewareManager: () => MiddlewareManager,
|
|
35
|
+
UnsupportedRateLimitStorageError: () => UnsupportedRateLimitStorageError,
|
|
35
36
|
_runWithMiddlewareContext: () => _runWithMiddlewareContext,
|
|
36
37
|
_runWithMiddlewareData: () => _runWithMiddlewareData,
|
|
37
38
|
applyProductionMiddlewareHeaders: () => applyProductionMiddlewareHeaders,
|
|
@@ -44,89 +45,76 @@ __export(middleware_exports, {
|
|
|
44
45
|
getMiddlewareValue: () => getMiddlewareValue,
|
|
45
46
|
getRateLimitStatus: () => getRateLimitStatus,
|
|
46
47
|
hasMiddlewareData: () => hasMiddlewareData,
|
|
48
|
+
memoryRateLimitStorage: () => memoryRateLimitStorage,
|
|
47
49
|
middleware: () => middleware,
|
|
48
50
|
unwrapMiddleware: () => unwrapMiddleware
|
|
49
51
|
});
|
|
50
52
|
module.exports = __toCommonJS(middleware_exports);
|
|
51
53
|
|
|
52
|
-
// src/
|
|
53
|
-
var
|
|
54
|
-
var
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
__name(createMemoryStorage, "createMemoryStorage");
|
|
61
|
-
var GLOBAL_STORAGE_KEY = /* @__PURE__ */ Symbol.for("farmjs.storage.global");
|
|
62
|
-
function readGlobalStorage() {
|
|
63
|
-
return globalThis[GLOBAL_STORAGE_KEY];
|
|
64
|
-
}
|
|
65
|
-
__name(readGlobalStorage, "readGlobalStorage");
|
|
66
|
-
function writeGlobalStorage(storage) {
|
|
67
|
-
globalThis[GLOBAL_STORAGE_KEY] = storage;
|
|
68
|
-
return storage;
|
|
69
|
-
}
|
|
70
|
-
__name(writeGlobalStorage, "writeGlobalStorage");
|
|
71
|
-
function getActiveGlobalStorage() {
|
|
72
|
-
const existing = readGlobalStorage();
|
|
73
|
-
if (existing) {
|
|
74
|
-
return existing;
|
|
54
|
+
// src/middleware/chain.ts
|
|
55
|
+
var DEFAULT_MEMORY_RATE_LIMIT_ENTRIES = 1e5;
|
|
56
|
+
var _UnsupportedRateLimitStorageError = class _UnsupportedRateLimitStorageError extends TypeError {
|
|
57
|
+
constructor() {
|
|
58
|
+
super(
|
|
59
|
+
"RateLimitStorage must implement atomic increment(key, windowMs). Legacy get/set adapters can lose increments under concurrency. Use memoryRateLimitStorage() for one process or redisRateLimitStorage() from @farm.js/cache-redis for production."
|
|
60
|
+
);
|
|
61
|
+
this.name = "UnsupportedRateLimitStorageError";
|
|
75
62
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
63
|
+
};
|
|
64
|
+
__name(_UnsupportedRateLimitStorageError, "UnsupportedRateLimitStorageError");
|
|
65
|
+
var UnsupportedRateLimitStorageError = _UnsupportedRateLimitStorageError;
|
|
66
|
+
function memoryRateLimitStorage(options = {}) {
|
|
67
|
+
const maxEntries = options.maxEntries ?? DEFAULT_MEMORY_RATE_LIMIT_ENTRIES;
|
|
68
|
+
if (!Number.isSafeInteger(maxEntries) || maxEntries <= 0) {
|
|
69
|
+
throw new TypeError("memoryRateLimitStorage maxEntries must be a positive safe integer.");
|
|
70
|
+
}
|
|
71
|
+
const records = /* @__PURE__ */ new Map();
|
|
72
|
+
function read(key, now) {
|
|
73
|
+
const record = records.get(key);
|
|
74
|
+
if (!record) return null;
|
|
75
|
+
if (record.resetAt <= now) {
|
|
76
|
+
records.delete(key);
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
return record;
|
|
80
|
+
}
|
|
81
|
+
__name(read, "read");
|
|
82
|
+
function pruneExpired(now) {
|
|
83
|
+
for (const [key, record] of records) {
|
|
84
|
+
if (record.resetAt <= now) records.delete(key);
|
|
85
|
+
}
|
|
89
86
|
}
|
|
90
|
-
|
|
87
|
+
__name(pruneExpired, "pruneExpired");
|
|
91
88
|
return {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
increment(key, windowMs) {
|
|
90
|
+
if (!Number.isSafeInteger(windowMs) || windowMs <= 0) {
|
|
91
|
+
throw new TypeError("Rate-limit windowMs must be a positive safe integer.");
|
|
92
|
+
}
|
|
93
|
+
const now = Date.now();
|
|
94
|
+
const current = read(key, now);
|
|
95
|
+
if (current) {
|
|
96
|
+
const next2 = { count: current.count + 1, resetAt: current.resetAt };
|
|
97
|
+
records.set(key, next2);
|
|
98
|
+
return next2;
|
|
99
|
+
}
|
|
100
|
+
if (records.size >= maxEntries) pruneExpired(now);
|
|
101
|
+
if (records.size >= maxEntries) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
`Process-local rate-limit storage reached its ${maxEntries} active-key capacity. Configure a shared production adapter or increase maxEntries.`
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
const next = { count: 1, resetAt: now + windowMs };
|
|
107
|
+
records.set(key, next);
|
|
108
|
+
return next;
|
|
109
|
+
},
|
|
110
|
+
get(key) {
|
|
111
|
+
const record = read(key, Date.now());
|
|
112
|
+
return record ? { ...record } : null;
|
|
96
113
|
}
|
|
97
114
|
};
|
|
98
115
|
}
|
|
99
|
-
__name(
|
|
100
|
-
|
|
101
|
-
// src/middleware/chain.ts
|
|
102
|
-
function getRateLimitStorage() {
|
|
103
|
-
return getStorage("ratelimit");
|
|
104
|
-
}
|
|
105
|
-
__name(getRateLimitStorage, "getRateLimitStorage");
|
|
106
|
-
var defaultRateLimitStorage = {
|
|
107
|
-
async get(key) {
|
|
108
|
-
const storage = getRateLimitStorage();
|
|
109
|
-
const value = await storage.getItem(key);
|
|
110
|
-
return value ?? null;
|
|
111
|
-
},
|
|
112
|
-
async set(key, value, ttl) {
|
|
113
|
-
const storage = getRateLimitStorage();
|
|
114
|
-
await storage.setItem(key, value, ttl ? { ttl } : void 0);
|
|
115
|
-
},
|
|
116
|
-
async delete(key) {
|
|
117
|
-
const storage = getRateLimitStorage();
|
|
118
|
-
await storage.removeItem(key);
|
|
119
|
-
},
|
|
120
|
-
async ttl(key) {
|
|
121
|
-
const storage = getRateLimitStorage();
|
|
122
|
-
const record = await storage.getItem(key);
|
|
123
|
-
if (!record || !record.resetAt) {
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
const remainingMs = record.resetAt - Date.now();
|
|
127
|
-
return remainingMs > 0 ? Math.ceil(remainingMs / 1e3) : null;
|
|
128
|
-
}
|
|
129
|
-
};
|
|
116
|
+
__name(memoryRateLimitStorage, "memoryRateLimitStorage");
|
|
117
|
+
var defaultRateLimitStorage = memoryRateLimitStorage();
|
|
130
118
|
function parseTimeWindow(window) {
|
|
131
119
|
const match = window.match(/^(\d+)(ms|s|m|h|d)$/);
|
|
132
120
|
if (!match) throw new Error(`Invalid time window: ${window}`);
|
|
@@ -139,52 +127,73 @@ function parseTimeWindow(window) {
|
|
|
139
127
|
h: 60 * 60 * 1e3,
|
|
140
128
|
d: 24 * 60 * 60 * 1e3
|
|
141
129
|
};
|
|
142
|
-
|
|
130
|
+
const windowMs = value * multipliers[unit];
|
|
131
|
+
if (!Number.isSafeInteger(windowMs) || windowMs <= 0) {
|
|
132
|
+
throw new Error(`Invalid time window: ${window}`);
|
|
133
|
+
}
|
|
134
|
+
return windowMs;
|
|
143
135
|
}
|
|
144
136
|
__name(parseTimeWindow, "parseTimeWindow");
|
|
145
137
|
function createRateLimitMiddleware(config) {
|
|
138
|
+
if (!Number.isSafeInteger(config.requests) || config.requests <= 0) {
|
|
139
|
+
throw new TypeError("Rate limit requests must be a positive safe integer.");
|
|
140
|
+
}
|
|
146
141
|
const windowMs = parseTimeWindow(config.window);
|
|
147
142
|
const storage = config.storage || defaultRateLimitStorage;
|
|
143
|
+
assertAtomicRateLimitStorage(storage);
|
|
148
144
|
return async (ctx, next) => {
|
|
149
145
|
const key = config.keyGenerator ? config.keyGenerator(ctx) : `${ctx.request.socket.remoteAddress}:${ctx.pathname}`;
|
|
146
|
+
const current = await storage.increment(key, windowMs);
|
|
147
|
+
assertRateLimitIncrementResult(current);
|
|
150
148
|
const now = Date.now();
|
|
151
|
-
const
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const current = await storage.get(key);
|
|
157
|
-
if (!current) {
|
|
158
|
-
await storage.set(
|
|
159
|
-
key,
|
|
160
|
-
{
|
|
161
|
-
count: 1,
|
|
162
|
-
resetAt: now + windowMs
|
|
163
|
-
},
|
|
164
|
-
ttlSeconds
|
|
165
|
-
);
|
|
166
|
-
return next();
|
|
167
|
-
}
|
|
168
|
-
if (current.count >= config.requests) {
|
|
149
|
+
const resetIn = Math.max(1, Math.ceil((current.resetAt - now) / 1e3));
|
|
150
|
+
const remaining = Math.max(0, config.requests - current.count);
|
|
151
|
+
setRateLimitHeaders(ctx, config.requests, remaining, resetIn, Math.ceil(windowMs / 1e3));
|
|
152
|
+
if (current.count > config.requests) {
|
|
153
|
+
setMiddlewareResponseHeader(ctx, "Retry-After", String(resetIn));
|
|
169
154
|
if (config.onLimit) {
|
|
170
155
|
const result = await config.onLimit(ctx);
|
|
171
|
-
if (result) return;
|
|
156
|
+
if (result) return result;
|
|
172
157
|
}
|
|
173
158
|
ctx.json(
|
|
174
159
|
{
|
|
175
160
|
error: "Rate limit exceeded",
|
|
176
|
-
retryAfter:
|
|
161
|
+
retryAfter: resetIn
|
|
177
162
|
},
|
|
178
163
|
429
|
|
179
164
|
);
|
|
180
165
|
return;
|
|
181
166
|
}
|
|
182
|
-
current.count++;
|
|
183
|
-
await storage.set(key, current, ttlSeconds);
|
|
184
167
|
return next();
|
|
185
168
|
};
|
|
186
169
|
}
|
|
187
170
|
__name(createRateLimitMiddleware, "createRateLimitMiddleware");
|
|
171
|
+
function assertAtomicRateLimitStorage(storage) {
|
|
172
|
+
if (!storage || typeof storage.increment !== "function") {
|
|
173
|
+
throw new UnsupportedRateLimitStorageError();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
__name(assertAtomicRateLimitStorage, "assertAtomicRateLimitStorage");
|
|
177
|
+
function assertRateLimitIncrementResult(result) {
|
|
178
|
+
if (!result || !Number.isSafeInteger(result.count) || result.count <= 0 || !Number.isFinite(result.resetAt) || result.resetAt <= 0) {
|
|
179
|
+
throw new TypeError(
|
|
180
|
+
"RateLimitStorage.increment() must return a positive integer count and a resetAt timestamp."
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
__name(assertRateLimitIncrementResult, "assertRateLimitIncrementResult");
|
|
185
|
+
function setRateLimitHeaders(ctx, limit, remaining, resetIn, windowSeconds) {
|
|
186
|
+
setMiddlewareResponseHeader(ctx, "RateLimit-Policy", `"farm";q=${limit};w=${windowSeconds}`);
|
|
187
|
+
setMiddlewareResponseHeader(ctx, "RateLimit", `"farm";r=${remaining};t=${resetIn}`);
|
|
188
|
+
}
|
|
189
|
+
__name(setRateLimitHeaders, "setRateLimitHeaders");
|
|
190
|
+
function setMiddlewareResponseHeader(ctx, name, value) {
|
|
191
|
+
ctx.headers.set(name, value);
|
|
192
|
+
if (!ctx.response.headersSent && !ctx.response.writableEnded) {
|
|
193
|
+
ctx.response.setHeader(name, value);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
__name(setMiddlewareResponseHeader, "setMiddlewareResponseHeader");
|
|
188
197
|
function matchPattern(pattern, pathname) {
|
|
189
198
|
if (pattern instanceof RegExp) {
|
|
190
199
|
return pattern.test(pathname);
|
|
@@ -334,6 +343,15 @@ var _MiddlewareChainImpl = class _MiddlewareChainImpl {
|
|
|
334
343
|
__name(_MiddlewareChainImpl, "MiddlewareChainImpl");
|
|
335
344
|
var MiddlewareChainImpl = _MiddlewareChainImpl;
|
|
336
345
|
async function getRateLimitStatus(key, limit, storage = defaultRateLimitStorage) {
|
|
346
|
+
if (!Number.isSafeInteger(limit) || limit <= 0) {
|
|
347
|
+
throw new TypeError("Rate limit must be a positive safe integer.");
|
|
348
|
+
}
|
|
349
|
+
assertAtomicRateLimitStorage(storage);
|
|
350
|
+
if (typeof storage.get !== "function") {
|
|
351
|
+
throw new TypeError(
|
|
352
|
+
"getRateLimitStatus() requires a RateLimitStorage adapter that implements get(key)."
|
|
353
|
+
);
|
|
354
|
+
}
|
|
337
355
|
const record = await storage.get(key);
|
|
338
356
|
if (!record) {
|
|
339
357
|
return {
|
|
@@ -345,6 +363,7 @@ async function getRateLimitStatus(key, limit, storage = defaultRateLimitStorage)
|
|
|
345
363
|
isLimited: false
|
|
346
364
|
};
|
|
347
365
|
}
|
|
366
|
+
assertRateLimitIncrementResult(record);
|
|
348
367
|
const now = Date.now();
|
|
349
368
|
if (record.resetAt && now > record.resetAt) {
|
|
350
369
|
return {
|
|
@@ -365,9 +384,6 @@ async function getRateLimitStatus(key, limit, storage = defaultRateLimitStorage)
|
|
|
365
384
|
const remainingMs = record.resetAt - now;
|
|
366
385
|
resetIn = remainingMs > 0 ? Math.ceil(remainingMs / 1e3) : null;
|
|
367
386
|
resetAt = new Date(record.resetAt);
|
|
368
|
-
} else if (storage.ttl) {
|
|
369
|
-
resetIn = await storage.ttl(key);
|
|
370
|
-
resetAt = resetIn ? new Date(now + resetIn * 1e3) : null;
|
|
371
387
|
}
|
|
372
388
|
return {
|
|
373
389
|
requests,
|
|
@@ -2130,6 +2146,7 @@ __name(farmMiddlewarePlugin, "farmMiddlewarePlugin");
|
|
|
2130
2146
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2131
2147
|
0 && (module.exports = {
|
|
2132
2148
|
MiddlewareManager,
|
|
2149
|
+
UnsupportedRateLimitStorageError,
|
|
2133
2150
|
_runWithMiddlewareContext,
|
|
2134
2151
|
_runWithMiddlewareData,
|
|
2135
2152
|
applyProductionMiddlewareHeaders,
|
|
@@ -2142,6 +2159,7 @@ __name(farmMiddlewarePlugin, "farmMiddlewarePlugin");
|
|
|
2142
2159
|
getMiddlewareValue,
|
|
2143
2160
|
getRateLimitStatus,
|
|
2144
2161
|
hasMiddlewareData,
|
|
2162
|
+
memoryRateLimitStorage,
|
|
2145
2163
|
middleware,
|
|
2146
2164
|
unwrapMiddleware
|
|
2147
2165
|
});
|