UNPKG

@nasriya/hypercloud

Version:

Nasriya HyperCloud is a lightweight Node.js HTTP2 framework.

248 lines (247 loc) 9.93 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.HyperCloudRequest = void 0; const helpers_1 = __importDefault(require("../../../utils/helpers")); const user_1 = __importDefault(require("./user")); const handler_1 = __importDefault(require("../../uploads/assets/handler")); /**This class is used internallly, not by the user */ class HyperCloudRequest { #_request; #_req; #_params = {}; /**The locale of the client. Example: `en-PS`; */ #_locale; #_lang; #_user = Object.seal({ instance: null, initialized: false }); #_colorScheme = 'Light'; constructor(request, req) { this.#_request = request; this.#_req = req; this.#_lang = this.#_request.server.languages.default; this.#_locale = `${this.#_lang}-PS`; /**@type {HyperCloudUserOptions} */ this.#_user.instance = new user_1.default(this); } /**The ID of the HTTP request */ get id() { return this.#_request.id; } /**The IP of the remote client */ get ip() { return this.#_request.ip; } /**The request protocol */ get protocol() { return this.#_request.protocol; } /**The request host */ get host() { return this.#_request.host; } /**The request domain */ get domain() { return this.#_request.domain; } /**The request subdomain */ get subDomain() { return this.#_request.subDomain; } /**The request base URL */ get baseUrl() { return this.#_request.baseUrl; } /**The request path, in other words, the part of the URL after the first `/`. */ get path() { return this.#_request.path; } /**The request query, in other words, the part of the URL after the `?`. */ get query() { return this.#_request.query; } /** * The entire URL of the request. This includes: {@link protocol}, {@link host}, {@link path}, and any potential {@link query}. * * Example: `https://auth.nasriya.net/tfa?token=randomID`. */ get href() { return this.#_request.href; } /**The type of the recieved body. Note that the body is converted to `json` format whenever possible */ get bodyType() { return this.#_request.bodyType; } /**The body of the request */ get body() { return this.#_request.body; } /**The request cookies object */ get cookies() { return this.#_request.cookies; } /**The request headers */ get headers() { return this.#_req.headers; } /**The `request.aborted` property will be `true` if the request has been aborted. */ get aborted() { return this.#_req.aborted; } /**The request authority pseudo header field. Because HTTP/2 allows requests to set either `:authority` or `host`, this value is derived from `req.headers[':authority']` if present. Otherwise, it is derived from `req.headers['host']`. */ get authority() { return this.#_req.authority; } /**Is `true` after `'close'` has been emitted. */ get closed() { return this.#_req.closed; } /**The `request.complete` property will be `true` if the request has been completed, aborted, or destroyed. */ get complete() { return this.#_req.complete; } /** * In case of server request, the HTTP version sent by the client. In the case of client response, the HTTP version of the connected-to server. Returns`'2.0'`. * * Also `message.httpVersionMajor` is the first integer and `message.httpVersionMinor` is the second. */ get httpVersion() { return this.#_req.httpVersion; } get httpVersionMajor() { return this.#_req.httpVersionMajor; } get httpVersionMinor() { return this.#_req.httpVersionMinor; } /**The request method as a string. Read-only. Examples: `'GET'`, `'DELETE'`. */ get method() { return this.#_req.method; } get server() { return this.#_request.server; } /**@private */ _toString() { return JSON.stringify(this._toJSON(), null, 4); } /**@private */ _toJSON() { return { id: this.id, ip: this.ip, protocol: this.protocol, host: this.host, domain: this.domain, subDomain: this.subDomain, baseUrl: this.baseUrl, path: this.path, query: this.query, href: this.href, bodyType: this.bodyType, body: this.body, params: this.params, cookies: this.cookies, locale: this.locale, language: this.language || null, user: this.user._toJSON(), }; } /** * The parameters of that matches the current route. * * Note: Each route will have its own `params` if available */ get params() { return this.#_params; } set params(value) { if (helpers_1.default.is.realObject(value)) { this.#_params = value; } else { throw `The request.params has been set with an invalid value. Expected an object but got ${typeof value}`; } } /**The locale of the client. Example: `en-PS`; */ get locale() { return this.#_locale; } /** * Set the request locale * @param {string} value * @private */ set _locale(value) { if (typeof value === 'string') { if (helpers_1.default.validate.locale(value)) { this.#_locale = value; } else { throw `(${value}) is not a valid locale`; } } else { throw new TypeError(`The request's locale that has been used is not a valid string, but a type of ${typeof value}`); } } /**Get request language */ get language() { return this.#_lang; } /** * Set the request language * @param {string} lang The new language * @private */ set _language(lang) { if (typeof lang === 'string') { lang = lang.toLowerCase(); if (!this.server.languages.supported.includes(lang)) { throw `The language you provided (${lang}) is not a supported language. Supported languages are: ${this.server.languages.supported.join(', ')}.`; } this.#_lang = lang; } else { throw new TypeError(`The request's language that has been used is not a valid string, but a type of ${typeof lang}`); } } /**@returns {HyperCloudUser} */ get user() { return this.#_user.instance; } /** * Setup the user details of this request. * * **Note:** Once set, you cannot change the user details * @param {HyperCloudUserOptions} options */ set user(options) { if (this.#_user.initialized) { throw `Unable to set HyperCloud user: User is already defined`; } this.#_user.initialized = true; this.#_user.instance = new user_1.default(this, options); } /**Get the site's `colorScheme` */ get colorScheme() { return this.#_colorScheme; } /** * Set the `colorScheme` of the request * @param {ColorScheme} scheme The request's `colorScheme` * @private */ set _colorScheme(scheme) { if (['Light', 'Dark'].includes(scheme)) { this.#_colorScheme = scheme; } else { throw `The provided request's "scheme" (${scheme}) is not a valid color scheme`; } } /** * Handles incoming multipart form data for file uploads. * * This method processes multipart form data from the HTTP request to handle file uploads. * It initializes an `UploadHandler` to manage the upload process and handles any errors * that might occur. After processing, the request body will include a `cleanup` function * that can be used to clean up temporary files after they have been processed, such as * moving them to a permanent location or storing their metadata in a database. * * **Example Usage:** * * ```ts * router.post('/api/v1/uploads', async (request, response, next) => { * try { * // Process the form data and handle the files * await request.processFormData(response); * * // Extract fields, files, and the cleanup function from the request body * const { fields, files, cleanup } = request.body as FormDataBody; * * // Process the files and fields (e.g., store files, update database) * // ............................ * * // Clean up temporary files after processing * await cleanup(); * * // Return a response or proceed to the next middleware/handler * next(); * } catch(error) { * response.status(500).json(error); * } * }); * ``` * * @param {HyperCloudResponse} response - The response object used to send responses back to the client. * * @returns {Promise<void>} A promise that resolves when the form data has been processed. * The cleanup function is included in the request body and should be called after processing the files. * * @throws {Error} If an error occurs during form data processing, the response will send a 500 status * with an error message, and the error will be re-thrown. */ processFormData(response) { const handler = new handler_1.default(this, this.#_request, response); try { return handler.handle(); } catch (error) { response.status(500).json({ type: 'server_error', error }); throw error; } } /**The original HTTP request */ get httpRequest() { return this.#_req; } } exports.HyperCloudRequest = HyperCloudRequest; exports.default = HyperCloudRequest;