# parse-uri _(no submodules)_ ## Purpose `parseUri(uri)` is the RFC 3986 subset parser the resolver uses to extract a scheme, optional authority, path, and optional query from a URI string. It exists to keep `StorageUriResolver` scheme-agnostic — every adapter plugin owns its own scheme-specific addressing and composes against this base parser. The parser intentionally rejects more inputs than RFC 3986 strictly requires: whitespace, NUL bytes, and strings longer than 4096 characters are all hard-failures. The 4096-cap matches the de-facto path-length ceiling observed across S3, Rackspace, Bunny, and most filesystems and prevents quadratic blow-ups inside plugin parsers. ## Features - Scheme regex `^[A-Za-z][A-Za-z0-9+\-.]*$` per RFC 3986 §3.1. - Case-insensitive scheme — the returned `scheme` is lower-cased. - Authority extraction when the rest starts with `//`. - Query/fragment split with both kept off the path. - Single error code on rejection: `STORAGE_URI.INVALID_URI` with the offending input on the `uri` discriminant. ## Usage: Basic ```ts import { parseUri } from "@suaveplan/storage-uri/parse-uri"; const parts = parseUri("s3://bucket/raw/clip.mov"); // { scheme: "s3", authority: "bucket", path: "/raw/clip.mov" } ``` ## Usage: Advanced ```ts import { parseUri } from "@suaveplan/storage-uri/parse-uri"; import { STORAGE_URI_CODES, StorageUriError } from "@suaveplan/storage-uri/error-codes"; function parseOrNull(uri: string) { try { return parseUri(uri); } catch (err) { if (err instanceof StorageUriError && err.code === STORAGE_URI_CODES.INVALID_URI) { return null; } throw err; } } ``` ## API Reference - `interface ParsedUriParts { scheme: string; authority?: string; path: string; query?: string }` - `function parseUri(uri: string): ParsedUriParts` — throws `StorageUriError(STORAGE_URI.INVALID_URI)` on rejection. ## Implementation Notes Authority termination is hand-rolled instead of regex-based so the parser avoids re-walking the input. The `findAuthorityEnd` helper scans for the first `/`, `?`, or `#` character — these are the three RFC 3986 component delimiters that may follow an authority. Empty path is permitted (e.g. `s3://bucket`); empty rest after the colon (`scheme:`) is not. The maximum-length check happens BEFORE the regex test so pathological inputs cannot pin a regex engine.