@bgord/bun 0.18.12 → 0.18.14
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/node-cache-rate-limit-store.adapter.d.ts +11 -0
- package/dist/node-cache-rate-limit-store.adapter.d.ts.map +1 -0
- package/dist/node-cache-rate-limit-store.adapter.js +24 -0
- package/dist/node-cache-rate-limit-store.adapter.js.map +1 -0
- package/dist/rate-limit-shield.middleware.d.ts +7 -0
- package/dist/rate-limit-shield.middleware.d.ts.map +1 -1
- package/dist/rate-limit-shield.middleware.js +15 -11
- package/dist/rate-limit-shield.middleware.js.map +1 -1
- package/dist/rate-limit-store.port.d.ts +7 -0
- package/dist/rate-limit-store.port.d.ts.map +1 -0
- package/dist/rate-limit-store.port.js +2 -0
- package/dist/rate-limit-store.port.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/zip-draft.service.d.ts.map +1 -1
- package/dist/zip-draft.service.js +1 -0
- package/dist/zip-draft.service.js.map +1 -1
- package/package.json +4 -4
- package/readme.md +2 -0
- package/src/node-cache-rate-limit-store.adapter.ts +29 -0
- package/src/rate-limit-shield.middleware.ts +25 -11
- package/src/rate-limit-store.port.ts +8 -0
- package/src/zip-draft.service.ts +1 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as tools from "@bgord/tools";
|
|
2
|
+
import { RateLimitStore, RateLimitStoreSubjectType } from "./rate-limit-store.port";
|
|
3
|
+
export declare class NodeCacheRateLimitStore implements RateLimitStore {
|
|
4
|
+
private readonly time;
|
|
5
|
+
private readonly store;
|
|
6
|
+
constructor(time: tools.TimeResult);
|
|
7
|
+
get(subject: RateLimitStoreSubjectType): Promise<tools.RateLimiter | undefined>;
|
|
8
|
+
set(subject: RateLimitStoreSubjectType, limiter: tools.RateLimiter): Promise<void>;
|
|
9
|
+
flushAll(): void;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=node-cache-rate-limit-store.adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-cache-rate-limit-store.adapter.d.ts","sourceRoot":"","sources":["../src/node-cache-rate-limit-store.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,OAAO,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEpF,qBAAa,uBAAwB,YAAW,cAAc;IAGhD,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;gBAEL,IAAI,EAAE,KAAK,CAAC,UAAU;IAS7C,GAAG,CAAC,OAAO,EAAE,yBAAyB;IAItC,GAAG,CAAC,OAAO,EAAE,yBAAyB,EAAE,OAAO,EAAE,KAAK,CAAC,WAAW;IAIxE,QAAQ;CAGT"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import NodeCache from "node-cache";
|
|
2
|
+
export class NodeCacheRateLimitStore {
|
|
3
|
+
time;
|
|
4
|
+
store;
|
|
5
|
+
constructor(time) {
|
|
6
|
+
this.time = time;
|
|
7
|
+
this.store = new NodeCache({
|
|
8
|
+
stdTTL: this.time.seconds,
|
|
9
|
+
checkperiod: this.time.seconds,
|
|
10
|
+
deleteOnExpire: true,
|
|
11
|
+
maxKeys: 100_000,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
async get(subject) {
|
|
15
|
+
return this.store.get(subject);
|
|
16
|
+
}
|
|
17
|
+
async set(subject, limiter) {
|
|
18
|
+
this.store.set(subject, limiter);
|
|
19
|
+
}
|
|
20
|
+
flushAll() {
|
|
21
|
+
this.store.flushAll();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=node-cache-rate-limit-store.adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-cache-rate-limit-store.adapter.js","sourceRoot":"","sources":["../src/node-cache-rate-limit-store.adapter.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,YAAY,CAAC;AAInC,MAAM,OAAO,uBAAuB;IAGL;IAFZ,KAAK,CAAY;IAElC,YAA6B,IAAsB;QAAtB,SAAI,GAAJ,IAAI,CAAkB;QACjD,IAAI,CAAC,KAAK,GAAG,IAAI,SAAS,CAAC;YACzB,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO;YACzB,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO;YAC9B,cAAc,EAAE,IAAI;YACpB,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,OAAkC;QAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,OAAO,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,OAAkC,EAAE,OAA0B;QACtE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;CACF"}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import * as tools from "@bgord/tools";
|
|
2
|
+
import { Context } from "hono";
|
|
2
3
|
import { HTTPException } from "hono/http-exception";
|
|
4
|
+
import { RateLimitStore } from "./rate-limit-store.port";
|
|
5
|
+
type SubjectResolver = (c: Context) => string;
|
|
6
|
+
export declare const AnonSubjectResolver: SubjectResolver;
|
|
7
|
+
export declare const UserSubjectResolver: SubjectResolver;
|
|
3
8
|
type RateLimitShieldOptionsType = {
|
|
4
9
|
time: tools.TimeResult;
|
|
5
10
|
enabled: boolean;
|
|
11
|
+
store: RateLimitStore;
|
|
12
|
+
subject: SubjectResolver;
|
|
6
13
|
};
|
|
7
14
|
export declare const TooManyRequestsError: HTTPException;
|
|
8
15
|
export declare const RateLimitShield: (options: RateLimitShieldOptionsType) => import("hono").MiddlewareHandler<any, string, {}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit-shield.middleware.d.ts","sourceRoot":"","sources":["../src/rate-limit-shield.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"rate-limit-shield.middleware.d.ts","sourceRoot":"","sources":["../src/rate-limit-shield.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,KAAK,eAAe,GAAG,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;AAE9C,eAAO,MAAM,mBAAmB,EAAE,eAA8B,CAAC;AAEjE,eAAO,MAAM,mBAAmB,EAAE,eAAoD,CAAC;AAEvF,KAAK,0BAA0B,GAAG;IAChC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,cAAc,CAAC;IACtB,OAAO,EAAE,eAAe,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,eAA+D,CAAC;AAEjG,eAAO,MAAM,eAAe,GAAI,SAAS,0BAA0B,sDAsBlE,CAAC"}
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import * as tools from "@bgord/tools";
|
|
2
2
|
import { createMiddleware } from "hono/factory";
|
|
3
3
|
import { HTTPException } from "hono/http-exception";
|
|
4
|
-
export const
|
|
5
|
-
|
|
6
|
-
});
|
|
4
|
+
export const AnonSubjectResolver = () => "anon";
|
|
5
|
+
export const UserSubjectResolver = (c) => c.get("user")?.id ?? "anon";
|
|
6
|
+
export const TooManyRequestsError = new HTTPException(429, { message: "app.too_many_requests" });
|
|
7
7
|
export const RateLimitShield = (options) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return createMiddleware(async (_c, next) => {
|
|
11
|
-
if (!enabled)
|
|
8
|
+
return createMiddleware(async (c, next) => {
|
|
9
|
+
if (!options.enabled)
|
|
12
10
|
return next();
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
if (!
|
|
16
|
-
|
|
11
|
+
const subject = options.subject(c);
|
|
12
|
+
let limiter = await options.store.get(subject);
|
|
13
|
+
if (!limiter) {
|
|
14
|
+
limiter = new tools.RateLimiter(options.time);
|
|
15
|
+
options.store.set(subject, limiter);
|
|
17
16
|
}
|
|
17
|
+
const now = tools.Timestamp.parse(Date.now());
|
|
18
|
+
const check = limiter.verify(now);
|
|
19
|
+
if (!check.allowed)
|
|
20
|
+
throw TooManyRequestsError;
|
|
21
|
+
options.store.set(subject, limiter);
|
|
18
22
|
return next();
|
|
19
23
|
});
|
|
20
24
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit-shield.middleware.js","sourceRoot":"","sources":["../src/rate-limit-shield.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"rate-limit-shield.middleware.js","sourceRoot":"","sources":["../src/rate-limit-shield.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKpD,MAAM,CAAC,MAAM,mBAAmB,GAAoB,GAAG,EAAE,CAAC,MAAM,CAAC;AAEjE,MAAM,CAAC,MAAM,mBAAmB,GAAoB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,MAAM,CAAC;AASvF,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,aAAa,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC,CAAC;AAEjG,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAmC,EAAE,EAAE;IACrE,OAAO,gBAAgB,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACxC,IAAI,CAAC,OAAO,CAAC,OAAO;YAAE,OAAO,IAAI,EAAE,CAAC;QAEpC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAEnC,IAAI,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAE/C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC9C,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACtC,CAAC;QAED,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAElC,IAAI,CAAC,KAAK,CAAC,OAAO;YAAE,MAAM,oBAAoB,CAAC;QAE/C,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAEpC,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as tools from "@bgord/tools";
|
|
2
|
+
export type RateLimitStoreSubjectType = string;
|
|
3
|
+
export interface RateLimitStore {
|
|
4
|
+
get(subject: RateLimitStoreSubjectType): Promise<tools.RateLimiter | undefined>;
|
|
5
|
+
set(subject: RateLimitStoreSubjectType, limiter: tools.RateLimiter): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=rate-limit-store.port.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit-store.port.d.ts","sourceRoot":"","sources":["../src/rate-limit-store.port.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IAChF,GAAG,CAAC,OAAO,EAAE,yBAAyB,EAAE,OAAO,EAAE,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit-store.port.js","sourceRoot":"","sources":["../src/rate-limit-store.port.ts"],"names":[],"mappings":""}
|