npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@yamato-daiwa/express-extensions

v1.2.2

Published

Additional functionality for Express.js and also "routing-controllers" aimed to reduce the routine code.

Readme

Yamato Daiwa Express Extensions

Additional functions for express and its plugins, and also for routing-controllers.

Installation

npm i @yamato-daiwa/express-extensions -E

Also, install the following peer dependencies if not installed yet.

  • body-parser: ~2.2.0
  • express: ~5.1.0
  • express-session: ~1.19.0
  • routing-controllers: ~0.11.0

Functionality

ExpressMiddleware

The abstract class intended to be extended for the creating of Express middleware and using with @UseBefore and @UseAfter decorators. Unlike MiddlewareInterface and @Middleware() decorator of routing-controllers, has safely typed parameters.

classDiagram
  class ExpressMiddleware {
    <<abstract>>
    #handleRequest(request: Express.Request, response: Express.Response, toNextMiddleware: ToNextMiddlewareTransfer) Promise<void>
  }

The only method need to be implemented is handleRequest:

(
  request: Express.Request,
  response: Express.Response,
  toNextMiddleware: ExpressMiddleware.ToNextMiddlewareTransfer
): Promise<void>

Example

import type Express from "express";
import { ExpressMiddleware } from "@yamato-daiwa/express-extensions";
import { Logger } from "@yamato-daiwa/es-extensions";


export default class DebuggerMiddleware extends ExpressMiddleware {

  protected override async handleRequest(
    request: Express.Request,
    response: Express.Response,
    toNextMiddleware: ExpressMiddleware.ToNextMiddlewareTransfer
  ): Promise<void> {

    Logger.logInfo({
      title: "DebuggerMiddleware",
      description: "",
      additionalData: {
        request,
        response
      }
    });

    toNextMiddleware();
    return Promise.resolve();

  }

}

initializeRoutingControllersExpressHTTPS_Application

Initializer of the application using routing-controllers, Express and HTTPS protocol.

(
  {
    configuration: {
      HTTPS,
      routingControllers
    },
    eventsHandlers: {
      onExpressApplicationCreated,
      onHTTPS_ServerCreated,
      onRoutingControllersSetupComplete,
      onApplicationStarted
    }
  }: Readonly<{

    configuration: Readonly<{
      
      HTTPS: Readonly<
        { port: number; } &
        (
          (
            { SSL_Key: string; } |
            { SSL_KeyFilePath__absoluteOrRelative: string; }
          ) &
          (
            { SSL_Certificate: string; } |
            { SSL_CertificateFilePath__absoluteOrRelative: string; }
          ) 
        )
      >;
      routingControllers: RoutingControllersOptions;
    }>;

    eventsHandlers: Readonly<{
      onExpressApplicationCreated: (expressApplication: ExpressApplication) => Promise<void>;
      onHTTPS_ServerCreated?: (HTTPS_Server: NodeHTTPS.Server, expressApplication: ExpressApplication) => Promise<void>;
      onRoutingControllersSetupComplete?: () => Promise<void>;
      onApplicationStarted?: () => Promise<void>;
    }>;

  }>
): Promise<void>

Background

The initialization of routing-controllers + Express + HTTPS application has not been documented well and a little bit complicated:

import Express, { type Express as ExpressApplication } from "express";
import createExpressApplication from "express";
import { useExpressServer as supportClassSyntax } from "routing-controllers";

import HTTPS from "https";
import FileSystem from "fs";


const expressApplication: ExpressApplication = createExpressApplication();

expressApplication.get(
  "/",
  (_request: Express.Request, response: Express.Response): void => {
    response.send("<h1>Hello, world!</h1>");
  }
);

const HTTPS_Server: HTTPS.Server = HTTPS.createServer(
  {
    key: FileSystem.readFileSync("./SSL/key.pem"),
    cert: FileSystem.readFileSync("./SSL/cert.pem")
  },
  expressApplication
);

supportClassSyntax(expressApplication);

HTTPS_Server.listen(443, "127.0.0.1");

initializeRoutingControllersExpressHTTPS_Application encapsulates this complexity.

Configuration

HTTPS - The HTTPS Requirements
routingControllers - The "routing-controllers" configuration

Options of routing-controllers. See the TypeScript type definitions of RoutingControllersOptions type for reference.

Events Handers

onExpressApplicationCreated
(expressApplication: ExpressApplication) => Promise<void>

As it obviously from the function name, called when basic Express application created. Basically being used to use the Express plugins and middlewares.

  • routing-controllers library has not been involved yet.
  • The express application instance will be passed via parameter.
onHTTPS_ServerCreated
(HTTPS_Server: NodeHTTPS.Server, expressApplication: ExpressApplication) => Promise<void>

As it obviously from the function name, called when the HTTPS server created.

  • routing-controllers library has not been involved yet.
  • The HTTPS server instance, and also the express application instance will be passed via parameters.
onRoutingControllersSetupComplete
(expressApplication: ExpressApplication) => Promise<void>;

As it obviously from the function name, called when the routing-controllers functionality has been initialized.

onRoutingControllersSetupComplete
() => Promise<void>

As it obviously from the function name, called when the application actually started and ready to accept the HTTP requests. Usually being called to log the application starting.

redirectOnNotFound

redirectOnNotFound(targetRoute: string): (_request: Express.Request, response: Express.Response) => void

Redirects to specified route when response.headersSent value is false. Intended to be used via expressApplicationUse() after the initialization of routing-controllers application complete to redirect to "Not found" page.

Although with the plain Express the "Not found" page is being provided by other way, with routing-controllers the usual ways may not work because of incorrectly arranged routes. There is no official recommendation how to redirect to "Not found" page when no route matchings found so redirectOnNotFound function may be used for such purposes.

Route

The adapter for Method decorator from routing-controllers to HTTP_Methods enumeration from "fundamental-constants"/"@yamato-daiwa/es-extensions".

QueryParametersProcessor

@QueryParametersProcessor.process is the alternative @QueryParams from routing-controllers. In comparison with @QueryParams,

  • Has customizable deserialization (does not use pre-deserialized request.query)
  • Validation without additional classes via RawObjectDataProcessor API;
  • Possible to modify object to which query string has been deserialized as far as RawObjectDataProcessor supports.
import { Controller, Get, Reader } from "routing-controllers";
import { QueryParametersProcessor } from "@yamato-daiwa/express-extensions";
import { RawObjectDataProcessor } from "@yamato-daiwa/es-extensions";


@Controller()
export default class UserController {

  @Get("/componets/users/edtior/new")
  @Reader("Components/UserEditor/ForNewUser/EditorForNewUser.mvc.component.hbs")
  protected async renderUserEditorFragmentForNewUser(
    @QueryParametersProcessor.process({
      userType: {
        type: String,
        required: true,
        allowedAlternatives: Object.values(User.Types)
      },
      willBeFirstAmongOnesOfSameType: {
        preValidationModifications: [ destringifyBooleanValue ],
        type: Boolean,
        required: true
      },
      currentContOfUsersOfSameType: {
        preValidationModifications: [ convertPotentialStringToIntegerIfPossible ],
        type: Number,
        numbersSet: RawObjectDataProcessor.NumbersSets.naturalNumber,
        required: true
      }
    })
    {
      userType,
      willBeFirstAmongOnesOfSameType,
      currentContOfUsersOfSameType
    }: Readonly<{
      
    }>
  ): Promise<EditorForNewUserMVC_FragmentVariables> {
    
    console.log(userType)
    console.log(willBeFirstAmongOnesOfSameType)
    console.log(currentContOfUsersOfSameType)
  
    // ...
    
  }

}

Query parameters deserializing

To set the default deserializer, use setDefaultDeserializer static method of QueryParametersProcessor.

import { QueryParametersProcessor } from "@yamato-daiwa/express-extensions"; 
import QueryString from "qs";


QueryParametersProcessor.setDefaultDeserializer(QueryString.parse)

The parameter must be the functions accepts the serialized (thus the string) query parameters and return JSON-compatible type.

Obvious but frequently missed out: the deserializing algorithm on backend must correspond to serializing algorithm on frontend. Well, the QueryString.parse() is predefined deserializer for QueryParametersProcessor but even you are fine with this one, add above code to your application to explicitly show that you selected this serializer consciously.

Additionally, you can set the custom deserializer per request what is basically not recommended but inevitably if development of the client part is out your control.

import { Controller, Get, Reader } from "routing-controllers";
import { QueryParametersProcessor } from "@yamato-daiwa/express-extensions";
import { RawObjectDataProcessor, type ReadonlyParsedJSON_Object } from "@yamato-daiwa/es-extensions";


@Controller()
export default class UserController {

  @Get("/componets/users/edtior/new")
  @Reader("Components/UserEditor/ForNewUser/EditorForNewUser.mvc.component.hbs")
  protected async renderUserEditorFragmentForNewUser(
    @QueryParametersProcessor.process(
      {
        userType: {
          type: String,
          required: true,
          allowedAlternatives: Object.values(User.Types)
        },
        // ...
      },
      (queryString: string): ReadonlyParsedJSON_Object => {
        // ....
      }
    )
    {
      userType,
      willBeFirstAmongOnesOfSameType,
      currentContOfUsersOfSameType
    }: Readonly<{
      
    }>
  ): Promise<EditorForNewUserMVC_FragmentVariables> {
    
    console.log(userType)
    console.log(willBeFirstAmongOnesOfSameType)
    console.log(currentContOfUsersOfSameType)
  
    // ...
    
  }

}

QueryParametersDeserializingError

If error will occur during query parameters deserializing, the QueryParametersProcessor.QueryParametersDeserializingError will be thrown. You can detect it via error instanceof QueryParametersProcessor.QueryParametersDeserializingError or error instanceof HttpError because QueryParametersProcessor.QueryParametersDeserializingError extended from HttpError of routing-controllers.

Session

saveExpressSession

saveExpressSession(session: Session): Promise<void>

The promisfied version of session.save(callback). The promise will reject if the callback of session.save will receive neither undefined nor null parameter.

disposeExpressSession

# === [ Overload 1 ] Must wait until completion
(session: Session, options: Readonly<{ mustWaitUntilCompletion: true; }>): Promise<void>;

# === [ Overload 2 ] Do not wait until completion
(session: Session, options: Readonly<{ mustWaitUntilCompletion: false; }>): void;

The wrapper for session.destroy(callback).

  • If the second parameter has been set to { mustWaitUntilCompletion: true }, this function will return the promise which will be resolved when the disposal will successfully complete. In this case, the disposeExpressSession is the promisfied version of session.destroy(callback).
  • If there is no need to wait the ending of disposal, set the second parameter to { mustWaitUntilCompletion: false } and this function will return nothing.

Request Body

parseAndValidateJSON_RequestBody

<RequestData extends ReadonlyParsedJSON>(
  settings: Readonly<{
    requestBodySizeLimit__bytesPackageFormat: string | number;
    validationAndProcessing: RawObjectDataProcessor.ObjectDataSpecification;
    mustLogDataAfterParsing?: boolean;
  }>
): ExpressMiddleware

Parses expected to be the JSON-type request body, validates it by RawObjectDataProcessor and, if demanded, modifying it by same util. The alternative to class-transformer which is transforming the request body to the instances of classes for the cases when there is no need to turn the objects to the instances of the classes.

  • Requirements
    1. body-parser has not been applied neither globally nor locally, by other words, the request body has not been parsed yet.
    2. The class-transformer is disabled by useExpressServer({ classTransformer: false }) where the useExpressServer is the function from routing-controllers
  • Intended to be used as one of parameters of routing-controllers middleware.

validateAndProcessJSON_RequestBody

<RequestData extends ReadonlyParsedJSON>(
  validationAndProcessing: RawObjectDataProcessor.ObjectDataSpecification,
  { mustLogDataAfterParsing = false }: Readonly<{ mustLogDataAfterParsing?: boolean; }> = { mustLogDataAfterParsing: false }
): ExpressMiddleware

Validates the pre-parsed JSON body by RawObjectDataProcessor and, if demanded, modifying it by same util. The alternative to class-transformer which is transforming the request body to the instances of classes for the cases when there is no need to turn the objects to the instances of the classes.

  • Requirements
    1. The JSON-type request body has been preliminary parsed by body-parser.
    2. The class-transformer is disabled by useExpressServer({ classTransformer: false }) where the useExpressServer is the function from routing-controllers
  • Intended to be used as one of parameters of routing-controllers middleware.