UNPKG

@trpc-limiter/core

Version:
62 lines (61 loc) 1.96 kB
// 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 };