first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
# `schemas/options` — Zod schema for `createRateLimitPlugin` options
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Validates the caller-supplied `RateLimitPluginOptions` at the
boundary and fills in defaults for every optional field, producing the
resolved `RateLimitPluginConfig` the plugin's `onInit` lifecycle and
the `RateLimitService` rely on. The schema is the single source of
truth for what shape `createRateLimitPlugin` accepts — the factory
calls `safeParse(...)` and throws `RateLimitPluginError(INVALID_INPUT)`
with the underlying `ZodError` attached as `cause` on validation
failure, so callers see a typed error rather than a runtime crash.
## Features
- `defaultLimit` / `defaultWindowMs` mandatory positive integers.
- `routes`, `tenants`, `ipWhitelist` default to empty arrays.
- `keyResolver` defaults to `${ip}|${tenantId ?? "_"}` — composable
isolation between IPs and tenants out of the box.
- `headerStyle` enum: `"x-rate-limit"` (default), `"rfc-9238"`,
`"both"`.
- `emitRetryAfter` defaults to `true`.
- `storage` is a custom Zod runtime check accepting any
`RateLimitStorage`-shaped object — caller-supplied adapters
(Redis, SurrealDB) pass through untouched.
- `.strict()` so typos in option names fail loudly instead of
silently doing nothing.
## Usage: Basic
```ts
import { RateLimitPluginOptionsSchema } from "@suaveplan/api-plugin-rate-limit";
const config = RateLimitPluginOptionsSchema.parse({
defaultLimit: 100,
defaultWindowMs: 60_000,
});
```
## Usage: Advanced
```ts
import { RateLimitPluginOptionsSchema } from "@suaveplan/api-plugin-rate-limit";
const result = RateLimitPluginOptionsSchema.safeParse({
defaultLimit: 100,
defaultWindowMs: 60_000,
routes: [
{ path: "/api/login", method: "POST", limit: 5, windowMs: 60_000, id: "login" },
{ path: "/api/users/:id", limit: 30, windowMs: 60_000 },
],
tenants: [
{ tenantId: "enterprise", multiplier: 10 },
{ tenantId: "internal", bypass: true },
],
ipWhitelist: ["127.0.0.1"],
headerStyle: "both",
});
if (!result.success) console.error(result.error.issues);
```
## API Reference
- `RateLimitPluginOptionsSchema` — Zod schema instance. Parses
`RateLimitPluginOptions` (input) into `RateLimitPluginConfig`
(output) with every default filled in.
- `RateLimitPluginOptionsInput` — `z.input<typeof
RateLimitPluginOptionsSchema>` — what callers supply.
- `RateLimitPluginOptionsResolved` — `z.output<typeof
RateLimitPluginOptionsSchema>` — what the plugin receives.
## Implementation Notes
- `keyResolver` uses `z.custom<RateLimitKeyResolver>` — functions
cannot be expressed as a JSON-Schema-compatible Zod shape; the
custom check enforces `typeof === "function"`.
- `storage` and `logger` are runtime references; the schema preserves
them as-is via `z.custom` rather than attempting to validate their
internal shape.
- `defaults` declared inline so `RateLimitPluginOptionsResolved` is a
total interface — no `undefined` fallbacks in the consumer.
- The schema is `.strict()` to catch typos like
`defaultLimti: 100` at the boundary.