UNPKG

@dwp/govuk-casa

Version:

A framework for building GOVUK Collect-And-Submit-Applications

269 lines 9.44 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = require("express"); /** @memberof module:@dwp/govuk-casa */ class MutableRouter { /** @type {Array} */ #stack; /** @type {Router} */ #router; /** @type {boolean} */ #sealed; /** * A wrapping class to make Express routers mutable. You can append, prepend * and remove routes from a MutableRouter before finally "sealing" it and * mounting it on your Express app. * * @class * @param {import("express").RouterOptions} [options] Router options */ constructor(options) { this.#router = (0, express_1.Router)(options); this.#stack = []; this.#sealed = false; } #append(method, path, ...callbacks) { if (this.#sealed) { throw new Error("Cannot alter middleware in a sealed mutable router"); } this.#stack.push({ method, path, args: [path, ...callbacks], }); } #prepend(method, path, ...callbacks) { if (this.#sealed) { throw new Error("Cannot alter middleware in a sealed mutable router"); } this.#stack.splice(0, 0, { method, path, args: [path, ...callbacks], }); } // This will replace the first found route, and remove all other routes on the // given path #replace(method, path, ...callbacks) { if (this.#sealed) { throw new Error("Cannot alter middleware in a sealed mutable router"); } const finder = (command) => `${command.method}|${command.path}` === `${method}|${path}`; const index = this.#stack.findIndex(finder); if (index > -1) { this.#stack.splice(index, 1, { method, path, args: [path, ...callbacks], }); this.#stack = this.#stack.filter((command, idx) => idx <= index || !finder(command)); } } /** * Seals this router to make it immutable. Returns the ExpressJS router. * * @returns {Router} ExpressJS Router */ seal() { if (this.#sealed) { return this.#router; } for (const { method, args } of this.#stack) { // ESLint disabled as `#router` is dev-controlled, and `seal()` is only // run at boot-time before any user interaction /* eslint-disable-next-line security/detect-object-injection */ this.#router[method].call(this.#router, ...args); } this.#sealed = true; return this.#router; } /* ------------------------------------------------------------- prependers */ /** * Prepend middleware function(s) using the `all()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ prependAll(path, ...callbacks) { this.#prepend("all", path, ...callbacks); } /** * Prepend middleware function(s) using the `get()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ prependGet(path, ...callbacks) { this.#prepend("get", path, ...callbacks); } /** * Prepend middleware function(s) using the `post()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ prependPost(path, ...callbacks) { this.#prepend("post", path, ...callbacks); } /** * Prepend middleware function(s) using the `delete()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ prependDelete(path, ...callbacks) { this.#prepend("delete", path, ...callbacks); } /** * Prepend middleware function(s) using the `put()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ prependPut(path, ...callbacks) { this.#prepend("put", path, ...callbacks); } /** * Prepend middleware function(s) using the `use()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ prependUse(path, ...callbacks) { this.#prepend("use", path, ...callbacks); } /* -------------------------------------------------------------- replacers */ /** * Replace middleware function(s) that were mounted using the `all()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ replaceAll(path, ...callbacks) { this.#replace("all", path, ...callbacks); } /** * Replace middleware function(s) that were mounted using the `get()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ replaceGet(path, ...callbacks) { this.#replace("get", path, ...callbacks); } /** * Replace middleware function(s) that were mounted using the `post()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ replacePost(path, ...callbacks) { this.#replace("post", path, ...callbacks); } /** * Replace middleware function(s) that were mounted using the `delete()` * method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ replaceDelete(path, ...callbacks) { this.#replace("delete", path, ...callbacks); } /** * Replace middleware function(s) that were mounted using the `put()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ replacePut(path, ...callbacks) { this.#replace("put", path, ...callbacks); } /** * Replace middleware function(s) that were mounted using the `use()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ replaceUse(path, ...callbacks) { this.#replace("use", path, ...callbacks); } /* ---------------------------------------------- express.Router() wrappers */ /** * Append middleware function(s) using the `all()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ all(path, ...callbacks) { this.#append("all", path, ...callbacks); } /** * Append middleware function(s) using the `get()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ get(path, ...callbacks) { this.#append("get", path, ...callbacks); } /** * Append middleware function(s) using the `post()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ post(path, ...callbacks) { this.#append("post", path, ...callbacks); } /** * Append middleware function(s) using the `delete()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ delete(path, ...callbacks) { this.#append("delete", path, ...callbacks); } /** * Append middleware function(s) using the `put()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ put(path, ...callbacks) { this.#append("put", path, ...callbacks); } /** * Append middleware function(s) using the `use()` method. * * @param {string | Function} path Route path or middleware function * @param {...Function} callbacks Additional middleware functions * @returns {void} */ use(path, ...callbacks) { this.#append("use", path, ...callbacks); } route() { throw new Error("route() method is not supported on MutableRouter. Use verb methods for now."); } } exports.default = MutableRouter; //# sourceMappingURL=MutableRouter.js.map