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:
2026-05-30 01:10:00 +01:00
parent fe3fedf42e
commit 9bf56a806b
6022 changed files with 12437 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
# `path-matcher` — Hono-compatible path-pattern compilation and matching
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Compiles a Hono-style path pattern string into a regular expression
+ parameter-name list, then matches it against concrete inbound paths
and returns the captured params. The plugin pre-compiles every
`RouteRule.path` once at init so per-request route lookup is constant
time per rule and zero-allocation in the happy path.
The matcher accepts the same forms Hono's router accepts so route
rules written for the framework's router transparently apply to
rate-limit rules without translation. The compiled-pattern cache is
exposed so consumers wiring `RateLimitService.check(...)` manually
(without the middleware) can pre-compile their own rules.
## Features
+ Exact-literal, trailing wildcard (`/api/users/*`), inline segment
wildcard (`/api/*/avatar`), and named-param (`/api/users/:id`)
pattern forms.
+ Captured params returned as a frozen `Record<string, string>` so
callers can rely on referential stability.
+ All metacharacters in the literal portions are escaped before
pattern composition — `?`, `.`, `+` in a path do not turn into
regex operators by accident.
+ Defensive: every `RegExp` construction is wrapped so a future
pattern-syntax mistake surfaces as `RateLimitPluginError(INVALID_PATH_PATTERN)`
rather than a bare `SyntaxError`.
## Usage: Basic
```ts
import { isPathMatch } from "@suaveplan/api-plugin-rate-limit";
isPathMatch("/api/users/:id", "/api/users/123"); // true
isPathMatch("/api/users/:id", "/api/posts/123"); // false
```
## Usage: Advanced
```ts
import {
compilePathPattern,
matchPath,
} from "@suaveplan/api-plugin-rate-limit";
const pattern = compilePathPattern("/api/orgs/:org/users/:user");
const result = matchPath(pattern, "/api/orgs/acme/users/u42");
if (result.matched) {
console.log(result.params); // { org: "acme", user: "u42" }
}
```
## API Reference
+ `interface CompiledPathPattern` — `{ source, regex, paramNames }`.
+ `interface PathMatchResult` — `{ matched, params }`.
+ `function compilePathPattern(source: string): CompiledPathPattern` —
compile a pattern. Throws `RateLimitPluginError(INVALID_PATH_PATTERN)`
on regex construction failure.
+ `function matchPath(pattern: CompiledPathPattern, path: string): PathMatchResult`
— match a compiled pattern against a path.
+ `function isPathMatch(source: string, path: string): boolean` —
compile + match convenience helper.
## Implementation Notes
+ Pattern compilation is `O(n)` over the source length; matching is
`O(n)` over the path length once the regex is JIT'd by the engine.
+ Trailing `/*` matches zero or more path segments (the trailing slash
is optional), so `/api/users/*` matches both `/api/users/123` and
`/api/users/` — but not `/api/users` (no trailing slash). This
mirrors Hono's behavior.
+ Inline `*` matches exactly one segment (`[^/]+`) — `/api/*/avatar`
matches `/api/u1/avatar` but not `/api/u1/sub/avatar`.
+ Named params (`:name`) bind to the captured value; the value is
not currently used by the rate-limit service (rules apply to the
pattern as a whole) but is preserved so downstream consumers may
use it.
+ The matcher is universal — zero runtime dependencies.