/**
 * Validate and return a path parameter, throwing if it's unsafe to use
 * in filesystem interpolation.
 *
 * The default contract is single-segment: no `/`, no `\`, no `..`, no
 * absolute path, no null bytes, no control characters, length ≤ 255.
 * Pass `allowSlashes: true` for a multi-segment path (still rejects
 * the rest).
 *
 * @throws {PathParamError} when the value fails any check.
 */
export declare function sanitizePathParam(value: unknown, options?: SanitizePathParamOptions): string;
/**
 * Non-throwing variant. Returns the sanitized value or `null` if any
 * check failed. Use when you want a fast yes/no in a conditional
 * without a try/catch around the throw site.
 */
export declare function safePathParam(value: unknown, options?: SanitizePathParamOptions): string | null;
export declare interface SanitizePathParamOptions {
  context?: string
  maxLength?: number
  allowSlashes?: boolean
}
/**
 * Path-parameter sanitization helpers.
 *
 * Route params arrive from the URL as untyped strings and are merged
 * directly into `req.params`. Actions that interpolate those values
 * into filesystem paths or shell commands without first scrubbing
 * them are vulnerable to `..`-traversal, absolute-path takeovers, and
 * null-byte truncation attacks.
 *
 * The router itself can't auto-sanitize every param (some are
 * deliberately path-shaped — file servers, asset proxies, etc.). What
 * we ship instead is a single canonical helper that callers reach for
 * at the boundary where the param meets the filesystem.
 *
 * See stacksjs/stacks#1870 R-12.
 *
 * @example
 * ```ts
 * import { sanitizePathParam } from '@stacksjs/router'
 *
 * const filename = sanitizePathParam(req.params.filename, {
 *   context: 'avatar download',
 * })
 * return new Response(Bun.file(path.appPath(`avatars/${filename}`)))
 * ```
 */
/**
 * Reasons {@link sanitizePathParam} rejects a value. Surfaced via the
 * thrown error so callers can log or branch.
 */
export type PathParamRejection = | 'empty'
  | 'not-string'
  | 'absolute-path'
  | 'traversal'
  | 'null-byte'
  | 'control-char'
  | 'too-long';
export declare class PathParamError extends Error {
  readonly reason: PathParamRejection;
  constructor(reason: PathParamRejection, value: unknown, context?: string);
}
