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,98 @@
# parseImgproxyUrl
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`parseImgproxyUrl` parses the compact imgproxy URL grammar used by the
Caddy module — `/[s|u]<op><gravity><dims><modifiers>/<path>.<format>` —
into a typed, frozen `ParsedImgproxyUrl`. It is the canonical entry
point for every other helper in the package; the URL builder, the
handler, and the dimensions calculator all consume the value it
returns.
Behaviour mirrors the upstream Go implementation byte-for-byte so the
TypeScript port and the Go module can be tested against a shared
fixture corpus. The function never partially succeeds: invalid input
throws a `CaddyImgproxyError` carrying a stable code from
`CADDY_IMGPROXY_CODES`, and the parse-total counter ticks once per
call with the matching outcome tag.
## Features
- Single-pass regex grammar covering signed / unsigned prefix, five
operations (`cover`, `crop`, `fit`, `stretch`, `resize`), nine
gravities, aspect / pixel / square dimensions, and width / height /
quality modifiers in arbitrary order.
- Quality validation built into the grammar (`q1..q100`) — out-of-band
values raise `INVALID_URL`.
- Operation + dimension constraint enforcement (`MISSING_DIMENSIONS`).
- Frozen, immutable return value safe to memoise.
- OTel counter on every call (`caddy_imgproxy_parse_total`).
## Usage: Basic
```ts
import { parseImgproxyUrl } from "@suaveplan/caddy-imgproxy";
const parsed = parseImgproxyUrl("/uv16:9/avatar.png");
parsed.operation; // "cover"
parsed.aspectW; // 16
parsed.path; // "avatar"
parsed.format; // "png"
```
## Usage: Advanced
```ts
import {
CADDY_IMGPROXY_CODES,
CaddyImgproxyError,
parseImgproxyUrl,
} from "@suaveplan/caddy-imgproxy";
function tryParse(path: string): string | null {
try {
const parsed = parseImgproxyUrl(path);
return `${parsed.operation || "passthrough"} → ${parsed.path}.${parsed.format}`;
} catch (err) {
if (
err instanceof CaddyImgproxyError &&
err.code === CADDY_IMGPROXY_CODES.MISSING_DIMENSIONS
) {
return "needs dims";
}
throw err;
}
}
```
## API Reference
### `parseImgproxyUrl(path: string): ParsedImgproxyUrl`
- **Parameters:** `path` — the URL path including leading `/`.
- **Returns:** a frozen `ParsedImgproxyUrl` (see `types/types.ts`).
- **Throws:**
- `CaddyImgproxyError(INVALID_URL)` when the regex rejects the
input — bad prefix, malformed dimensions, quality outside
`1..100`.
- `CaddyImgproxyError(MISSING_DIMENSIONS)` when an operation
(`v|c|f|s|r`) is present without any dimension grammar.
## Implementation Notes
The grammar regex is a single anchored expression with thirteen
capture groups that mirror the field order of the Go regex
exactly. The modifier sub-grammar (`w<int>`, `h<int>`, `q1..100`) is
extracted via a global secondary regex so order is irrelevant — the
last `w`/`h` wins (matching Go), and `q` always wins for quality.
`Number.parseInt` with radix 10 is used for every numeric extraction
to avoid the legacy octal-from-leading-zero behaviour. Defensive
defaults are deliberately omitted from branches the regex can never
reach so coverage stays honest; the only fallbacks in the function
body protect against future grammar evolution (e.g. an empty gravity
capture defaulting to `"c"`).