import accepts from 'accepts'; import { URL } from 'node:url'; import rangeParser from 'range-parser'; import { Cookie } from './cookies/Cookie.js'; import { UploadedFile } from '@stone-js/filesystem'; import { CookieCollection } from './cookies/CookieCollection.js'; import { IncomingEvent, IncomingEventOptions } from '@stone-js/core'; import { HttpMethods, IOutgoingHttpResponse, IRoute } from './declarations.js'; /** * IncomingHttpEventOptions interface. */ export interface IncomingHttpEventOptions extends IncomingEventOptions { url: URL; ip: string; ips?: string[]; protocol?: string; method?: HttpMethods; queryString?: string; cookies?: CookieCollection; body?: Record; files?: Record; headers?: Record | Headers; } /** * Class representing an IncomingHttpEvent. * * @author Mr. Stone */ /** The result of an HTTP content-negotiation lookup: the best match, all matches, or false. */ export type NegotiationResult = string | string[] | false; export declare class IncomingHttpEvent extends IncomingEvent { static readonly INCOMING_HTTP_EVENT = "stonejs@incoming_http_event"; /** The IP address of the client making the request. */ readonly ip: string; /** The list of IP addresses, typically for proxies. */ readonly ips: string[]; /** The URL of the request. */ readonly url: URL; /** The body of the request. */ readonly body: Record; /** The files included in the request. */ readonly files: Record; /** The query parameters of the request. */ readonly query: URLSearchParams; /** The HTTP method of the request. */ readonly method: HttpMethods; /** The content negotiation handler for the request. */ readonly accepts: accepts.Accepts; /** The headers of the request. */ protected readonly _headers: Headers; /** The cookies included in the request. */ readonly cookies: CookieCollection; /** The protocol used for the request (e.g., http or https). */ readonly protocol: string; /** The query string of the request. */ readonly queryString?: string; protected userResolver?: () => unknown; protected routeResolver?: () => IRoute; /** * Create an IncomingHttpEvent. * * @param options - The IncomingHttpEvent options. * @returns A new instance of IncomingHttpEvent. */ static create(options: IncomingHttpEventOptions): IncomingHttpEvent; /** * Constructor for IncomingHttpEvent. * * @param options - The options to create an IncomingHttpEvent instance. * @throws {HttpError} If the URL option is not a valid instance of URL. */ protected constructor({ ip, url, source, ips, body, files, locale, headers, metadata, protocol, cookies, queryString, method }: IncomingHttpEventOptions); /** @returns The headers of the request. */ get headers(): Record; /** @returns The decoded pathname of the URL. */ get decodedPathname(): string | undefined; /** @returns The hash part of the URL. */ get hash(): string; /** @returns The host of the URL (hostname:port). */ get host(): string; /** @returns The hostname of the URL. */ get hostname(): string; /** @returns The route parameters. */ get params(): Record | undefined; /** @returns The full path including pathname and search query. */ get path(): string; /** @returns The pathname of the URL. */ get pathname(): string; /** @returns The full URL as a string. */ get uri(): string; /** @returns The protocol of the URL (e.g., "http" or "https"). */ get scheme(): string; /** @returns The URL segments split by '/'. */ get segments(): string[]; /** @returns Whether the request was made over a secure connection. */ get isSecure(): boolean; /** @returns Whether the request is an XMLHttpRequest. */ get isXhr(): boolean; /** @returns Whether the request is an AJAX request. */ get isAjax(): boolean; /** @returns The user agent of the request. */ get userAgent(): string | undefined; /** @returns Whether the request was prefetch. */ get isPrefetch(): boolean; /** @returns The ETag of the request, if present. */ get etag(): string | undefined; /** @returns An array of acceptable content types for the request. */ get types(): string[]; /** @returns An array of acceptable character sets for the request. */ get charsets(): string[]; /** @returns An array of acceptable languages for the request. */ get languages(): string[]; /** @returns An array of acceptable encodings for the request. */ get encodings(): string[]; /** @returns The content type specified in the headers. */ get contentType(): string; /** @returns The charset specified in the content-type header. */ get charset(): string | undefined; /** * Get request DATA by key (route params → body → query → metadata). * * SECURITY: does NOT read headers or cookies — use {@link getHeader}/{@link getCookie}. * * @param key - The key to look for. * @returns The value of the key, or undefined. */ get(key: string): TReturn | undefined; /** * Get request DATA by key with a fallback (route params → body → query → metadata). * * SECURITY: does NOT read headers or cookies — use {@link getHeader}/{@link getCookie}. * * @param key - The key to look for. * @param fallback - A fallback value if the key is not found. * @returns The value of the key or the fallback. */ get(key: string, fallback: TReturn): TReturn; /** * Get a header value. * * @param name - The header name. * @returns The header value or the fallback value. * @throws {HttpError} If the header name is not a valid string. */ getHeader(name: string): TReturn | undefined; /** * Get a header value. * * @param name - The header name. * @param fallback - A fallback value if the header is not found. * @returns The header value or the fallback value. * @throws {HttpError} If the header name is not a valid string. */ getHeader(name: string, fallback: TReturn): TReturn; /** * Check if a header exists. * * @param name - The header name to check. * @returns True if the header exists, otherwise false. */ hasHeader(name: string): boolean; /** * Get a cookie value. * * @param name - The cookie name. * @returns The cookie value or the fallback. */ getCookie(name: string): TReturn | undefined; /** * Get a cookie value. * * @param name - The cookie name. * @param fallback - A fallback value if the cookie is not found. * @returns The cookie value or the fallback. */ getCookie(name: string, fallback: TReturn): TReturn; /** * Check if a cookie exists. * * @param name - The cookie name to check. * @returns True if the cookie exists, otherwise false. */ hasCookie(name: string): boolean; /** * Get the body of the request. * * @returns The body of the request or the fallback. */ getBody(): TReturn | undefined; /** * Get the body of the request. * * @param fallback - The fallback value if the body is not found. * @returns The body of the request or the fallback. */ getBody(fallback: TReturn): TReturn; /** * Return the first accepted content type. * * @param values - The content types to check. * @returns The first accepted type, or false if none are accepted. */ acceptsTypes(...values: string[]): NegotiationResult; /** * Return the first accepted encoding. * * @param values - The encodings to check. * @returns The first accepted encoding, or false if none are accepted. */ acceptsEncodings(...values: string[]): NegotiationResult; /** * Return the first accepted charset. * * @param values - The charsets to check. * @returns The first accepted charset, or false if none are accepted. */ acceptsCharsets(...values: string[]): NegotiationResult; /** * Return the first accepted language. * * @param values - The languages to check. * @returns The first accepted language, or false if none are accepted. */ acceptsLanguages(...values: string[]): NegotiationResult; /** * Get MIME type for a given file path or extension. * * @param format - The file path or extension. * @returns The corresponding MIME type, or undefined if not found. */ getMimeType(format: string): string | undefined; /** * Get file extension for a given MIME type. * * @param mimeType - The MIME type. * @returns The corresponding file extension, or undefined if not found. */ getFormat(mimeType: string): string | undefined; /** * Check if the request matches one of the given content types. * * @param types - The content types to check. * @returns The best match, or false if no match is found. */ isType(...types: string[]): string | false; /** * Determines the preferred response type based on content negotiation. * Uses Accept, Content-Type, User-Agent, and AJAX detection. * * @param types - Allowed response types, in priority order. * @param defaultType - Default type if none match. * @returns The best response type as a string. */ preferredType(types?: string[], defaultType?: string): string; /** * Get request range. * * @param size - The maximum size of the resource. * @param combine - Specifies if overlapping & adjacent ranges should be combined. * @returns The parsed range, or undefined if not applicable. */ range(size: number, combine?: boolean): rangeParser.Result | rangeParser.Ranges | undefined; /** * Get a value from the JSON body. * * @param key - The key to look for in the JSON body. * @returns The value of the key or the fallback. */ json(key: string): TReturn | undefined; /** * Get a value from the JSON body. * * @param key - The key to look for in the JSON body. * @param fallback - A fallback value if the key is not found. * @returns The value of the key or the fallback. */ json(key: string, fallback: TReturn): TReturn; /** * Check if a key exists in the JSON body. * * @param key - The key to check for. * @returns True if the key exists, otherwise false. */ hasJson(key: string): boolean; /** * Determine if the response cache is fresh. * * @param response - The outgoing HTTP response to check freshness against. * @returns True if the cache is fresh, otherwise false. */ isFresh(response: IOutgoingHttpResponse): boolean; /** * Determine if the response cache is stale. * * @param response - The outgoing HTTP response to check staleness against. * @returns True if the cache is stale, otherwise false. */ isStale(response: IOutgoingHttpResponse): boolean; /** * Filter and return files based on their names. * * @param files - The array of file names to filter. * @returns An object containing the filtered files. */ filterFiles(files: string[]): Record; /** * Get a file by its name. * * @param name - The name of the file. * @returns The file if it exists, otherwise undefined. */ getFile(name: string): UploadedFile[] | undefined; /** * Check if a file exists by its name. * * @param name - The name of the file. * @returns True if the file exists, otherwise false. */ hasFile(name: string): boolean; /** * Check if the current event method matches the given method. * * @param method - The method to check. * @returns True if the event method matches, otherwise false. */ isMethod(method: string): boolean; /** * Check if the current event method is considered safe. * * @returns True if the method is safe, otherwise false. */ isMethodSafe(): boolean; /** * Check if the current event method is cacheable. * * @returns True if the method is cacheable, otherwise false. */ isMethodCacheable(): boolean; /** * Generate a full URL for the given path. * * @param path - The path to append to the base URL. * @returns The full URL for the given path. */ uriForPath(path: string): string; /** * Get the URI with or without the domain. * * @param withDomain - Whether to include the domain in the URI. * @returns The URI with or without the domain. */ getUri(withDomain?: boolean): string | undefined; /** * Get the user instance. * * @returns The user object, resolved through a user resolver function if available. */ getUser(): T; /** * Get the user resolver function. * * @returns The user resolver function. */ getUserResolver(): () => unknown; /** * Set the user resolver function. * * @param resolver - The user resolver function. * @returns The current instance for method chaining. */ setUserResolver(resolver: () => unknown): this; /** * Get the route resolver function. * * @returns The route resolver function. */ getRouteResolver(): () => IRoute | undefined; /** * Set the route resolver function. * * @param resolver - The route resolver function. * @returns The current instance for method chaining. */ setRouteResolver(resolver: () => RouteType): this; /** * Return the current route or a route parameter. * * @returns The route parameter or the route object. */ getRoute(): RouteType | undefined; /** * Generate a unique fingerprint for the event. * * @param full - Whether to include the user agent and IP address in the fingerprint. * @returns The generated fingerprint as a base64 string. */ fingerprint(full?: boolean): string; /** * Retrieve a parameter from the route if it exists. * * @param name - The name of the parameter to retrieve. * @returns The value of the parameter if it exists, otherwise undefined. */ getParam(name: string): TReturn | undefined; /** * Retrieve a parameter from the route if it exists. * * @param name - The name of the parameter to retrieve. * @param fallback - The fallback value if the parameter does not exist. * @returns The value of the parameter if it exists, otherwise undefined. */ getParam(name: string, fallback: TReturn): TReturn; /** * Retrieve a value from the request body. * * @param key - The key of the value to retrieve. * @returns The value from the body if it exists, otherwise undefined. */ private getFromBody; /** * Retrieve a value from the query parameters. * * @param key - The key of the value to retrieve. * @returns The value from the query parameters if it exists, otherwise undefined. */ private getFromQueryParams; /** * Validate the provided name. * * @param name - The name to validate. * @returns True if the name is valid, otherwise false. */ private isValidName; }