UNPKG

@unkey/ratelimit

Version:

<div align="center"> <h1 align="center">@unkey/ratelimit</h1> <h5>@unkey/ratelimit is a library for fast global ratelimiting in serverless functions.</h5> </div>

160 lines (155 loc) 3.99 kB
// src/noop.ts var NoopRatelimit = class { limit(_identifier, _opts) { return Promise.resolve({ limit: 0, remaining: 0, reset: 0, success: true }); } }; // src/ratelimit.ts import { Unkey } from "@unkey/api"; // package.json var version = "0.5.5"; // src/duration.ts function ms(d) { if (typeof d === "number") { return d; } const match = d.match(/^(\d+)\s?(ms|s|m|h|d)$/); if (!match) { throw new Error(`Unable to parse window size: ${d}`); } const time = Number.parseInt(match[1]); const unit = match[2]; switch (unit) { case "ms": return time; case "s": return time * 1e3; case "m": return time * 1e3 * 60; case "h": return time * 1e3 * 60 * 60; case "d": return time * 1e3 * 60 * 60 * 24; default: throw new Error(`Unable to parse window size: ${d}`); } } // src/ratelimit.ts var Ratelimit = class { config; unkey; constructor(config) { this.config = config; this.unkey = new Unkey({ baseUrl: config.baseUrl, rootKey: config.rootKey, disableTelemetry: config.disableTelemetry, wrapperSdkVersion: `@unkey/ratelimit@${version}` }); } /** * Limit a specific identifier, you can override a lot of things about this specific request using * the 2nd argument. * * @example * ```ts * const identifier = getIpAddress() // or userId or anything else * const res = await unkey.limit(identifier) * * if (!res.success){ * // reject request * } * // handle request * ``` */ async limit(identifier, opts) { try { return this._limit(identifier, opts); } catch (e) { if (!this.config.onError) { throw e; } const err = e instanceof Error ? e : new Error(String(e)); return await this.config.onError(err, identifier); } } async _limit(identifier, opts) { const timeout = this.config.timeout === false ? null : this.config.timeout ?? { ms: 5e3, fallback: () => ({ success: false, limit: 0, remaining: 0, reset: Date.now() }) }; let timeoutId = null; try { const ps = [ this.unkey.ratelimits.limit({ namespace: this.config.namespace, identifier, limit: this.config.limit, duration: ms(this.config.duration), cost: opts?.cost, meta: opts?.meta, resources: opts?.resources, async: typeof opts?.async !== "undefined" ? opts.async : this.config.async }).then((res) => { if (res.error) { throw new Error( `Ratelimit failed: [${res.error.code} - ${res.error.requestId}]: ${res.error.message}` ); } return res.result; }) ]; if (timeout) { ps.push( new Promise((resolve) => { timeoutId = setTimeout(async () => { const resolvedValue = typeof timeout.fallback === "function" ? await timeout.fallback(identifier) : timeout.fallback; resolve(resolvedValue); }, ms(timeout.ms)); }) ); } return await Promise.race(ps); } finally { if (timeoutId) { clearTimeout(timeoutId); } } } }; // src/overrides.ts import { Unkey as Unkey2 } from "@unkey/api"; var Overrides = class { unkey; constructor(config) { this.unkey = new Unkey2({ baseUrl: config.baseUrl, rootKey: config.rootKey, disableTelemetry: config.disableTelemetry, wrapperSdkVersion: `@unkey/ratelimit@${version}` }); } get getOverride() { return this.unkey.ratelimits.getOverride; } get setOverride() { return this.unkey.ratelimits.setOverride; } get deleteOverride() { return this.unkey.ratelimits.deleteOverride; } get listOverrides() { return this.unkey.ratelimits.listOverrides; } }; export { NoopRatelimit, Overrides, Ratelimit }; //# sourceMappingURL=index.mjs.map