UNPKG

exstack

Version:

A utility library designed to simplify and enhance express.js applications.

187 lines (186 loc) 6.38 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const require_errors = require("./errors-CWrfln6s.cjs"); let express = require("express"); //#region src/helps/api-res.ts /** ApiRes class for standardizing API responses. */ var ApiRes = class ApiRes { result; status; message; constructor(result = null, status = require_errors.HttpStatus.OK, message = "Operation successful") { this.result = result; this.status = status; this.message = message; } /** * Returns the Body (JSON) representation of the response. * @returns The Body (JSON) representation of the response * * @example * new ApiRes('Hello World', 200).body; */ get body() { return { status: this.status, message: this.message, result: this.result }; } /** Set message (chainable) */ msg = (message) => { this.message = message; return this; }; /** Set result/data (chainable) */ data = (result) => { this.result = result; return this; }; /** * Send the json of HTTP response. * @param {Response} res - The Express response object. * * @example * new ApiRes('Hello World', 200).toJson(res); */ toJson = (res) => { res?.status(this.status)?.json(this.body); }; /** Clone self with a different status */ static status = (code) => new ApiRes(null, code); /** Creates an OK (200) response. */ static ok = (result, message = "Request processed successfully") => new ApiRes(result, require_errors.HttpStatus.OK, message); /** Creates a Created (201) response. */ static created = (result, message = "Resource created successfully") => new ApiRes(result, require_errors.HttpStatus.CREATED, message); /** Creates a paginated OK (200) response. */ static paginated = (data, meta, message = "Data retrieved successfully") => new ApiRes({ ...meta, data }, require_errors.HttpStatus.OK, message); }; //#endregion //#region src/helps/handler.ts /** * Sends the result from a route handler to the client. * * - If `result` is an {@link ApiRes}, calls its `.toJson(res)` method. * - Otherwise, sends it directly (unless it *is* the response object itself). * * @param result - The value returned by a route handler. * @param res - The Express response object. */ const handleResult = (result, res) => { if (result instanceof ApiRes) result.toJson(res); else if (typeof result === "string") res.type("text/plain").send(result); else if (result && result !== res) res.send(result); }; /** * Wraps a route handler (sync or async) and automatically: * - Invokes the handler with `(req, res, next)` * - Catches synchronous and asynchronous errors * - Passes any returned value into {@link handleResult} * * @param callback - A function that handles a request, returning a value or `Promise`. * @returns An Express-compatible request handler. * * @example * app.get('/ping', handler(async () => ApiRes.ok({ alive: true }).msg('Pong'))); * * @example * app.post('/login', handler(async (req, res) => { * const { username, password } = req.body; * return new ApiRes(200, { user: username }); * })); */ const handler = (callback) => async (req, res, next) => { try { const result = callback(req, res, next); if (result instanceof Promise) result.then((value) => handleResult(value, res)).catch(next); else handleResult(result, res); } catch (error) { next(error); } }; //#endregion //#region src/middle/x-powered.ts /** * Middleware to customize or override the `X-Powered-By` HTTP header. * Often used for branding or hiding technology stack. * * @param name - Value to be set for the `X-Powered-By` header */ const poweredBy = (name) => (_, res, next) => { res.setHeader("x-powered-by", name); next(); }; //#endregion //#region src/middle/error-handler.ts /** * Express middleware to handle `HttpError` and unknown errors. * * - Sends JSON response for `HttpError` instances. * - Logs unknown errors and sends generic error response. * - Includes detailed error info in development (`isDev`). * * @param {Boolean} [isDev = true] - Flag to indicate if the environment is development. * @param {(error: unknown) => void} [logger = console.error] - Function to log errors. * @returns {ErrorRequestHandler} - Middleware for handling errors. * * @example * // Basic usage with default options: * app.use(errorHandler(process.env.NODE_ENV !== 'production')); * // Custom usage with a logging function in production mode: * app.use(errorHandler(conf.isDev, logger.error)); */ const errorHandler = (isDev = true, logger = console.error) => (err, _req, res, _next) => { if (require_errors.HttpError.isHttpError(err)) { if (err.options.cause) logger?.(err.options.cause); return err.toJson(res); } logger?.(err); const unknown = { status: require_errors.HttpStatus.INTERNAL_SERVER_ERROR, error: "InternalServerError", message: isDev ? err.message || "Unexpected error" : "Something went wrong", stack: isDev ? err.stack : void 0 }; res.status(unknown.status).json(unknown); }; /** * Middleware to handle 404 Not Found errors. * * This function creates an Express router that catches all requests to * undefined routes and returns a JSON response with a 404 error. * * @param {string} [path='*'] - The route pattern to match (default: '*'). * @returns {Router} Express router instance handling 404 errors. * * @example * app.use(notFound("*")) // v4 * app.use(notFound("*splat")) // v5 */ const notFound = (path) => (0, express.Router)().all(path, (req, res) => new require_errors.HttpError(require_errors.HttpStatus.NOT_FOUND, { message: "Wrong Path", code: "NOT_FOUND", meta: { path: req.path, method: req.method } }).toJson(res)); //#endregion exports.ApiRes = ApiRes; exports.BadRequestError = require_errors.BadRequestError; exports.ConflictError = require_errors.ConflictError; exports.ContentTooLargeError = require_errors.ContentTooLargeError; exports.ForbiddenError = require_errors.ForbiddenError; exports.HttpError = require_errors.HttpError; exports.HttpStatus = require_errors.HttpStatus; exports.InternalServerError = require_errors.InternalServerError; exports.NotFoundError = require_errors.NotFoundError; exports.UnAuthorizedError = require_errors.UnAuthorizedError; exports.createHttpErrorClass = require_errors.createHttpErrorClass; exports.errorHandler = errorHandler; exports.handleResult = handleResult; exports.handler = handler; exports.notFound = notFound; exports.poweredBy = poweredBy;