Files
skills/docs/persistence/storage/storage-uri/src/parse-uri/parse-uri.md
2026-05-29 08:20:56 +01:00

2.4 KiB

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

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

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.