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,71 @@
# parse-uri
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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.