@trpc-limiter/core
Version:
The core of tRPC limiter.
62 lines (61 loc) • 1.96 kB
JavaScript
// src/index.ts
import { TRPCError } from "@trpc/server";
var parseOptions = (passed, getDefaultOptions) => {
const b = {
...passed,
windowMs: passed.windowMs ?? 6e4,
max: passed.max ?? 5,
message: passed.message ?? "Too many requests, please try again later.",
fingerprint: passed.fingerprint,
onLimit: passed.onLimit
};
const newOpts = getDefaultOptions ? getDefaultOptions(b) : {};
return {
...b,
...newOpts
};
};
var defineTRPCLimiter = (adapter, getDefaultOptions) => {
return (opts) => {
const options = parseOptions(opts, getDefaultOptions);
const store = adapter.store(options);
const middleware = async ({ ctx, next, input }) => {
const fp = await options.fingerprint(ctx, input);
if (!fp) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "No fingerprint returned"
});
}
const hitInfo = await adapter.isBlocked(store, fp, options);
if (hitInfo) {
if (typeof options.onLimit === "function") {
await options.onLimit(hitInfo, ctx, fp);
}
const message = typeof options.message === "function" ? await options.message(hitInfo, ctx, fp) : options.message;
throw new TRPCError({
code: "TOO_MANY_REQUESTS",
message
});
}
return next();
};
return middleware;
};
};
var defineLimiterWithProps = (adapter, getDefaultOptions) => {
const d = defineTRPCLimiter(adapter, getDefaultOptions);
return (opts) => {
return d(opts);
};
};
var defaultFingerPrint = (req) => {
const forwarded = req instanceof Request ? req.headers.get("x-forwarded-for") : req.headers["x-forwarded-for"];
const ip = forwarded ? (typeof forwarded === "string" ? forwarded : forwarded[0])?.split(/, /)[0] : req?.socket?.remoteAddress ?? null;
return ip || "127.0.0.1";
};
export {
defaultFingerPrint,
defineLimiterWithProps,
defineTRPCLimiter
};