Move docs/ package mirror into document-navigator plugin
Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
# @suaveplan/api-plugin-rate-limit - Rate-limit plugin for @suaveplan/api. Wraps @suaveplan/rate-limiter as a definePlugin descriptor: per-route + per-tenant configuration, parameterised path matcher, IP whitelist, tenant multiplier applied to numeric limit, Hono middleware factory, 429 + Retry-After + X-RateLimit-* / RateLimit-* headers, OTel counters, RFC 7807 Problem+JSON body. Registers `rateLimitService` in the host ServiceRegistry.
|
||||
|
||||
Rate-limit plugin for `@suaveplan/api`. Wraps `@suaveplan/rate-limiter`
|
||||
as a `definePlugin` descriptor exposing per-route + per-tenant
|
||||
configuration, parameterised path matching, IP whitelist, applied
|
||||
tenant multiplier, Hono middleware, `X-RateLimit-*` / `RateLimit-*` /
|
||||
`Retry-After` headers, RFC 7807 Problem+JSON 429 body, and OTel
|
||||
counters / histogram. Registers a typed `rateLimitService` slot in the
|
||||
host `ServiceRegistry` so sibling plugins can run manual checks.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
## Documentation tree
|
||||
|
||||
- [error-codes](./src/error-codes/error-codes.md) — Provides the stable, namespaced error-code registry every failure path in `@suaveplan/api-plugin-rate-limit` reports th…
|
||||
- [error-codes](./src/error-codes/error-codes.md) — Provides the stable, namespaced error-code registry every failure path in `@suaveplan/api-plugin-rate-limit` reports th…
|
||||
- [headers](./src/headers/headers.md) — Builds the HTTP response headers and Problem+JSON body the rate-limit middleware writes onto every response (allowed AN…
|
||||
- [headers](./src/headers/headers.md) — Builds the HTTP response headers and Problem+JSON body the rate-limit middleware writes onto every response (allowed AN…
|
||||
- [context-augmentation](./src/middleware/context-augmentation.md) — Augments Hono's `ContextVariableMap` interface so handlers calling `c.get("rateLimit")` get a typed `RateLimitDecision`…
|
||||
- [rate-limit](./src/middleware/rate-limit.md) — Constructs a Hono `MiddlewareHandler` that consults a `RateLimitService` on every request, emits the configured `X-Rate…
|
||||
- [otel](./src/otel/instruments.md) — Builds (and caches) the bundle of OpenTelemetry instruments the rate-limit plugin emits on every check. Operators wirin…
|
||||
- [instruments](./src/otel/instruments.md) — Builds (and caches) the bundle of OpenTelemetry instruments the rate-limit plugin emits on every check. Operators wirin…
|
||||
- [path-matcher](./src/path-matcher/path-matcher.md) — Compiles a Hono-style path pattern string into a regular expression
|
||||
- [path-matcher](./src/path-matcher/path-matcher.md) — Compiles a Hono-style path pattern string into a regular expression
|
||||
- [plugin](./src/plugin/plugin.md) — Factory that returns a typed `PluginDescriptor` for the rate-limit plugin, ready to be passed to `@suaveplan/api`'s plu…
|
||||
- [plugin](./src/plugin/plugin.md) — Factory that returns a typed `PluginDescriptor` for the rate-limit plugin, ready to be passed to `@suaveplan/api`'s plu…
|
||||
- [schemas](./src/schemas/options.md) — Validates the caller-supplied `RateLimitPluginOptions` at the boundary and fills in defaults for every optional field,…
|
||||
- [options](./src/schemas/options.md) — Validates the caller-supplied `RateLimitPluginOptions` at the boundary and fills in defaults for every optional field,…
|
||||
- [rate-limit-service](./src/services/rate-limit-service.md) — Wraps the universal `@suaveplan/rate-limiter` core in the plugin's policy layer: IP whitelist, tenant bypass, tenant mu…
|
||||
- [registry-augmentation](./src/services/registry-augmentation.md) — Augments the `ServiceRegistry` interface owned by `@suaveplan/api-plugin/service-registry` so consumers see the `rateLi…
|
||||
- [types](./src/types/types.md) — Defines the public type surface every other module in the package references — the caller-facing `RateLimitPluginOption…
|
||||
- [types](./src/types/types.md) — Defines the public type surface every other module in the package references — the caller-facing `RateLimitPluginOption…
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
bun add @suaveplan/api-plugin-rate-limit
|
||||
```
|
||||
|
||||
## Quick start
|
||||
|
||||
```ts
|
||||
import { createApi } from "@suaveplan/api";
|
||||
import { createRateLimitPlugin } from "@suaveplan/api-plugin-rate-limit";
|
||||
|
||||
const api = createApi();
|
||||
api.use(
|
||||
createRateLimitPlugin({
|
||||
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",
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
Every request flowing through the host Hono app is now rate-limited.
|
||||
Responses carry both legacy `X-RateLimit-Limit` / `X-RateLimit-Remaining`
|
||||
/ `X-RateLimit-Reset` and IETF `RateLimit-Limit` / `RateLimit-Remaining`
|
||||
/ `RateLimit-Reset` headers. Denied requests return `429` with
|
||||
`Content-Type: application/problem+json` and a `Retry-After` header.
|
||||
|
||||
## Manual `service.check(...)` from sibling plugins
|
||||
|
||||
```ts
|
||||
import {
|
||||
rateLimitExceeded,
|
||||
type RateLimitService,
|
||||
} from "@suaveplan/api-plugin-rate-limit";
|
||||
|
||||
const service = ctx.getService("rateLimitService") as RateLimitService;
|
||||
const decision = await service.check({
|
||||
ip,
|
||||
tenantId,
|
||||
path: "/api/billing/invoice",
|
||||
method: "POST",
|
||||
});
|
||||
if (!decision.allowed) throw rateLimitExceeded(decision);
|
||||
```
|
||||
|
||||
## The 3-way plug-and-play contract
|
||||
|
||||
This package follows the same contract every `@suaveplan/api-plugin-*`
|
||||
package follows: it owns its boundary Zod schemas
|
||||
(`RateLimitPluginOptionsSchema`), registers a typed slot in the host
|
||||
`ServiceRegistry` (`rateLimitService`), and installs a global Hono
|
||||
middleware via `app.use("*", rateLimit({ service }))` from its
|
||||
canonical 6-step `onInit` lifecycle (resolve services → build storage
|
||||
→ construct service → register slot → install middleware → log
|
||||
readiness).
|
||||
|
||||
## Modules
|
||||
|
||||
- [`src/error-codes/error-codes.md`](src/error-codes/error-codes.md) —
|
||||
`RATE_LIMIT_PLUGIN_CODES` registry + `RateLimitPluginError`.
|
||||
- [`src/types/types.md`](src/types/types.md) — public type surface.
|
||||
- [`src/schemas/options.md`](src/schemas/options.md) — Zod schema for
|
||||
caller-supplied options.
|
||||
- [`src/path-matcher/path-matcher.md`](src/path-matcher/path-matcher.md)
|
||||
— Hono-compatible path-pattern compilation + matching.
|
||||
- [`src/headers/headers.md`](src/headers/headers.md) — header bag +
|
||||
Problem+JSON body construction.
|
||||
- [`src/otel/instruments.md`](src/otel/instruments.md) — OpenTelemetry
|
||||
instruments bundle.
|
||||
- [`src/services/rate-limit-service.md`](src/services/rate-limit-service.md)
|
||||
— `RateLimitService` factory.
|
||||
- [`src/services/registry-augmentation.md`](src/services/registry-augmentation.md)
|
||||
— `ServiceRegistry` module augmentation.
|
||||
- [`src/middleware/rate-limit.md`](src/middleware/rate-limit.md) —
|
||||
Hono middleware factory.
|
||||
- [`src/middleware/context-augmentation.md`](src/middleware/context-augmentation.md)
|
||||
— Hono `ContextVariableMap` augmentation.
|
||||
- [`src/plugin/plugin.md`](src/plugin/plugin.md) —
|
||||
`createRateLimitPlugin` factory.
|
||||
|
||||
## Status
|
||||
|
||||
`0.1.0` — initial ship. Surface is final for the 0.1.x line.
|
||||
|
||||
Reference in New Issue
Block a user