@h3ravel/http
Version:
HTTP kernel, middleware pipeline, request/response classes for H3ravel.
1,807 lines (1,806 loc) • 53 kB
TypeScript
/// <reference path="./app.globals.d.ts" />
import { Command } from "@h3ravel/musket";
import { DateTime } from "@h3ravel/support";
import { EventHandlerRequest, H3Event, HTTPResponse } from "h3";
import { DotNestedKeys, DotNestedValue, HttpContext as HttpContext$1, IApplication, IMiddleware, IParamBag, IRequest, IResponse, RequestMethod, RequestObject, ResponseObject } from "@h3ravel/shared";
import { Application } from "@h3ravel/core";
import { Url } from "@h3ravel/url";
//#region src/Commands/FireCommand.d.ts
declare class FireCommand extends Command {
/**
* The name and signature of the console command.
*
* @var string
*/
protected signature: string;
/**
* The console command description.
*
* @var string
*/
protected description: string;
handle(): Promise<void>;
protected fire(): Promise<void>;
}
//#endregion
//#region src/Contracts/HttpContract.d.ts
type CacheOptions = Partial<{
must_revalidate: boolean;
no_cache: boolean;
no_store: boolean;
no_transform: boolean;
public: boolean;
private: boolean;
proxy_revalidate: boolean;
max_age: number;
s_maxage: number;
immutable: boolean;
stale_while_revalidate: number;
stale_if_error: number;
last_modified: string | Date;
etag: string;
}>;
//#endregion
//#region src/Exceptions/BadRequestException.d.ts
declare class BadRequestException extends Error {
constructor(message: string);
}
//#endregion
//#region src/Exceptions/ConflictingHeadersException.d.ts
declare class ConflictingHeadersException extends Error {
constructor(message: string);
}
//#endregion
//#region src/Utilities/HeaderBag.d.ts
/**
* HeaderBag — A container for HTTP headers
* for Node/H3 environments.
*/
declare class HeaderBag implements Iterable<[string, (string | null)[]]> {
protected static readonly UPPER = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
protected static readonly LOWER = "-abcdefghijklmnopqrstuvwxyz";
protected headers: Record<string, (string | null)[]>;
protected headerNames: Record<string, string>;
protected cacheControl: Record<string, string | boolean>;
constructor(headers?: Record<string, string | string[] | null>);
/**
* Returns all headers as string (for debugging / toString)
*
* @returns
*/
toString(): string;
/**
* Returns all headers or specific header list
*
* @param key
* @returns
*/
all<K extends string | undefined>(key?: K): K extends string ? (string | null)[] : Record<string, (string | null)[]>;
/**
* Returns header keys
*
* @returns
*/
keys(): string[];
/**
* Replace all headers with new set
*
* @param headers
*/
replace(headers?: Record<string, string | string[] | null>): void;
/**
* Add multiple headers
*
* @param headers
*/
add(headers: Record<string, string | string[] | null>): void;
/**
* Returns first header value by name or default
*
* @param key
* @param defaultValue
* @returns
*/
get<R = undefined>(key: string, defaultValue?: string | null): R extends undefined ? string | null : R;
/**
* Sets a header by name.
*
* @param replace Whether to replace existing values (default true)
*/
set(key: string, values: string | string[] | null, replace?: boolean): void;
/**
* Returns true if header exists
*
* @param key
* @returns
*/
has(key: string): boolean;
/**
* Returns true if header contains value
*
* @param key
* @param value
* @returns
*/
contains(key: string, value: string): boolean;
/**
* Removes a header
*
* @param key
*/
remove(key: string): void;
/**
* Returns parsed date from header
*
* @param key
* @param defaultValue
* @returns
*/
getDate(key: string, defaultValue?: Date | null): DateTime | undefined;
/**
* Adds a Cache-Control directive
*
* @param key
* @param value
*/
addCacheControlDirective(key: string, value?: string | boolean): void;
/**
* Returns true if Cache-Control directive is defined
*
* @param key
* @returns
*/
hasCacheControlDirective(key: string): boolean;
/**
* Returns a Cache-Control directive value by name
*
* @param key
* @returns
*/
getCacheControlDirective(key: string): string | boolean | null;
/**
* Removes a Cache-Control directive
*
* @param key
* @returns
*/
removeCacheControlDirective(key: string): void;
/**
* Number of headers
*
* @param key
* @returns
*/
count(): number;
/**
* Normalize header name to lowercase with hyphens
*
* @param key
* @returns
*/
protected normalizeKey(key: string): string;
/**
* Generates Cache-Control header string
*
* @param header
* @returns
*/
protected getCacheControlHeader(): string;
/**
* Parses Cache-Control header
*
* @param header
* @returns
*/
protected parseCacheControl(header: string): Record<string, string | boolean>;
/**
* Iterator support
* @returns
*/
[Symbol.iterator](): Iterator<[string, (string | null)[]]>;
}
//#endregion
//#region src/Utilities/Cookie.d.ts
/**
* Represents a Cookie
*/
declare class Cookie {
private name;
private value?;
private domain?;
private secure?;
private httpOnly;
static readonly SAMESITE_NONE = "none";
static readonly SAMESITE_LAX = "lax";
static readonly SAMESITE_STRICT = "strict";
private expire;
private path;
private sameSite?;
private raw;
private partitioned;
private secureDefault;
private static readonly RESERVED_CHARS_LIST;
private static readonly RESERVED_CHARS_FROM;
private static readonly RESERVED_CHARS_TO;
constructor(name: string, value?: string | null | undefined, expire?: number | string | Date, path?: string, domain?: string | null | undefined, secure?: boolean | null | undefined, httpOnly?: boolean, raw?: boolean, sameSite?: string | null, partitioned?: boolean);
/**
* Create a Cookie instance from a Set-Cookie header string.
*/
static fromString(cookie: string, decode?: boolean): Cookie;
/**
* Convert various expiration formats into a timestamp (seconds)
*/
private static expiresTimestamp;
private clone;
withValue(value: string | null): Cookie;
withDomain(domain: string | null): Cookie;
withPath(path: string | null): Cookie;
withSecure(secure?: boolean): Cookie;
withHttpOnly(httpOnly?: boolean): Cookie;
withRaw(raw?: boolean): Cookie;
withSameSite(sameSite?: string | null): Cookie;
withPartitioned(partitioned?: boolean): Cookie;
withExpires(expire: number | string | Date): Cookie;
getName(): string;
getValue(): string | undefined | null;
getDomain(): string | undefined | null;
getPath(): string;
getExpiresTime(): number;
getMaxAge(): number;
/**
* Checks whether the cookie should only be transmitted over a secure HTTPS connection from the client.
*/
isSecure(): boolean;
isHttpOnly(): boolean;
isRaw(): boolean;
getSameSite(): string | undefined | null;
isPartitioned(): boolean;
/**
* Whether this cookie is about to be cleared.
*/
isCleared(): boolean;
/**
* Convert the cookie to a Set-Cookie header string.
*/
toString(): string;
/**
* @param bool $default The default value of the "secure" flag when it is set to null
*/
setSecureDefault(defaultValue: boolean): void;
}
//#endregion
//#region src/Utilities/ResponseHeaderBag.d.ts
/**
* ResponseHeaderBag is a container for Response HTTP headers.
* for Node/H3 environments.
*/
declare class ResponseHeaderBag extends HeaderBag {
static readonly COOKIES_FLAT = "flat";
static readonly COOKIES_ARRAY = "array";
static readonly DISPOSITION_ATTACHMENT = "attachment";
static readonly DISPOSITION_INLINE = "inline";
protected computedCacheControl: Record<string, string | boolean>;
protected cookies: Record<string, Record<string, Record<string, Cookie>>>;
protected headerNames: Record<string, string>;
constructor(
/**
* The current H3 H3Event instance
*/
event: H3Event);
/**
* Returns the headers with original capitalizations.
*/
allPreserveCase(): Record<string, string[]>;
allPreserveCaseWithoutCookies(): Record<string, string[]>;
replace(headers?: Record<string, string | string[]>): void;
all<K extends string | undefined>(key?: K): K extends string ? (string | null)[] : Record<string, (string | null)[]>;
set(key: string, values: string | string[] | null, replace?: boolean): void;
remove(key: string): void;
hasCacheControlDirective(key: string): boolean;
getCacheControlDirective(key: string): boolean | string | null;
setCookie(cookie: Cookie): void;
removeCookie(name: string, path?: string, domain?: string | null): void;
/**
* @throws {Error} if format is invalid
*/
getCookies(format?: string): Cookie[] | Record<string, any>;
clearCookie(name: string, path?: string, domain?: string | null, secure?: boolean, httpOnly?: boolean, sameSite?: string | null, partitioned?: boolean): void;
makeDisposition(disposition: string, filename: string, fallback?: string): string;
protected computeCacheControlValue(): string;
private initDate;
}
//#endregion
//#region src/Utilities/HttpResponse.d.ts
declare class HttpResponse {
/**
* The current H3 H3Event instance
*/
protected readonly event: H3Event;
protected statusCode: number;
protected headers: ResponseHeaderBag;
protected content: any;
protected version: string;
protected statusText: string;
protected charset?: string;
/**
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
*/
private HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES;
/**
* The exception that triggered the error response (if applicable).
*/
exception?: Error;
/**
* Tracks headers already sent in informational responses.
*/
private sentHeaders;
/**
* Status codes translation table.
*
* The list of codes is complete according to the
* @link https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml Hypertext Transfer Protocol (HTTP) Status Code Registry
* (last updated 2021-10-01).
*
* Unless otherwise noted, the status code is defined in RFC2616.
*/
static statusTexts: {
[key: number]: string;
};
constructor(
/**
* The current H3 H3Event instance
*/
event: H3Event);
/**
* Set HTTP status code.
*/
setStatusCode(code: number, text?: string): this;
/**
* Retrieves the status code for the current web response.
*/
getStatusCode(): number;
/**
* Sets the response charset.
*/
setCharset(charset: string): this;
/**
* Retrieves the response charset.
*/
getCharset(): string | undefined;
/**
* Returns true if the response may safely be kept in a shared (surrogate) cache.
*
* Responses marked "private" with an explicit Cache-Control directive are
* considered uncacheable.
*
* Responses with neither a freshness lifetime (Expires, max-age) nor cache
* validator (Last-Modified, ETag) are considered uncacheable because there is
* no way to tell when or how to remove them from the cache.
*
* Note that RFC 7231 and RFC 7234 possibly allow for a more permissive implementation,
* for example "status codes that are defined as cacheable by default [...]
* can be reused by a cache with heuristic expiration unless otherwise indicated"
* (https://tools.ietf.org/html/rfc7231#section-6.1)
*
* @final
*/
isCacheable(): boolean;
/**
* Returns true if the response is "fresh".
*
* Fresh responses may be served from cache without any interaction with the
* origin. A response is considered fresh when it includes a Cache-Control/max-age
* indicator or Expires header and the calculated age is less than the freshness lifetime.
*/
isFresh(): boolean;
/**
* Returns true if the response includes headers that can be used to validate
* the response with the origin server using a conditional GET request.
*/
isValidateable(): boolean;
/**
* Sets the response content.
*/
setContent(content?: any): this;
/**
* Gets the current response content.
*/
getContent(): any;
/**
* Set a header.
*/
setHeader(name: string, value: string): this;
/**
* Sets the HTTP protocol version (1.0 or 1.1).
*/
setProtocolVersion(version: string): this;
/**
* Gets the HTTP protocol version.
*/
getProtocolVersion(): string;
/**
* Marks the response as "private".
*
* It makes the response ineligible for serving other clients.
*/
setPrivate(): this;
/**
* Marks the response as "public".
*
* It makes the response eligible for serving other clients.
*/
setPublic(): this;
/**
* Returns the Date header as a DateTime instance.
* @throws {RuntimeException} When the header is not parseable
*/
getDate(): DateTime | undefined;
/**
* Returns the age of the response in seconds.
*
* @final
*/
getAge(): number;
/**
* Marks the response stale by setting the Age header to be equal to the maximum age of the response.
*/
expire(): this;
/**
* Returns the value of the Expires header as a DateTime instance.
*
* @final
*/
getExpires(): DateTime | undefined;
/**
* Returns the number of seconds after the time specified in the response's Date
* header when the response should no longer be considered fresh.
*
* First, it checks for a s-maxage directive, then a max-age directive, and then it falls
* back on an expires header. It returns null when no maximum age can be established.
*/
getMaxAge(): number | undefined;
/**
* Sets the number of seconds after which the response should no longer be considered fresh.
*
* This method sets the Cache-Control max-age directive.
*/
setMaxAge(value: number): this;
/**
* Sets the number of seconds after which the response should no longer be returned by shared caches when backend is down.
*
* This method sets the Cache-Control stale-if-error directive.
*/
setStaleIfError(value: number): this;
/**
* Sets the number of seconds after which the response should no longer return stale content by shared caches.
*
* This method sets the Cache-Control stale-while-revalidate directive.
*/
setStaleWhileRevalidate(value: number): this;
/**
* Returns the response's time-to-live in seconds.
*
* It returns null when no freshness information is present in the response.
*
* When the response's TTL is 0, the response may not be served from cache without first
* revalidating with the origin.
*
* @final
*/
getTtl(): number | undefined;
/**
* Sets the response's time-to-live for shared caches in seconds.
*
* This method adjusts the Cache-Control/s-maxage directive.
*/
setTtl(seconds: number): this;
/**
* Sets the response's time-to-live for private/client caches in seconds.
*
* This method adjusts the Cache-Control/max-age directive.
*/
setClientTtl(seconds: number): this;
/**
* Sets the number of seconds after which the response should no longer be considered fresh by shared caches.
*
* This method sets the Cache-Control s-maxage directive.
*/
setSharedMaxAge(value: number): this;
/**
* Returns the Last-Modified HTTP header as a DateTime instance.
*
* @throws \RuntimeException When the HTTP header is not parseable
*
* @final
*/
getLastModified(): DateTime | undefined;
/**
* Sets the Last-Modified HTTP header with a DateTime instance.
*
* Passing null as value will remove the header.
*
* @return $this
*
* @final
*/
setLastModified(date?: DateTime | Date | string): this;
/**
* Returns the literal value of the ETag HTTP header.
*/
getEtag(): string | null;
/**
* Sets the ETag value.
*
* @param etag The ETag unique identifier or null to remove the header
* @param weak Whether you want a weak ETag or not
*/
setEtag(etag?: string, weak?: boolean): this;
/**
* Sets the response's cache headers (validation and/or expiration).
*
* Available options are: must_revalidate, no_cache, no_store, no_transform, public, private, proxy_revalidate, max_age, s_maxage, immutable, last_modified and etag.
*
* @throws {InvalidArgumentException}
*/
setCache(options: CacheOptions): this;
/**
* Modifies the response so that it conforms to the rules defined for a 304 status code.
*
* This sets the status, removes the body, and discards any headers
* that MUST NOT be included in 304 responses.
* @see https://tools.ietf.org/html/rfc2616#section-10.3.5
*/
setNotModified(): this;
/**
* Add an array of headers to the response.
*
*/
withHeaders(headers: HeaderBag | ResponseObject): this;
/**
* Set the exception to attach to the response.
*/
withException(e: Error): this;
/**
* Throws the response in a HttpResponseException instance.
*
* @throws {HttpResponseException}
*/
throwResponse(): void;
/**
* Is response invalid?
*
* @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
*/
isInvalid(): boolean;
/**
* Is response informative?
*/
isInformational(): boolean;
/**
* Is response successful?
*/
isSuccessful(): boolean;
/**
* Is the response a redirect?
*/
isRedirection(): boolean;
/**
* Is there a client error?
*/
isClientError(): boolean;
/**
* Was there a server side error?
*/
isServerError(): boolean;
/**
* Is the response OK?
*/
isOk(): boolean;
/**
* Is the response forbidden?
*/
isForbidden(): boolean;
/**
* Is the response a not found error?
*/
isNotFound(): boolean;
/**
* Is the response a redirect of some form?
*/
isRedirect(location?: string | null): boolean;
/**
* Is the response empty?
*/
isEmpty(): boolean;
/**
* Apply headers before sending response.
*/
sendHeaders(statusCode?: number): this;
/**
* Prepares the Response before it is sent to the client.
*
* This method tweaks the Response to ensure that it is
* compliant with RFC 2616. Most of the changes are based on
* the Request that is "associated" with this Response.
**/
prepare(request: Request): this;
/**
* Checks if we need to remove Cache-Control for SSL encrypted downloads when using IE < 9.
*
* @see http://support.microsoft.com/kb/323308
*/
protected ensureIEOverSSLCompatibility(request: Request): void;
}
//#endregion
//#region src/Exceptions/HttpResponseException.d.ts
declare class HttpResponseException extends Error {
/**
* The underlying response instance.
*/
protected response: HttpResponse;
/**
* Create a new HTTP response exception instance.
*
* @param response
* @param previous
*/
constructor(response: HttpResponse, previous?: Error);
/**
* Get the underlying response instance.
*/
getResponse(): HttpResponse;
}
//#endregion
//#region src/Exceptions/SuspiciousOperationException.d.ts
declare class SuspiciousOperationException extends Error {
constructor(message: string);
}
//#endregion
//#region src/Exceptions/UnexpectedValueException.d.ts
declare class UnexpectedValueException extends Error {
constructor(message: string);
}
//#endregion
//#region src/UploadedFile.d.ts
declare class UploadedFile {
originalName: string;
mimeType: string;
size: number;
content: File;
constructor(originalName: string, mimeType: string, size: number, content: File);
static createFromBase(file: File): UploadedFile;
/**
* Save to disk (Node environment only)
*/
moveTo(destination: string): Promise<void>;
}
//#endregion
//#region src/FormRequest.d.ts
declare class FormRequest {
protected dataset: {
files: Record<string, File | UploadedFile | (File | UploadedFile)[]>;
input: Record<string, any>;
};
constructor(data: FormData);
/**
* Initialize the data
* @param data
*/
initialize(data: FormData): void;
/**
* Get all uploaded files
*/
files(): Record<string, File | UploadedFile | (File | UploadedFile)[]>;
/**
* Get all input fields
*/
input(): Record<string, any>;
/**
* Get combined input and files
* File entries take precedence if names overlap.
*/
all(): Record<string, any>;
}
//#endregion
//#region src/HttpContext.d.ts
/**
* Represents the HTTP context for a single request lifecycle.
* Encapsulates the application instance, request, and response objects.
*/
declare class HttpContext implements HttpContext$1 {
app: IApplication;
request: IRequest;
response: IResponse;
private static contexts;
constructor(app: IApplication, request: IRequest, response: IResponse);
/**
* Factory method to create a new HttpContext instance from a context object.
* @param ctx - Object containing app, request, and response
* @returns A new HttpContext instance
*/
static init(ctx: {
app: IApplication;
request: IRequest;
response: IResponse;
}, event?: unknown): HttpContext;
/**
* Retrieve an existing HttpContext instance for an event, if any.
*/
static get(event: unknown): HttpContext | undefined;
/**
* Delete the cached context for a given event (optional cleanup).
*/
static forget(event: unknown): void;
}
//#endregion
//#region src/Middleware.d.ts
declare abstract class Middleware implements IMiddleware {
abstract handle(context: HttpContext, next: () => Promise<unknown>): Promise<unknown>;
}
//#endregion
//#region src/Middleware/LogRequests.d.ts
declare class LogRequests extends Middleware {
handle({
request
}: HttpContext, next: () => Promise<unknown>): Promise<unknown>;
}
//#endregion
//#region src/Providers/HttpServiceProvider.d.ts
/**
* Sets up HTTP kernel and request lifecycle.
*
* Register Request, Response, and Middleware classes.
* Configure global middleware stack.
* Boot HTTP kernel.
*
* Auto-Registered
*/
declare class HttpServiceProvider {
private app;
static priority: number;
registeredCommands?: (new (app: any, kernel: any) => any)[];
constructor(app: any);
register(): void;
boot(): void;
}
//#endregion
//#region src/Utilities/ParamBag.d.ts
/**
* ParamBag is a container for key/value pairs
* for Node/H3 environments.
*/
declare class ParamBag implements IParamBag {
protected parameters: RequestObject;
/**
* The current H3 H3Event instance
*/
readonly event: H3Event;
constructor(parameters: RequestObject | undefined,
/**
* The current H3 H3Event instance
*/
event: H3Event);
/**
* Returns the parameters.
* @
* @param key The name of the parameter to return or null to get them all
*
* @throws BadRequestException if the value is not an array
*/
all(key?: string): any;
get(key: string, defaultValue?: any): any;
set(key: string, value: any): void;
/**
* Returns true if the parameter is defined.
*
* @param key
*/
has(key: string): boolean;
/**
* Removes a parameter.
*
* @param key
*/
remove(key: string): void;
/**
*
* Returns the parameter as string.
*
* @param key
* @param defaultValue
* @throws UnexpectedValueException if the value cannot be converted to string
* @returns
*/
getString(key: string, defaultValue?: string): string;
/**
* Returns the parameter value converted to integer.
*
* @param key
* @param defaultValue
* @throws UnexpectedValueException if the value cannot be converted to integer
*/
getInt(key: string, defaultValue?: number): number;
/**
* Returns the parameter value converted to boolean.
*
* @param key
* @param defaultValue
* @throws UnexpectedValueException if the value cannot be converted to a boolean
*/
getBoolean(key: string, defaultValue?: boolean): boolean;
/**
* Returns the alphabetic characters of the parameter value.
*
* @param key
* @param defaultValue
* @throws UnexpectedValueException if the value cannot be converted to string
*/
getAlpha(key: string, defaultValue?: string): string;
/**
* Returns the alphabetic characters and digits of the parameter value.
*
* @param key
* @param defaultValue
* @throws UnexpectedValueException if the value cannot be converted to string
*/
getAlnum(key: string, defaultValue?: string): string;
/**
* Returns the digits of the parameter value.
*
* @param key
* @param defaultValue
* @throws UnexpectedValueException if the value cannot be converted to string
* @returns
**/
getDigits(key: string, defaultValue?: string): string;
/**
* Returns the parameter keys.
*/
keys(): string[];
/**
* Replaces the current parameters by a new set.
*/
replace(parameters?: RequestObject): void;
/**
* Adds parameters.
*/
add(parameters?: RequestObject): void;
/**
* Returns the number of parameters.
*/
count(): number;
/**
* Returns an iterator for parameters.
*
* @returns
*/
[Symbol.iterator](): ArrayIterator<[string, any]>;
}
//#endregion
//#region src/Utilities/InputBag.d.ts
/**
* InputBag is a container for user input values
* (e.g., query params, body, cookies)
* for Node/H3 environments.
*/
declare class InputBag extends ParamBag {
constructor(inputs: RequestObject | undefined,
/**
* The current H3 H3Event instance
*/
event: H3Event);
/**
* Returns a scalar input value by name.
*
* @param key
* @param defaultValue
* @throws BadRequestException if the input contains a non-scalar value
* @returns
*/
get<T extends string | number | boolean | null>(key: string, defaultValue?: T | null): T | string | number | boolean | null;
/**
* Replaces all current input values.
*
* @param inputs
* @returns
*/
replace(inputs?: RequestObject): void;
/**
* Adds multiple input values.
*
* @param inputs
* @returns
*/
add(inputs?: RequestObject): void;
/**
* Sets an input by name.
*
* @param key
* @param value
* @throws TypeError if value is not scalar or array
* @returns
*/
set(key: string, value: any): void;
/**
* Returns true if a key exists.
*
* @param key
* @returns
*/
has(key: string): boolean;
/**
* Returns all parameters.
*
* @returns
*/
all(): RequestObject;
/**
* Converts a parameter value to string.
*
* @param key
* @param defaultValue
* @throws BadRequestException if input contains a non-scalar value
* @returns
*/
getString(key: string, defaultValue?: string): string;
/**
* Filters input value with a predicate.
* Mimics PHP’s filter_var() in spirit, but simpler.
*
* @param key
* @param defaultValue
* @param filterFn
* @throws BadRequestException if validation fails
* @returns
*/
filter<T = any>(key: string, defaultValue?: T | null, filterFn?: (value: any) => boolean): T | null;
/**
* Returns an enum value by key.
*
* @param key
* @param EnumClass
* @param defaultValue
* @throws BadRequestException if conversion fails
* @returns
*/
getEnum<T extends Record<string, string | number>>(key: string, EnumClass: T, defaultValue?: T[keyof T] | null): T[keyof T] | null;
/**
* Removes a key.
*
* @param key
*/
remove(key: string): void;
/**
* Returns all keys.
*
* @returns
*/
keys(): string[];
/**
* Returns number of parameters.
*
* @returns
*/
count(): number;
}
//#endregion
//#region src/Utilities/FileBag.d.ts
type FileInput = UploadedFile | File | null | undefined;
/**
* FileBag is a container for uploaded files
* for Node/H3 environments.
*/
declare class FileBag extends ParamBag {
protected parameters: Record<string, UploadedFile | UploadedFile[] | null>;
constructor(parameters: Record<string, FileInput | FileInput[]> | undefined,
/**
* The current H3 H3Event instance
*/
event: H3Event);
/**
* Replace all stored files.
*/
replace(files?: Record<string, FileInput | FileInput[]>): void;
/**
* Set a file or array of files.
*/
set(key: string, value: FileInput | FileInput[]): void;
/**
* Add multiple files.
*/
add(files?: Record<string, FileInput | FileInput[]>): void;
/**
* Get all stored files.
*/
all(): Record<string, UploadedFile | UploadedFile[] | null>;
/**
* Normalize file input into UploadedFile instances.
*/
protected convertFileInformation(file: FileInput): UploadedFile | null;
}
//#endregion
//#region src/Utilities/ServerBag.d.ts
/**
* ServerBag — a simplified version of Symfony's ServerBag
* for Node/H3 environments.
*
* Responsible for extracting and normalizing HTTP headers
* from the incoming request.
*/
declare class ServerBag extends ParamBag {
constructor(parameters: Record<string, string | undefined> | undefined,
/**
* The current H3 H3Event instance
*/
event: H3Event);
/**
* Returns all request headers, normalized to uppercase with underscores.
* Example: content-type → CONTENT_TYPE
*/
getHeaders(): Record<string, string>;
/**
* Returns a specific header by name, case-insensitive.
*/
get(name: string): string | undefined;
/**
* Returns true if a header exists.
*/
has(name: string): boolean;
}
//#endregion
//#region src/Utilities/HttpRequest.d.ts
declare class HttpRequest {
#private;
/**
* The current H3 H3Event instance
*/
protected readonly event: H3Event;
/**
* The current app instance
*/
app: Application;
HEADER_FORWARDED: number;
HEADER_X_FORWARDED_FOR: number;
HEADER_X_FORWARDED_HOST: number;
HEADER_X_FORWARDED_PROTO: number;
HEADER_X_FORWARDED_PORT: number;
HEADER_X_FORWARDED_PREFIX: number;
HEADER_X_FORWARDED_AWS_ELB: number;
HEADER_X_FORWARDED_TRAEFIK: number;
METHOD_HEAD: string;
METHOD_GET: string;
METHOD_POST: string;
METHOD_PUT: string;
METHOD_PATCH: string;
METHOD_DELETE: string;
METHOD_PURGE: string;
METHOD_OPTIONS: string;
METHOD_TRACE: string;
METHOD_CONNECT: string;
/**
* Names for headers that can be trusted when
* using trusted proxies.
*
* The FORWARDED header is the standard as of rfc7239.
*
* The other headers are non-standard, but widely used
* by popular reverse proxies (like Apache mod_proxy or Amazon EC2).
*/
private TRUSTED_HEADERS;
private FORWARDED_PARAMS;
/**
* Parsed request body
*/
body: unknown;
protected format?: string;
protected formData: FormRequest;
private preferredFormat?;
private isForwardedValid;
private static trustedHeaderSet;
/**
* Gets route parameters.
* @returns An object containing route parameters.
*/
params: NonNullable<H3Event['context']['params']>;
/**
* Request body parameters (POST).
*
* @see getPayload() for portability between content types
*/
protected request: InputBag;
/**
* Uploaded files (FILES).
*/
files: FileBag;
/**
* Query string parameters (GET).
*/
query: InputBag;
/**
* Server and execution environment parameters
*/
server: ServerBag;
/**
* Cookies
*/
cookies: InputBag;
/**
* The request attributes (parameters parsed from the PATH_INFO, ...).
*/
attributes: ParamBag;
/**
* Gets the request headers.
* @returns An object containing request headers.
*/
headers: HeaderBag;
protected content?: ReadableStream | string | false | null;
protected static formats?: Record<string, string[]> | undefined | null;
protected static trustedProxies: string[];
protected static httpMethodParameterOverride: boolean;
/**
* List of Acceptable Content Types
*/
private acceptableContentTypes;
private trustedValuesCache;
constructor(
/**
* The current H3 H3Event instance
*/
event: H3Event,
/**
* The current app instance
*/
app: Application);
/**
* Sets the parameters for this request.
*
* This method also re-initializes all properties.
*
* @param attributes
* @param cookies The COOKIE parameters
* @param files The FILES parameters
* @param server The SERVER parameters
* @param content The raw body data
*/
initialize(): Promise<void>;
/**
* Gets a list of content types acceptable by the client browser in preferable order.
* @returns {string[]}
*/
getAcceptableContentTypes(): string[];
/**
* Get a URI instance for the request.
*/
getUriInstance(): Url;
/**
* Checks whether the request is secure or not.
*
* This method can read the client protocol from the "X-Forwarded-Proto" header
* when trusted proxies were set via "setTrustedProxies()".
*
* The "X-Forwarded-Proto" header must contain the protocol: "https" or "http".
*/
isSecure(): boolean;
/**
* Returns the value of the requested header.
*/
getHeader(name: string): string | undefined | null;
/**
* Checks if the request method is of specified type.
*
* @param method Uppercase request method (GET, POST etc)
*/
isMethod(method: string): boolean;
/**
* Checks whether or not the method is safe.
*
* @see https://tools.ietf.org/html/rfc7231#section-4.2.1
*/
isMethodSafe(): boolean;
/**
* Checks whether or not the method is idempotent.
*/
isMethodIdempotent(): boolean;
/**
* Checks whether the method is cacheable or not.
*
* @see https://tools.ietf.org/html/rfc7231#section-4.2.3
*/
isMethodCacheable(): boolean;
/**
* Returns true if the request is an XMLHttpRequest (AJAX).
*/
isXmlHttpRequest(): boolean;
/**
* Initializes HTTP request formats.
*/
protected static initializeFormats(): void;
/**
* Gets the request "intended" method.
*
* If the X-HTTP-Method-Override header is set, and if the method is a POST,
* then it is used to determine the "real" intended HTTP method.
*
* The _method request parameter can also be used to determine the HTTP method,
* but only if enableHttpMethodParameterOverride() has been called.
*
* The method is always an uppercased string.
*
* @see getRealMethod()
*/
getMethod(): RequestMethod;
/**
* Gets the preferred format for the response by inspecting, in the following order:
* * the request format set using setRequestFormat;
* * the values of the Accept HTTP header.
*
* Note that if you use this method, you should send the "Vary: Accept" header
* in the response to prevent any issues with intermediary HTTP caches.
*/
getPreferredFormat(defaultValue?: string): string | undefined;
/**
* Gets the format associated with the mime type.
*/
getFormat(mimeType: string): string | undefined;
/**
* Gets the request format.
*
* Here is the process to determine the format:
*
* * format defined by the user (with setRequestFormat())
* * _format request attribute
* * $default
*
* @see getPreferredFormat
*/
getRequestFormat(defaultValue?: string): string | undefined;
/**
* Sets the request format.
*/
setRequestFormat(format: string): void;
/**
* Gets the "real" request method.
*
* @see getMethod()
*/
getRealMethod(): RequestMethod;
/**
* Gets the mime type associated with the format.
*/
getMimeType(format: string): string | undefined;
/**
* Gets the mime types associated with the format.
*/
static getMimeTypes(format: string): string[];
/**
* Gets the list of trusted proxies.
*/
static getTrustedProxies(): string[];
/**
* Returns the request body content.
*
* @param asStream If true, returns a ReadableStream instead of the parsed string
* @return {string | ReadableStream | Promise<string | ReadableStream>}
*/
getContent(asStream?: boolean): string | ReadableStream;
/**
* Gets a "parameter" value from any bag.
*
* This method is mainly useful for libraries that want to provide some flexibility. If you don't need the
* flexibility in controllers, it is better to explicitly get request parameters from the appropriate
* public property instead (attributes, query, request).
*
* Order of precedence: PATH (routing placeholders or custom attributes), GET, POST
*
* @internal use explicit input sources instead
*/
get(key: string, defaultValue?: any): any;
/**
* Indicates whether this request originated from a trusted proxy.
*
* This can be useful to determine whether or not to trust the
* contents of a proxy-specific header.
*/
isFromTrustedProxy(): boolean;
/**
* This method is rather heavy because it splits and merges headers, and it's called by many other methods such as
* getPort(), isSecure(), getHost(), getClientIps(), getBaseUrl() etc. Thus, we try to cache the results for
* best performance.
*/
private getTrustedValues;
private normalizeAndFilterClientIps;
/**
* Enables support for the _method request parameter to determine the intended HTTP method.
*
* Be warned that enabling this feature might lead to CSRF issues in your code.
* Check that you are using CSRF tokens when required.
* If the HTTP method parameter override is enabled, an html-form with method "POST" can be altered
* and used to send a "PUT" or "DELETE" request via the _method request parameter.
* If these methods are not protected against CSRF, this presents a possible vulnerability.
*
* The HTTP method can only be overridden when the real HTTP method is POST.
*/
static enableHttpMethodParameterOverride(): void;
/**
* Checks whether support for the _method request parameter is enabled.
*/
static getHttpMethodParameterOverride(): boolean;
}
//#endregion
//#region src/Request.d.ts
declare class Request extends HttpRequest implements IRequest {
#private;
/**
* All of the converted files for the request.
*/
protected convertedFiles?: Record<string, UploadedFile | UploadedFile[]>;
constructor(
/**
* The current H3 H3Event instance
*/
event: H3Event,
/**
* The current app instance
*/
app: Application);
/**
* Factory method to create a Request instance from an H3Event.
*/
static create(
/**
* The current H3 H3Event instance
*/
event: H3Event,
/**
* The current app instance
*/
app: Application): Promise<Request>;
private setBody;
/**
* Retrieve all data from the instance (query + body).
*/
all<T = Record<string, any>>(keys?: string | string[]): T;
/**
* Retrieve an input item from the request.
*
* @param key
* @param defaultValue
* @returns
*/
input<K extends string | undefined>(key?: K, defaultValue?: any): K extends undefined ? RequestObject : any;
/**
* Retrieve a file from the request.
*
* By default a single `UploadedFile` instance will always be returned by
* the method (first file in property when there are multiple), unless
* the `expectArray` parameter is set to true, in which case, the method
* returns an `UploadedFile[]` array.
*
* @param key
* @param defaultValue
* @param expectArray set to true to return an `UploadedFile[]` array.
* @returns
*/
file<K extends string | undefined = undefined, E extends boolean | undefined = undefined>(key?: K, defaultValue?: any, expectArray?: E): K extends undefined ? Record<string, E extends true ? UploadedFile[] : UploadedFile> : E extends true ? UploadedFile[] : UploadedFile;
/**
* Determine if the uploaded data contains a file.
*
* @param key
* @return boolean
*/
hasFile(key: string): boolean;
/**
* Check that the given file is a valid file instance.
*
* @param file
* @return boolean
*/
protected isValidFile(file: UploadedFile): boolean;
/**
* Get an object with all the files on the request.
*/
allFiles(): Record<string, UploadedFile | UploadedFile[]>;
/**
* Extract and convert uploaded files from FormData.
*/
convertUploadedFiles(files: Record<string, UploadedFile | UploadedFile[]>): Record<string, UploadedFile | UploadedFile[]>;
/**
* Determine if the data contains a given key.
*
* @param keys
* @returns
*/
has(keys: string[] | string): boolean;
/**
* Determine if the instance is missing a given key.
*/
missing(key: string | string[]): boolean;
/**
* Get a subset containing the provided keys with values from the instance data.
*
* @param keys
* @returns
*/
only<T = Record<string, any>>(keys: string[]): T;
/**
* Get all of the data except for a specified array of items.
*
* @param keys
* @returns
*/
except<T = Record<string, any>>(keys: string[]): T;
/**
* Merges new input data into the current request's input source.
*
* @param input - An object containing key-value pairs to merge.
* @returns this - For fluent chaining.
*/
merge(input: Record<string, any>): this;
/**
* Merge new input into the request's input, but only when that key is missing from the request.
*
* @param input
*/
mergeIfMissing(input: Record<string, any>): this;
/**
* Get the keys for all of the input and files.
*/
keys(): string[];
/**
* Determine if the request is sending JSON.
*
* @return bool
*/
isJson(): boolean;
/**
* Determine if the current request probably expects a JSON response.
*
* @returns
*/
expectsJson(): boolean;
/**
* Determine if the current request is asking for JSON.
*
* @returns
*/
wantsJson(): boolean;
/**
* Determine if the request is the result of a PJAX call.
*
* @return bool
*/
pjax(): boolean;
/**
* Returns true if the request is an XMLHttpRequest (AJAX).
*
* @alias isXmlHttpRequest()
* @returns {boolean}
*/
ajax(): boolean;
/**
* Get the client IP address.
*/
ip(): string | undefined;
/**
* Get a URI instance for the request.
*/
uri(): Url;
/**
* Get the full URL for the request.
*/
fullUrl(): string;
/**
* Return the Request instance.
*/
instance(): this;
/**
* Get the request method.
*/
method(): RequestMethod;
/**
* Get the JSON payload for the request.
*
* @param key
* @param defaultValue
* @return {InputBag}
*/
json<K extends string | undefined = undefined>(key?: string, defaultValue?: any): K extends undefined ? InputBag : any;
/**
* Get the input source for the request.
*
* @return {InputBag}
*/
protected getInputSource(): InputBag;
/**
* Dump the items.
*
* @param keys
*/
dump(...keys: any[]): this;
/**
* Get the base event
*/
getEvent(): H3Event;
getEvent<K extends DotNestedKeys<H3Event>>(key: K): DotNestedValue<H3Event, K>;
}
//#endregion
//#region src/Resources/JsonResource.d.ts
interface Resource {
[key: string]: any;
pagination?: {
from?: number | undefined;
to?: number | undefined;
perPage?: number | undefined;
total?: number | undefined;
} | undefined;
}
type BodyResource = Resource & {
data: Omit<Resource, 'pagination'>;
meta?: {
pagination?: Resource['pagination'];
} | undefined;
};
/**
* Class to render API resource
*/
declare class JsonResource<R extends Resource = any> {
#private;
protected event: H3Event;
/**
* The request instance
*/
request: H3Event<EventHandlerRequest>['req'];
/**
* The response instance
*/
response: H3Event['res'];
/**
* The data to send to the client
*/
resource: R;
/**
* The final response data object
*/
body: BodyResource;
/**
* Flag to track if response should be sent automatically
*/
private shouldSend;
/**
* Flag to track if response has been sent
*/
private responseSent;
/**
* Declare that this includes R's properties
*/
[key: string]: any;
/**
* @param req The request instance
* @param res The response instance
* @param rsc The data to send to the client
*/
constructor(event: H3Event, rsc: R);
/**
* Return the data in the expected format
*
* @returns
*/
data(): Resource;
/**
* Build the response object
* @returns this
*/
json(): this;
/**
* Add context data to the response object
* @param data Context data
* @returns this
*/
additional<X extends {
[key: string]: any;
}>(data: X): this;
/**
* Send the output to the client
* @returns this
*/
send(): this;
/**
* Set the status code for this response
* @param code Status code
* @returns this
*/
status(code: number): this;
/**
* Check if send should be triggered automatically
*/
private checkSend;
}
//#endregion
//#region src/Resources/ApiResource.d.ts
declare function ApiResource(instance: JsonResource): JsonResource<any>;
//#endregion
//#region src/Response.d.ts
declare class Response extends HttpResponse implements IResponse {
/**
* The current app instance
*/
app: Application;
constructor(
/**
* The current H3 H3Event instance
*/
event: H3Event,
/**
* The current app instance
*/
app: Application);
/**
* Sends content for the current web response.
*/
sendContent(type?: 'html' | 'json' | 'text' | 'xml', parse?: boolean): unknown;
/**
* Sends content for the current web response.
*/
send(type?: 'html' | 'json' | 'text' | 'xml'): unknown;
/**
*
* @param content The content to serve
* @param send if set to true, the content will be returned, instead of the Response instance
* @returns
*/
html(content?: string): this;
html(content: string, parse: boolean): HTTPResponse;
/**
* Send a JSON response.
*/
json<T = unknown>(data?: T): this;
json<T = unknown>(data: T, parse: boolean): T;
/**
* Send plain text.
*/
text(content?: string): this;
text(content: string, parse: boolean): HTTPResponse;
/**
* Send plain xml.
*/
xml(data?: string): this;
xml(data: string, parse: boolean): HTTPResponse;
/**
* Build the HTTP Response
*
* @param contentType
* @param data
*/
private httpResponse;
/**
* Redirect to another URL.
*/
redirect(location: string, status?: number, statusText?: string | undefined): HTTPResponse;
/**
* Dump the response.
*/
dump(): this;
/**
* Get the base event
*/
getEvent(): H3Event;
getEvent<K extends DotNestedKeys<H3Event>>(key: K): DotNestedValue<H3Event, K>;
}
//#endregion
//#region src/Utilities/HeaderUtility.d.ts
/**
* HTTP header utility functions .
*/
declare class HeaderUtility {
static readonly DISPOSITION_ATTACHMENT = "attachment";
static readonly DISPOSITION_INLINE = "inline";
private constructor();
/**
* Splits an HTTP header by one or more separators.
*
* Example:
* HeaderUtility.split('da, en-gb;q=0.8', ',;')
* // returns [['da'], ['en-gb', 'q=0.8']]
*/
static split(header: string, separators: string): string[][];
/**
* Combines an array of arrays into one associative object.
* [['foo', 'abc'], ['bar']] => { foo: 'abc', bar: true }
*/
static combine(parts: (string | true)[][]): Record<string, string | boolean>;
/**
* Joins an associative object into a string for use in an HTTP header.
* { foo: 'abc', bar: true, baz: 'a b c' } => 'foo=abc, bar, baz="a b c"'
*/
static toString(assoc: Record<string, string | boolean>, separator: string): string;
/**
* Encodes a string as a quoted string, if necessary.
*/
static quote(s: string): string;
/**
* Decodes a quoted string.
*/
static unquote(s: string): string;
/**
* Generates an HTTP Content-Disposition field-value.
*
* @see RFC 6266
*/
static makeDisposition(disposition: string, filename: string, filenameFallback?: string): string;
/**
* Like parse_str(), but preserves dots in variable names.
*/
static parseQuery(query: string, ignoreBrackets?: boolean, separator?: string): Record<string, any>;
private static groupParts;
}
//#endregion
//#region src/Utilities/IpUtils.d.ts
/**
* Http utility functions for IP handling.
*/
declare class IpUtils {
static readonly PRIVATE_SUBNETS: string[];
private static checkedIps;
private constructor();
/**
* Checks if an IPv4 or IPv6 address is contained in the list of given IPs or subnets.
*
* @param requestIp
* @param ips List of IPs or subnets (can be a string if only a single one)
*/
static checkIp(requestIp?: string, ips?: string | string[]): boolean;
/**
* Compares two IPv4 addresses or checks if one belongs to a CIDR subnet.
*
* @param requestIp
* @param ip IPv4 address or subnet in CIDR notation
*
* @return bool Whether the request IP matches the IP, or whether the request IP is within the CIDR subnet
*/
static checkIp4(requestIp: string, ip: string): boolean;
/**
* Compares two IPv6 addresses or checks if one belongs to a CIDR subnet.
*
* @see https://github.com/dsp/v6tools
*
* @param requestIp
* @param ip IPv6 address or subnet in CIDR notation
*
* @throws {RuntimeException} When IPV6 support is not enabled
*/
static checkIp6(requestIp: string, ip: string): boolean;
/**
* Anonymizes an IPv4/IPv6 by zeroing out trailing bytes.
*
* @param ip
* @param v4Bytes
* @param v6Bytes
*/
static anonymize(ip: string, v4Bytes?: number, v6Bytes?: number): string;
/**
* Checks if IP is within private subnets.
*/
static isPrivateIp(requestIp: string): boolean;
private static isIPv4;
private static isIPv6;
private static ipv4ToLong;
private static inetPton;
private static inetPton4;
private static inetPton6;
private static inetNtop;
private static getCacheResult;
private static setCacheResult;
}
//#endregion
//#region src/Utilities/ResponseUtilities.d.ts
declare enum ResponseCodes {
HTTP_CONTINUE = 100,
HTTP_SWITCHING_PROTOCOLS = 101,
HTTP_PROCESSING = 102,
// RFC2518
HTTP_EARLY_HINTS = 103,
// RFC8297
HTTP_OK = 200,
HTTP_CREATED = 201,
HTTP_ACCEPTED = 202,
HTTP_NON_