@nasriya/hypercloud
Version:
Nasriya HyperCloud is a lightweight Node.js HTTP2 framework.
894 lines (893 loc) • 39.5 kB
TypeScript
import http2 from 'http2';
import http from 'http';
import SSLManager from '../services/ssl/manager';
import HyperCloudRequest from '../services/handler/assets/request';
import HyperCloudResponse from '../services/handler/assets/response';
import HyperCloudServer from '../server';
import HTTPError from '../utils/errors/HTTPError';
import ms from 'ms';
/**The website's possible color schemes */
export type ColorScheme = 'Dark' | 'Light';
export type UserRole = 'Admin' | 'Member' | 'Visitor';
export type RedirectCode = 300 | 301 | 302 | 303 | 304 | 307 | 308;
/** View engine type */
export type ViewEngine = 'ejs' | 'nhc';
/**A `request` object for handlers */
export type Request = InstanceType<typeof HyperCloudRequest>;
/**A `response` object for handlers */
export type Response = InstanceType<typeof HyperCloudResponse>;
/** Handler for HyperCloud requests */
export type HyperCloudRequestHandler = (request: Request, response: Response, next: NextFunction) => void;
/** Handler for handling HyperCloud requests' errors */
export type HyperCloudRequestErrorHandler = (request: Request, response: Response, next: NextFunction, error: Error | HTTPError) => void;
/**HyperCloud's `next()` function */
export type NextFunction = () => void;
/**Represents various HTTP request methods. */
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS' | 'TRACE' | 'CONNECT';
/**Represents the type of the request body. */
export type RequestBodyType = 'text' | 'javascript' | 'json' | 'formData' | 'buffer' | 'graphql' | 'hls';
export type HyperCloudServerHandlers = 'notFound' | 'serverError' | 'unauthorized' | 'forbidden' | 'userSessions' | 'logger' | 'onHTTPError';
export type HttpEquivType = 'content-security-policy' | 'content-type' | 'default-style' | 'x-ua-compatible' | 'refresh';
export type HTMLMetaName = 'application-name' | 'author' | 'description' | 'generator' | 'keywords' | 'referrer' | 'theme-color' | 'color-scheme' | 'viewport' | 'creator' | 'googlebot' | 'publisher' | 'robots' | (string & {});
export type PageRenderingCacheAsset = Exclude<RenderingCacheAsset, "json">;
/**`DeepReadonly` means that the object or array is completely frozen */
export type DeepReadonly<T> = {
readonly [P in keyof T]: DeepReadonly<T[P]>;
};
/**A currency code */
export type Currency = 'AED' | 'AFN' | 'ALL' | 'AMD' | 'ANG' | 'AOA' | 'ARS' | 'AUD' | 'AWG' | 'AZN' | 'BAM' | 'BBD' | 'BDT' | 'BGN' | 'BHD' | 'BIF' | 'BMD' | 'BND' | 'BOB' | 'BRL' | 'BSD' | 'BTN' | 'BWP' | 'BYN' | 'BZD' | 'CAD' | 'CDF' | 'CHF' | 'CLP' | 'CNY' | 'COP' | 'CRC' | 'CUP' | 'CVE' | 'CZK' | 'DJF' | 'DKK' | 'DOP' | 'DZD' | 'EGP' | 'ERN' | 'ETB' | 'EUR' | 'FJD' | 'FKP' | 'FOK' | 'GBP' | 'GEL' | 'GGP' | 'GHS' | 'GIP' | 'GMD' | 'GNF' | 'GTQ' | 'GYD' | 'HKD' | 'HNL' | 'HRK' | 'HTG' | 'HUF' | 'IDR' | 'ILS' | 'IMP' | 'INR' | 'IQD' | 'IRR' | 'ISK' | 'JEP' | 'JMD' | 'JOD' | 'JPY' | 'KES' | 'KGS' | 'KHR' | 'KID' | 'KMF' | 'KRW' | 'KWD' | 'KYD' | 'KZT' | 'LAK' | 'LBP' | 'LKR' | 'LRD' | 'LSL' | 'LYD' | 'MAD' | 'MDL' | 'MGA' | 'MKD' | 'MMK' | 'MNT' | 'MOP' | 'MRU' | 'MUR' | 'MVR' | 'MWK' | 'MXN' | 'MYR' | 'MZN' | 'NAD' | 'NGN' | 'NIO' | 'NOK' | 'NPR' | 'NZD' | 'OMR' | 'PAB' | 'PEN' | 'PGK' | 'PHP' | 'PKR' | 'PLN' | 'PYG' | 'QAR' | 'RON' | 'RSD' | 'RUB' | 'RWF' | 'SAR' | 'SBD' | 'SCR' | 'SDG' | 'SEK' | 'SGD' | 'SHP' | 'SLL' | 'SOS' | 'SPL' | 'SRD' | 'STN' | 'SYP' | 'SZL' | 'THB' | 'TJS' | 'TMT' | 'TND' | 'TOP' | 'TRY' | 'TTD' | 'TVD' | 'TWD' | 'TZS' | 'UAH' | 'UGX' | 'USD' | 'UYU' | 'UZS' | 'VES' | 'VND' | 'VUV' | 'WST' | 'XAF' | 'XCD' | 'XOF' | 'XPF' | 'YER' | 'ZAR' | 'ZMW' | 'ZWD';
/**These mime types are used when sending/receiving files */
export type MimeType = "audio/aac" | "application/x-abiword" | "application/x-freearc" | "image/avif" | "video/x-msvideo" | "application/vnd.amazon.ebook" | "application/octet-stream" | "image/bmp" | "application/x-bzip" | "application/x-bzip2" | "application/x-cdf" | "application/x-csh" | "text/calendar" | "text/css" | "text/plain" | "text/csv" | "application/msword" | "application/vnd.openxmlformats-officedocument.wordprocessingml.document" | "application/vnd.ms-fontobject" | "application/epub+zip" | "application/gzip" | "image/gif" | "text/html" | "image/vnd.microsoft.icon" | "text/calendar" | "application/java-archive" | "image/jpeg" | "text/javascript" | "application/json" | "application/ld+json" | "audio/midi" | "audio/x-midi" | "audio/mpeg" | "video/mp4" | "video/mpeg" | "application/vnd.apple.installer+xml" | "application/vnd.oasis.opendocument.presentation" | "application/vnd.oasis.opendocument.spreadsheet" | "application/vnd.oasis.opendocument.text" | "audio/ogg" | "video/ogg" | "application/ogg" | "audio/opus" | "font/otf" | "image/png" | "application/pdf" | "application/x-httpd-php" | "application/vnd.ms-powerpoint" | "application/vnd.openxmlformats-officedocument.presentationml.presentation" | "application/vnd.rar" | "application/rtf" | "application/x-sh" | "image/svg+xml" | "application/x-tar" | "image/tiff";
export type OnRenderHandler = (locals: Record<string, any> | any, include: (name: string, locals: Record<string, any>) => Promise<string>, lang: string) => string | Promise<string>;
export type StorageUnitName = 'Bit' | 'Byte' | 'Kilobyte' | 'Kibibyte' | 'Megabyte' | 'Mebibyte' | 'Gigabyte' | 'Gibibyte' | 'Terabyte' | 'Tebibyte' | 'Petabyte' | 'Pebibyte' | 'Exabyte' | 'Exbibyte' | 'Zettabyte' | 'Zebibyte' | 'Yottabyte' | 'Yobibyte' | 'Brontobyte' | 'Geopbyte' | 'Nibble' | 'Word';
export type StorageUnitAbbreviation = 'b' | 'B' | 'KB' | 'KiB' | 'MB' | 'MiB' | 'GB' | 'GiB' | 'TB' | 'TiB' | 'PB' | 'PiB' | 'EB' | 'EiB' | 'ZB' | 'ZiB' | 'YB' | 'YiB' | 'BB' | 'GPB';
export type StorageUnit = StorageUnitName | StorageUnitAbbreviation;
export type UploadCleanUpFunction = () => Promise<void>;
export interface UploadLimitsController {
fileStream: {
get: () => number;
set: (limit: number) => void;
};
images: {
get: () => number;
set: (limit: number) => void;
};
videos: {
get: () => number;
set: (limit: number) => void;
};
mime: {
get: (mime: MimeType) => number | undefined;
set: (mime: MimeType, limit: number) => void;
};
}
export interface StorageSize {
/**A positive value */
value: number;
/**The storage unit */
unit: StorageUnit;
}
/**
* Represents the body of a form data request after parsing.
* This interface includes metadata about the fields and files from the form data,
* as well as a cleanup function for managing temporary files.
*/
export interface FormDataBody {
/**
* A record of form fields, where the keys are field names and the values are the field data.
* This includes all non-file fields submitted in the form.
*
* @type {Record<string, any>}
* @example
* {
* "username": "john_doe",
* "age": 30
* }
*/
fields: Record<string, any>;
/**
* An array of file objects representing the uploaded files.
* Each file object can either be a `FormDataMemoryFile` or `FormDataStorageFile`,
* depending on whether the file was stored in memory or on disk.
*
* @type {(FormDataMemoryFile | FormDataStorageFile)[]}
* @example
* [
* {
* fieldName: "profile_picture",
* fileName: "john.jpg",
* mime: "image/jpeg",
* size: 123456,
* content: <Buffer 89 50 4e ...> // For FormDataMemoryFile
* },
* {
* fieldName: "large_file",
* fileName: "document.pdf",
* mime: "application/pdf",
* size: 98765432,
* path: "/temp/uploads/document.pdf" // For FormDataStorageFile
* }
* ]
*/
files: (FormDataMemoryFile | FormDataStorageFile)[];
/**
* A function that cleans up temporary files created during the file upload process.
* This function should be called to remove any temporary files after processing is complete,
* such as after copying files to their final location or storing their metadata in a database.
*
* @type {UploadCleanUpFunction}
* @example
* // Call this function to clean up temporary files
* formDataBody.cleanup();
*/
cleanup: UploadCleanUpFunction;
}
/**Represents a file in form data. */
export interface FormDataFile {
/**
* The name of the form field associated with the file.
* @example 'profilePicture'
*/
fieldName: string;
/**
* The name of the uploaded file.
* @example 'profile.jpg'
*/
fileName: string;
/**
* The MIME type of the file.
* @example 'image/jpeg'
*/
mime: MimeType;
/**
* The size of the file in bytes.
* @example 204800
*/
size: number;
}
/**
* Represents a small file stored in memory.
* Inherits from {@link FormDataFile}.
*/
export interface FormDataMemoryFile extends FormDataFile {
/**
* The binary data of the file.
* This property is used for small-sized files that are stored entirely in memory.
* @example <Buffer 89 50 4e ...>
*/
content: Buffer;
}
/**
* Represents a large file stored in temporary storage.
* Inherits from {@link FormDataFile}.
*/
export interface FormDataStorageFile extends FormDataFile {
/**
* The path to the temporary file on disk.
* This property is used for large files that are stored in temporary storage.
* @example '/tmp/uploads/largefile.tmp'
*/
path?: string;
}
export interface HTMLScriptTag {
/**
* Specifies that the script is downloaded in parallel to
* parsing the page, and executed as soon as it is
* available (before parsing completes) (only for
* external scripts)
*/
async?: boolean;
/**Sets the mode of the request to an HTTP CORS Request */
crossorigin?: 'anonymous' | 'use-credentials';
/**
* Specifies that the script is downloaded in parallel to
* parsing the page, and executed after the page has
* finished parsing (only for external scripts)
*/
defer?: boolean;
/**
* Allows a browser to check the fetched script to ensure
* that the code is never loaded if the source has been
* manipulated
*/
integrity?: string;
/**
* Specifies that the script should not be executed in
* browsers supporting ES2015 modules
*/
nomodule?: boolean;
/**
* Specifies which referrer information to send when fetching a script
*/
referrerpolicy?: ReferrerPolicyOption;
/**Specifies the URL of an external script file */
src: string;
/**Specifies the media type of the script */
type?: 'text/javascript' | 'application/ecmascript' | 'text/babel' | 'application/ld+json' | 'module';
}
export interface InternalScriptOptions extends Omit<InternalScriptRecord, 'scope' | 'fileName'> {
}
export interface InternalScriptRecord extends Omit<HTMLScriptTag, 'src' | 'integrity'>, FileAsset {
scope: 'Internal';
/**The path to the script file */
filePath: string;
fileName: string;
}
export interface ExternalScriptOptions extends Omit<ExternalScriptRecord, 'scope'> {
}
export interface ExternalScriptRecord extends HTMLScriptTag {
scope: 'External';
}
export interface OnPageScriptOptions extends Omit<OnPageScriptRecord, 'scope'> {
}
export interface OnPageScriptRecord extends Pick<HTMLScriptTag, 'nomodule'> {
scope: 'OnPage';
/**The JavaScript code for in-place scripts (no imports). */
content?: string;
}
export type MetaTag = {
name: string;
content: string;
};
export interface FileAsset {
/**The cached content of the file */
content?: string;
/**The absolute path to the path involved */
filePath: string;
eTag?: string;
}
export type ViewRenderingAsset = Required<Omit<FileAsset, 'eTag'>>;
export interface RenderingAsset {
name: string;
view: ViewRenderingAsset;
css?: FileAsset;
js?: FileAsset;
locals: Record<string, FileAsset>;
}
export type RenderingCacheAsset = 'css' | 'js' | 'json';
export interface PageConstructorOpts extends RenderingAsset {
}
export interface InternalStylesheetRecord extends FileAsset {
scope: 'Internal';
fileName: string;
/**The content of the CSS file */
content?: string;
}
export interface ExternalStylesheetRecord {
scope: 'External';
/**The URL of the external CSS file */
url: URL;
}
export interface ComponentConstructorOpts extends RenderingAsset {
}
export interface RateLimitAuthOptions {
/**The value to check against the rules. */
value: string | number;
/**An array of rule names and their priorities. */
rules: ({
priority?: number;
name: string;
})[];
/**When set to `true`, all rules must pass; otherwise, at least one must pass. Default: `false` */
strict?: boolean;
/**The rule scope. Default: `global` */
scope?: 'global' | string;
}
export interface RateLimitRule {
/**A scope where the record will be searched for. Default: `global` */
scope: 'global' | string;
/**The name of the rule. E.g. `ipAddress`, `premiumSubscribers`. */
name: string;
/**The time (in nilleseconds) to wait before allowing requests again */
cooldown: number;
rate: {
/**The period in milliseconds */
windowMs: number;
/**The number of allowed requests in the specified `period` */
maxRequests: number;
};
}
export interface RateLimitRuleOptions {
/**A scope where the record will be searched for. Default: `global` */
scope?: 'global' | string;
/**The name this rule will be based on. E.g. `ipAddress`, `premiumSubscribers`. */
name: string;
/**The time (in nilleseconds) to wait before allowing requests again */
cooldown: number;
rate: {
/**The period in milliseconds */
windowMs: number;
/**The number of allowed requests in the specified `period` */
maxRequests: number;
};
}
export interface RateLimiterAuthorizedHit {
authorized: true;
/**The number of hits in the the */
hits: number;
hitsRemaining: number;
lastHitTimestamp: number;
}
export interface RateLimiterUnauthorizedHit {
authorized: false;
/**A timestamp after which the requests may be accepted */
retryAfter: number;
}
/** Main Helmet handler's options */
export interface HelmetConfigOptions {
/** Content-Security-Policy options */
contentSecurityPolicy?: ContentSecurityPolicyOptions | false;
/** Cross-Origin-Embedder-Policy options */
crossOriginEmbedderPolicy?: CrossOriginEmbedderPolicyOptions | false;
/** Cross-Origin-Opener-Policy options */
crossOriginOpenerPolicy?: CrossOriginOpenerPolicyOptions | false;
/** Cross-Origin-Resource-Policy options */
crossOriginResourcePolicy?: CrossOriginResourcePolicyOptions | false;
/** Origin-Agent-Cluster options */
originAgentCluster?: '?1' | false;
/** Referrer-Policy options */
referrerPolicy?: ReferrerPolicyOptions | false;
/** Strict-Transport-Security options */
strictTransportSecurity?: StrictTransportSecurityOptions | false;
/** X-Content-Type-Options options */
xContentTypeOptions?: 'nosniff' | false;
/** X-DNS-Prefetch-Control options */
xDnsPrefetchControl?: DNSPrefetchControlOptions | false;
/** X-Download-Options options */
xDownloadOptions?: boolean;
/** X-Frame-Options options */
xFrameOptions?: XFrameOptionsOptions | false;
/** X-Permitted-Cross-Domain-Policies options */
xPermittedCrossDomainPolicies?: XPermittedCrossDomainPoliciesOptions | false;
/** X-Powered-By options */
xPoweredBy?: false;
/** X-XSS-Protection options */
xXssProtection?: false;
}
/** Enum for X-Permitted-Cross-Domain-Policies options */
export declare enum XPermittedCrossDomainPoliciesOption {
NONE = "none",
MASTERONLY = "master-only",
BYCONTENTTYPE = "by-content-type",
ALL = "all"
}
/** Options for X-Permitted-Cross-Domain-Policies */
export interface XPermittedCrossDomainPoliciesOptions {
/** The permitted policy value */
permittedPolicies: XPermittedCrossDomainPoliciesOption;
}
/** Enum for X-Frame-Options options */
export declare enum XFrameOptionsOption {
DENY = "DENY",
SAMEORIGIN = "SAMEORIGIN",
ALLOWFROM = "ALLOW-FROM"
}
/** Options for X-Frame-Options */
export interface XFrameOptionsOptions {
/** The action to be taken */
action: XFrameOptionsOption;
/** Optional URI for ALLOW-FROM action */
uri?: string;
}
/** Options for DNS Prefetch Control */
export interface DNSPrefetchControlOptions {
/** Whether DNS prefetching is enabled */
enabled: boolean;
}
/** Options for Strict Transport Security */
export interface StrictTransportSecurityOptions {
/** Max age value in seconds */
maxAge?: number;
/** Whether to include subdomains */
includeSubDomains?: boolean;
/** Whether to preload HSTS */
preload?: boolean;
}
/** Type for Referrer Policy options */
export type ReferrerPolicyOption = "no-referrer" | "no-referrer-when-downgrade" | "same-origin" | "origin" | "strict-origin" | "origin-when-cross-origin" | "strict-origin-when-cross-origin" | "unsafe-url" | (string & {});
/** Options for Referrer Policy */
export interface ReferrerPolicyOptions {
/** The referrer policy value */
policy: ReferrerPolicyOption;
}
/** Type for Cross-Origin Resource Policy options */
export type CrossOriginResourcePolicyOption = "same-origin" | "same-site" | "cross-origin" | string;
/** Options for Cross-Origin Resource Policy */
export interface CrossOriginResourcePolicyOptions {
/** The policy value */
policy: CrossOriginResourcePolicyOption;
}
/** Type for Cross-Origin Opener Policy options */
export type CrossOriginOpenerPolicyOption = "same-origin" | "same-origin-allow-popups" | "unsafe-none" | string;
/** Options for Cross-Origin Opener Policy */
export interface CrossOriginOpenerPolicyOptions {
/** The policy value */
policy: CrossOriginOpenerPolicyOption;
}
/** Possible values for most Content Security Policy directives */
export type ContentSecurityPolicyDirectiveValue = "'self'" | "'unsafe-inline'" | "'unsafe-eval'" | "'none'" | 'data:' | 'blob:' | 'mediastream:' | 'filesystem:' | 'https:' | 'http:' | string;
export interface ContentSecurityPolicyDirectives {
[directive: string]: string[] | boolean | undefined | any;
/** Fallback for other directives. Usually set to 'self' to restrict to the same origin. */
defaultSrc?: ContentSecurityPolicyDirectiveValue[];
/** Specifies valid sources for JavaScript. */
scriptSrc?: ContentSecurityPolicyDirectiveValue[];
/** Specifies valid sources for CSS. */
styleSrc?: ContentSecurityPolicyDirectiveValue[];
/** Specifies valid sources for images. */
imgSrc?: ContentSecurityPolicyDirectiveValue[];
/** Specifies valid sources for fetch(), XMLHttpRequest, WebSocket, and EventSource connections. */
connectSrc?: ContentSecurityPolicyDirectiveValue[];
/** Specifies valid sources for fonts loaded using @font-face. */
fontSrc?: ContentSecurityPolicyDirectiveValue[];
/** Specifies valid sources for the <object>, <embed>, and <applet> elements. */
objectSrc?: ContentSecurityPolicyDirectiveValue[];
/** Specifies valid sources for loading media using the <audio> and <video> elements. */
mediaSrc?: ContentSecurityPolicyDirectiveValue[];
/** Specifies valid sources for nested browsing contexts loading using elements such as <frame> and <iframe>. */
frameSrc?: ContentSecurityPolicyDirectiveValue[];
/** Enables a sandbox for the requested resource, blocking certain actions like form submission, script execution, etc. */
sandbox?: ('allow-forms' | 'allow-modals' | 'allow-orientation-lock' | 'allow-pointer-lock' | 'allow-popups' | 'allow-popups-to-escape-sandbox' | 'allow-presentation' | 'allow-same-origin' | 'allow-scripts' | 'allow-top-navigation' | 'allow-top-navigation-by-user-activation')[];
/** Specifies a URI to which reports about policy violations should be sent. */
reportUri?: string[];
/** Specifies valid sources for web workers and nested browsing contexts loaded using elements such as <iframe> and <frame>. */
childSrc?: ContentSecurityPolicyDirectiveValue[];
/** Specifies valid endpoints for submitting forms. */
formAction?: ContentSecurityPolicyDirectiveValue[];
/** Specifies valid parents that may embed a page using <frame>, <iframe>, <object>, <embed>, or <applet>. */
frameAncestors?: ContentSecurityPolicyDirectiveValue[];
/** Specifies valid MIME types for plugins invoked by elements such as <object> and <embed>. */
pluginTypes?: string[];
/** Specifies valid sources for the <base> element. */
baseUri?: ContentSecurityPolicyDirectiveValue[];
/** Blocks all mixed content, preventing HTTP content from being loaded on HTTPS sites. */
blockAllMixedContent?: boolean;
/** Requires that all requests be sent over HTTPS. */
upgradeInsecureRequests?: boolean;
/** Specifies valid sources for web workers and shared workers. */
workerSrc?: ContentSecurityPolicyDirectiveValue[];
/** Specifies valid sources for the manifest. */
manifestSrc?: ContentSecurityPolicyDirectiveValue[];
/** Specifies valid sources to be prefetched or prerendered. */
prefetchSrc?: ContentSecurityPolicyDirectiveValue[];
/** Specifies valid sources for navigation. */
navigateTo?: ContentSecurityPolicyDirectiveValue[];
/** Specifies a reporting endpoint where the browser will send reports of CSP violations. */
reportTo?: string[];
/** Requires Trusted Types for specified script sources. */
requireTrustedTypesFor?: ('script')[];
/** Defines a policy for Trusted Types. */
trustedTypes?: {
/** The name of the Trusted Types policy. */
policyName: string;
/** Allows duplicate policy definitions. Default: `false` */
allowDuplicates?: boolean;
};
}
export type CrossOriginEmbedderPolicyOption = 'none' | 'require-corp' | 'unsafe-none' | "credentialless" | string;
export interface CrossOriginEmbedderPolicyOptions {
policy?: CrossOriginEmbedderPolicyOption;
}
export interface ContentSecurityPolicyOptions {
/** Whether to use default directives or not. Default: `false` */
useDefaults?: boolean;
directives: ContentSecurityPolicyDirectives;
}
export interface ExtensionData {
/**The actual extension. e.g. (.png, .mp4) */
extension: string;
description: string;
/**The mime type */
mime: string;
}
/**Options for the `500` server error page */
export interface ServerErrorOptions {
locals?: {
title?: string;
subtitle?: string;
message?: string;
};
error?: Error | Record<string, any>;
/**
* Do **NOT** use this property
* @private
*/
bypassHandler?: boolean;
}
/**User preferences is an object on the HyperCloud request. */
export interface UserPreferencesOptions {
language?: string;
locale?: string;
currency?: Currency;
colorScheme?: ColorScheme;
}
/**The `user` object on the HyperCloud request. */
export interface HyperCloudUserOptions {
loggedIn?: boolean;
role?: UserRole;
id?: string;
preferences?: UserPreferencesOptions;
}
/**Options for the `401` and `403` error pages */
export interface ForbiddenAndUnauthorizedOptions {
locals?: {
title?: string;
commands?: {
code?: string;
description?: string;
cause?: string;
allowed?: string;
regards?: string;
};
content?: {
code?: string;
description?: string;
cause?: string;
allowed?: {
label: string;
link: string;
}[];
};
};
}
/**Options for the default `404` error page */
export interface NotFoundResponseOptions {
locals?: {
title?: string;
subtitle?: string;
homeBtnLabel?: string;
};
}
export interface StaticRouteOptions {
/** The route path URL. */
path: string;
/** Option for serving dotfiles. Possible values are `allow`, `deny`, `ignore`. Default: `ignore`. */
dotfiles?: 'allow' | 'ignore' | 'deny';
/** The host's `subDomain` from HyperCloudRequest.subDomain. Default: `null`. */
subDomain?: string;
/** This will match only if the `path` exactly matches the HyperCloudRequest.path */
caseSensitive?: boolean;
/** Whether to cache the file in memory. Default: `true` */
memoryCache?: boolean;
}
export interface CookieOptions {
/** Indicates that the cookie should only be sent over HTTPS connections */
secure?: boolean;
/** Prevents client-side JavaScript from accessing the cookie */
httpOnly?: boolean;
/** Specifies the maximum age of the cookie in seconds. For example: `3600` (for one hour). If left empty, the cookie will only be valid until the browser session ends. */
maxAge?: number;
/** Specifies the domain for which the cookie is valid. For example: `example.com`. */
domain?: string;
/** Specifies the URL path for which the cookie is valid. For example: `/`. */
path?: string;
/** Specifies the date and time when the cookie will expire. For example: `Sat, 25 Feb 2023 12:00:00 GMT`. */
expires?: Date;
/** Controls whether the cookie should be sent with cross-site requests. */
sameSite?: 'Strict' | 'Lax' | 'None';
/** Specifies the priority of the cookie. */
priority?: 'High' | 'Medium' | 'Low';
}
export interface RouteOptions {
/** The route path URL. */
path: string;
/** The handler of this route */
handler: HyperCloudRequestHandler;
/** The request method */
method: 'USE' | HttpMethod;
/** The host's `subDomain` from HyperCloudRequest.subDomain. Default: `null`. */
subDomain?: string;
/** This will match only if the `path` exactly matches the HyperCloudRequest.path */
caseSensitive?: boolean;
}
export interface PageRenderingOptions {
title?: string;
description?: string;
keywords?: string | string[];
favicon?: string;
thumbnail?: string;
/** Local variables to be used */
locals?: Record<string, any>;
httpOptions?: RenderingOptions;
}
export interface RenderingOptions {
/** A status code to send */
statusCode?: number;
/** Enable or disable setting `Cache-Control` response header. Default: `true`. */
cacheControl?: boolean;
/** Sets the max-age property of the Cache-Control header in milliseconds or a string in [ms format](https://www.npmjs.com/package/ms). Default: `0`. */
maxAge?: number | ms.StringValue;
/** Enable or disable the `immutable` directive in the `Cache-Control` response header. If enabled, the `maxAge` option should also be specified to enable caching. The immutable directive will prevent supported clients from making conditional requests during the life of the `maxAge` option to check if the file has changed. */
immutable?: boolean;
/** Set an eTag on the page to let others know when the value changes */
eTag?: string;
}
export interface DownloadFileOptions {
/** Sets the max-age property of the Cache-Control header in milliseconds or a string in [ms format](https://www.npmjs.com/package/ms). Default: `0`. */
maxAge?: number | ms.StringValue;
/** Root directory for relative filenames. You can also use the this path to prevent using files outside of this directory. By default, it uses the project root from `process.cwd()`. */
root?: string;
/** Sets the Last-Modified header to the last modified date of the file on the OS. Set `false` to disable it. */
lastModified?: boolean;
/** Object containing HTTP headers to serve with the file. */
headers?: http2.OutgoingHttpHeaders;
/** Option for serving dotfiles. Possible values are `allow`, `deny`, `ignore`. Default: `ignore`. */
dotfiles?: 'allow' | 'ignore' | 'deny';
/** Enable or disable accepting ranged requests. Default: `true`. */
acceptRanges?: boolean;
/** Enable or disable setting `Cache-Control` response header. Default: `true`. */
cacheControl?: boolean;
/** Enable or disable the `immutable` directive in the `Cache-Control` response header. If enabled, the `maxAge` option should also be specified to enable caching. The immutable directive will prevent supported clients from making conditional requests during the life of the `maxAge` option to check if the file has changed. */
immutable?: boolean;
/** Provide a path for a custom `404` page to be displayed for ignored `dotFiles`. */
notFoundFile?: string;
/** Provide a path for a custom `401` page to be displayed for ignored `dotFiles`. */
unauthorizedFile?: string;
/** Provide a `500` server error page to be displayed instead of throwing an `Error`. */
serverErrorFile?: string;
/**eTags ae useful for caching */
eTag?: string;
/**A filename to send as the name of the downloaded filename */
fileName?: string;
}
export interface SendFileOptions extends DownloadFileOptions {
/** Set this to `true` if you want to download the file */
download?: boolean;
/**A filename to send as the name of the downloaded filename. */
fileName?: string;
}
/**Represents various HTTP request methods. */
export interface HttpMethods {
/** Represents the HTTP GET method. */
GET: string;
/** Represents the HTTP POST method. */
POST: string;
/** Represents the HTTP PUT method. */
PUT: string;
/** Represents the HTTP DELETE method. */
DELETE: string;
/** Represents the HTTP PATCH method. */
PATCH: string;
/** Represents the HTTP HEAD method. */
HEAD: string;
/** Represents the HTTP OPTIONS method. */
OPTIONS: string;
/** Represents the HTTP TRACE method. */
TRACE: string;
/** Represents the HTTP CONNECT method. */
CONNECT: string;
}
/**Represents an initialized request in HyperCloud. */
export interface InitializedRequest {
/** A unique request ID */
id: string;
/** The IPv4 address of the client making the request. Example: `172.15.47.118`. */
ip: string;
/** The protocol this request is sent over. */
protocol: 'http' | 'https';
/** The full domain of a request. E.g.: `nasriya.net` or `auth.nasriya.net`. */
host: string;
/** The subdomain of the `host`. Example URL: `https://auth.nasriya.net` => `subDomain = 'auth'`. */
subDomain?: string;
/** The `host`'s domain. Example: `https://auth.nasriya.net` => `domain = nasriya.net` */
domain: string;
/** The base URL of the host. It consists of the `protocol` and the `protocol`. Example: `https://nasriya.net`. */
baseUrl: string;
/** The path of the URL, for example, a URL of `/support/faq` corresponds to `['support', 'faq']`. */
path: string[];
/** The query parameters of the URL. Example: `/products/search?sku=random&lessThan=20` produces `{sku: 'random', lessThan: '20'}`. */
query: Record<string, string>;
/** The full URL, including the `protocol`, `baseUrl`, `path`, and `query`. Example: `https://nasriya.net/support?ticket=randomTicketID&lang=en`. */
href: string;
/** The type of the received data */
bodyType: RequestBodyType | undefined;
/** The received data */
body: string | Record<string, any> | Buffer | undefined;
/** The request cookies */
cookies: Record<string, string>;
/** The parameters of dynamic requests */
params: Record<string, string>;
/** A reference to the original server */
server: HyperCloudServer;
}
/**Options for configuring protocols (HTTP and HTTPS). */
export interface ProtocolsOptions {
http: {
/** The port for HTTP. */
port: number;
/** Optional callback function for HTTP. */
callback?: () => void;
};
https: {
/** The port for HTTPS. */
port: number;
/** Optional callback function for HTTPS. */
callback?: () => void;
};
}
export interface LetsEncryptOptions {
/** The maintainer email address. This must be consistent. */
email: string;
/** The domain(s) you want to add. At least one. */
domains: string[];
/** Enable to request a valid testing SSL certificate from Let's Encrypt. Default: `false` */
staging?: boolean;
/** Bind the issued certificate to this name. Default: Uses the `name` in the `package.json` of the project. */
certName?: string;
/**A port number to be used for achm challenges. Default: `80` */
challengePort?: number;
}
/**Options for configuring SSL. */
export interface SSLOptions {
/**The type of SSL configurations. Default: `selfSigned` */
type?: 'selfSigned' | 'letsEncrypt' | 'credentials';
letsEncrypt?: LetsEncryptOptions;
/**SSL credentials consisting of a certificate and a private key. */
credentials?: SSLCredentials;
/** The path you choose to store the SSL certificate and private key. (if you wish to) */
storePath?: string;
}
/**SSL credentials consisting of a certificate and a private key. */
export interface SSLCredentials {
/** The certificate to be used. */
cert: string;
/** The private key to be used. */
key: string;
}
/**HyperCloud configurations. */
export interface HyperCloudConfigs {
/** The protocols you want your server to run on. */
protocols: Protocols;
/** The SSL configurations. */
ssl: SSLOptions | SSLCredentials;
/** A property determined by whether the server was configured on HTTPS or not. */
secure: boolean;
/** Set to true if you want to generate staging certificates from Let's Encrypt to avoid being banned. */
staging: boolean;
/** Determine whether you want to add extra error details to the console. */
verbose: boolean;
/** Whether the server has been initialized. */
initialized: boolean;
}
/** Define the HTTP and HTTPS protocols. */
export interface Protocols {
/** Define the HTTP protocol. */
http?: Protocol;
/** Define the HTTPS protocol. */
https?: Protocol;
}
/** Define a protocol configuration. */
export interface Protocol {
/** Specify the port number of the protocol. */
port: number;
/** Pass a callback function to run when the server starts listening. */
callback?: () => void;
}
/** Define a protocol configuration. */
export interface OptionalProtocol {
/** Specify the port number of the protocol. Default: `443` for secure servers and `80` for plain HTTP ones */
port?: number;
/** Pass a callback function to run when the server starts listening. */
callback?: () => void;
}
/** Represents the HyperCloud system components. */
export interface HyperCloudSystem {
/** The HTTPS server instance. */
httpsServer: http2.Http2SecureServer;
/** The HTTP server instance. */
httpServer: http.Server;
/** The SSL manager. */
SSL: SSLManager;
}
/** Initialize this server with a configuration file */
export interface HyperCloudInitFile {
/** A JSON configuration file to initialize the server */
path: string;
}
/** If your server is running behind a reverse proxy, add its IP address to get the true IP address of the client. */
export interface ProxyOptions {
/** Set the IP address of your reverse proxy(ies) */
trusted_proxies?: string[];
/** Set this to true if your proxy is running in a docker container. */
isDockerContainer?: boolean;
/** Set this to true if the proxy is running on your machine. */
isLocal?: boolean;
}
export interface ServerOptions {
/** If your server is running behind a reverse proxy, add its IP address to get the true IP address of the client. */
proxy?: ProxyOptions;
/**Configure your server's default and supported languages */
languages?: {
/**Set your server's default language. Default: `en` */
default?: string;
/**Set your server's supported languages. Default: `['en']` */
supported?: string[];
};
/**
* The `server.locals` object has properties that are local
* variables within the application, and will be available
* in templates rendered with `{@link HyperCloudResponse.render}`.
*/
locals?: Record<string, string>;
/**Define handlers for various scenarios */
handlers?: Record<HyperCloudServerHandlers, HyperCloudRequestHandler>;
}
export interface SecureServerOptions extends ServerOptions {
/**Set to `true` to use `https`. Default: `false`, which means `http`. */
secure: true;
/** Configure the SSL certificate. If not options were provided, a self signed certificate will be used */
ssl?: SSLOptions;
}
export interface ServerPlusSecureOptions extends ServerOptions, SecureServerOptions {
}
/** Options for managing HyperCloud */
export interface HyperCloudManagementOptions {
/** Turn this on if you want to save your configurations. */
saveConfig?: boolean;
/** An absolute path to the folder where you want to save the configurations. */
configPath?: string;
}
/** Options for configuring routers in HyperCloud */
export interface HyperCloudRouterOptions {
/** Specify the subdomain this router works on. Default: '*' */
subdomains?: '*' | string;
/** When enabled, '/auth' is treated the same as '/Auth'. Default: false */
caseSensitive?: boolean;
}
export interface RandomOptions {
/** Include numbers. Default: `true` */
includeNumbers?: boolean;
/** Include letters. Default: `true` */
includeLetters?: boolean;
/** Include symbols: ``!";#$%&'()*+,-./:;<=>?@[]^_`{|}~``. Default: `true` */
includeSymbols?: boolean;
/** Include lowercase characters. Default: `true` */
includeLowerCaseChars?: boolean;
/** Include uppercase characters. Default: `true` */
includeUpperCaseChars?: boolean;
/** Don't begin with a number or symbol. Default: `true` */
beginWithLetter?: boolean;
/** Don't use characters like i, l, 1, L, o, 0, O, etc. Default: `true` */
noSimilarChars?: boolean;
/** Don't use the same character more than once. Default: `false` */
noDuplicateChars?: boolean;
/** Don't use sequential characters, e.g. `abc`, `789`. Default: `true` */
noSequentialChars?: boolean;
}
export interface ServerListeningConfigs {
/**
* The port your server is listening on.
* Default: `443` for secure servers and `80` for non-secure servers
*/
port?: number;
/**
* The host your server is listening on.
*
* Default: `0.0.0.0`, which means listen on all possible interfaces.
*/
host?: string;
/**
* The maximum length of the queue of pending connections.
* Default: the system's default value, usually 511.
*/
backlog?: number;
/**
* If true, the port will be exclusive, and no other process can use it.
*/
exclusive?: boolean;
/**
* If true, only IPv6 addresses will be allowed to connect.
*/
ipv6Only?: boolean;
/**
* The callback function that will be called when the server is listening
* on the specified port and host.
* @example
* server.listen({
* onListen(host, port) => {
* console.log(`Listening on ${host}:${port}`);
* }
* });
*/
onListen?: (host: string, port: number) => void;
}