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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@tsrt/application

v0.8.0

Published

Common Express Application

Downloads

6

Readme

Typescript Reusable Tools: Application

npm version GitHub license Size Downloads

Basic configurable Application built on top of awesome Express framework.

All necessary/common middlewares and configs are setted by default under the hood w/ ability to rewrite/disable/enable them using settings.

Important

Until version 1.0.0 Api should be considered as unstable and may be changed.

So prefer using exact version instead of version with ~ or ^.

Usage

import { Application } from '@tsrt/application';

new Application({ port: 3001 }).start();

This will create Express App and listen 3001 port.

Under the hood it will register global error handler, not found page handler, reponse interseptor (to add metadata for each response).

Use cases

For session it uses express-session.

The most basic use case:

const API = '/api/v1';

new Application({
  port: 3001,
  logger: new Logger(), // or just logger: console,
  apiBase: API,
  webApps: path.join(__dirname, '../client'),
  session: {
    session: {
      name: 'name',
      secret: 'secret',
      expiration: 86400000,
      cookie: { domain: 'example.com' },
    },
    store: { url: 'redis_url', password: 'redis_password' },
  },
  middlewares: { [API]: [someMiddleware, someMiddleware2], '/test': someMiddleware3 }, // Or .addMiddlewares(...)
  mount: { [API]: [`${__dirname}/api/controllers/**/*.ts`], [API_v2]: someRouter }, // Or .addRouters(...)
}).start();

Routes, middlewares, session also couldbe provided via config. Along with others:


const middleware = (req, res, next) => { console.log('Hi'); next(); };
const middleware2 = (req, res, next) => { console.log('Hi 2'); next(); };

const router = Router();
const router2 = Router();
const router3 = Router();

router
  .post('/', (req, res) => { ... })
  .get('/:id?', (req, res) => { ... })
  .put('/:id', (req, res) => { ... })
  .delete('/:id', (req, res) => { ... })

router2
  .post('/', (req, res) => { ... })
  .get('/:id?', (req, res) => { ... })
  .put('/:id', (req, res) => { ... })
  .delete('/:id', (req, res) => { ... })

new Application({ port: 3001 })
  .addSession(expressSessionConfig)
  .addMiddlewares({
    '/': middleware, // Provide middleware for route.
    '/only': [middleware, middleware2], //  ... or list of middlewares.
  })
  .addRoutes({ 
    '/only': router3, // Provide router for route.
    '/rest/api': [router, router2], //  ... or list of routers.
    '/test': 'path/to/controllers/**/*.ts' // ... or glob to get routers
  })
  .start();

Advice

As known when throwing exeption in Express route, if handler is an async function that exeption would not be correctly passed to next route, so it is necessary to make it expicitly:

import { Router } from 'express';

// Incorrect
Router().get('/incorrect', async (req, res) => {
  throw new Error('Error'); // This will cause an unhandled exception.
  // Note, that it will work correctly, if handler is not an `async`.
  res.send('Error');
});

// Note, same example will work correctly, if handler is not an `async`.
Router().get('/incorrect', (req, res) => {
  throw new Error('Error');
  res.send('Error');
});

// Correct
Router().get('/correct', async (req, res) => {
  next(throw new Error('Error'));
  res.send('Error');
});

In order to have ability to throw exceptions without calling next, or if some another method threw an exception, we can patch Express w/ help of express-async-errors.

import express from 'express';
require('express-async-errors'); // Should be used before any express usage.

// ... later in router
import { Router } from 'express';

// Incorrect
Router().get('/incorrect', async (req, res) => {
  throw new Error('Error'); // Now this will correctly path error to ErrorRequestHandler.
  res.send('Error');
});

API reference

export declare class Application<T extends IApplication = IApplication> {
  constructor(settings?: IApplicationSettings<T>, app?: T);

  /** Current Express Application. */
  app: T;

  /** Application settings. */
  settings: IApplicationSettings<T>;

  /** Add aditional routers (mount) imperatively (also could be done declaratively via settings). */
  addRoutes(mount: ApplicationMountList): Application;

  /** Add aditional middlewares imperatively (also could be done declaratively via settings). */
  addMiddlewares(middlewares: ApplicationMiddlewareList): Application;

  /** Set session middleware imperatively (also could be done declaratively via settings) or just as regular middleware. */
  addSession(sessionConfig: IApplicationSession): Application;

  /** Reassign default sendResponseHandler (also could be done declaratively via settings). */
  setSendResponseHandler(handler: RequestHandler): Application;

  /** Reassign default notFoundHandler (also could be done declaratively via settings). */
  setNotFoundHandler(handler: RequestHandler): Application;

  /** Reassign default globalErrorHandler (also could be done declaratively via settings). */
  setGlobalErrorHandler(handler: ErrorRequestHandler): Application;

  /** Start Application. */
  start(cb?: Callback): void;

  /** Here it is possible to call every setup methods in necessary order. */
  manualSetup(settings?: IApplicationManualSetupSettings): IApplicationManualSetup;
}

Options

export type IApplication = ExpressApplication;

export interface IApplicationSettings<T extends IApplication = IApplication> {
  /** Existing Express App. It will be used instead of creating new App by default. */
  app?: T;

  /** Custom application logger. It should implement at least 2 methods: `info` and `error`. */
  logger?: IApplicationLogger;

  /** Port to listen. */
  port?: number | string;

  /** Base api path/pathes. This one is necessary for registering default notFound, globalError and other middlewares. */
  apiBase?: ApplicationPaths;

  /** List of statics dirs, or object w/ key - route path, and value - statics dir. */
  statics?: ApplicationStatics;

  /** Same as for static, but also for serving webApps. */
  webApps?: ApplicationWebApps;

  /** Cors options. @see https://www.npmjs.com/package/cors */
  cors?: CorsOptions;

  /** Query parser options. @see https://www.npmjs.com/package/qs */
  qs?: IParseOptions;

  /** Helmep options @see https://www.npmjs.com/package/helmet */
  helmet?: IHelmetConfiguration;

  /**
   *  Default routers mount options. Key - value (Express Router instance) pairs.
   *  Key (path) - String value for router path.
   *  Value - Router instance or glob pattern from where to import.
   */
  mount?: ApplicationMountList;

  /** Register default middlewares here. */
  middlewares?: ApplicationMiddlewareList;

  /** Session options. @see https://www.npmjs.com/package/express-session */
  session?: IApplicationSession;

  /** Whether to use default controllers. They will be mounted under apiBase path(s). 2 controllers - server info and health check. */
  useDefaultControllers?: boolean;

  /** Middleware to be used instead of default `notFoundHandler` */
  notFoundHandler?: RequestHandler;

  /** Middleware to be used instead of default `sendResponseHandler` */
  sendResponseHandler?: RequestHandler;

  /** Middleware to be used instead of default `globalErrorHandler` */
  globalErrorHandler?: ErrorRequestHandler;
}

export interface IApplicationManualSetup {
  /** Proxy to native Express App `use` method */
  use: ApplicationRequestHandler<IApplicationManualSetup>;

  /** Proxy to native Express App `set` method */
  set(setting: string, value: any): this;

  /** Setups all middlewares and settings (which are used under this method) at once. */
  setupAll(): IApplicationManualSetup;

  /** Sets query parser for App. */
  setupQueryParser(cb?: (str: string) => any): IApplicationManualSetup;

  /** Sets default middlewares: cors, helmet, bodyparser, ... etc */
  setupDefaultExpressMiddlewares(): IApplicationManualSetup;

  /** Sets handler for attaching request id for each request. */
  setupRequestIdMiddleware(): IApplicationManualSetup;

  /** Sets session middleware. */
  setupSession(sessionConfig?: IApplicationSession): IApplicationManualSetup;

  /** Sets send response pathcer middleware (pathces `send` function before sending response). */
  setupSendResponseHandler(paths?: TypeOrArrayOfTypes<string | RegExp>): IApplicationManualSetup;

  /** Sets statics. */
  setupStatics(statics?: ApplicationStatics): IApplicationManualSetup;

  /** Sets custom middlewares provide via `options` or via `addMiddlewares` method. */
  setupMiddlewares(middlewares?: ApplicationMiddlewareList): IApplicationManualSetup;

  /** Sets custom controllers (routes) provide via `options` or via `addRoutes` method. */
  setupRouter(mount: ApplicationMountList): IApplicationManualSetup;

  /** Sets notFoundHandler. */
  setupNotFoundHandler(): IApplicationManualSetup;

  /** Sets webApps statics and serving. */
  setupWebApps(webApps?: ApplicationWebApps): IApplicationManualSetup;

  /** Sets global request handler. */
  setupGlobalErrorHandler(): IApplicationManualSetup;

  /** Proxy to public Application `start` method */
  start(cb?: Callback): void;
}

export interface IApplicationSession extends ISessionSettings {
  paths?: string | string[];
}

export interface IApplicationManualSetupSettings {
  useMethodsByDefault?: boolean;
}

export type ApplicationMount = string | Router;

export type ApplicationMountList = Record<string, TypeOrArrayOfTypes<ApplicationMount>>;

export type ApplicationMiddlewareList = Record<string, TypeOrArrayOfTypes<RequestHandler>>;

export type ApplicationStatics = string[] | Record<string, string>;

export type ApplicationWebApps = string | Record<string, string>;

export type ApplicationPaths = TypeOrArrayOfTypes<string>;

export type TypeOrArrayOfTypes<T> = T | T[];

export type Callback = (...args: any[]) => void;

License

This project is licensed under the terms of the MIT license.