@tree-house/core

NodeJS utilities and handy helpers extending ExpressJS functionalities

Usage no npm install needed!

<script type="module">
  import treeHouseCore from 'https://cdn.skypack.dev/@tree-house/core';
</script>

README

Tree House Core

NodeJS utilities and handy helpers extending ExpressJS functionalities

Installation

Install via npm

npm install @tree-house/core

or via yarn

yarn add @tree-house/core

Usage

const treehouse = require('@tree-house/core')
import * as treehouse from '@tree-house/core'

Security

setBasicSecurity(app, route, options)

Set some basic Express security using cors and helmet.

const app = express();

treehouse.setBasicSecurity(app, '*', {
  cors: {},   // cors options
  helmet: {}, // helmet options
})

setBodyParser(app, route, options)

Set a body parser using the body-parser module

const app = express();

treehouse.setBodyParser(app, '*', {
  json: {},   // json options
  raw: {}, // raw options
  text: {}, // text options
  urlEncoded: {}, // urlEncoded options
})

getRateLimiter(options)

Get a rate limiter instance to prevent brute force attacks. This can be used as a middleware in Express. At the moment there is support for a built in-memorystore or Redis. Both use the express-rate-limit module.

const app = express();

// In memory store (development purposes)
const globalRateLimiter = treehouse.getRateLimiter({
  max: 100, // limit each IP to 100 requests per windowMs
  delayMs: 0 // disable delaying - full speed until the max limit is reached
  windowMs: 60 * 60 * 1000, // 1 hour window
  message:
    "Too many accounts created from this IP, please try again after an hour"
});

app.use('/login', globalRateLimiter, ...);

// Using existing Redis client
treehouse.getRateLimiter({
  redis: {
    client: existingClient, // All Redis options or 'client' to use an existing client (see rate-limit-redis)
  },
});

Responder

tryCatchRoute((req, res, next(optional)) => { ... })

Express middleware that wraps and executes a given function with try/catch to avoid unhandled promises within Express.

const app = express();

function getAllUsers(req, res) {
  //  res.send(users) -> return users...
  // or
  // if an unhandled error occurs this will be passed onto the Express error handler instead of raising an UnhandledPromiseRejectionError
}

app.use('/users', treehouse.tryCatchRoute(getAllUsers));

Server

startServer(app, options)

Start an http or https server using an express instance

const app = express();

treehouse.startServer(app, {
  port: 3000,
  title: 'My app',
  pre: preFn,       // function to execute before starting server (optional)
  post: postFn,     // function to execute after starting server (optional) - will contain the http server as first argument
  https: {          // optional
    port: 3001,
    privateKey: 'assets/ssl.key',
    certificate: 'assets/ssl.cert',
  },
  healthCheck: {    // Adds graceful shutdown and Kubernetes readiness / liveness checks for any HTTP applications. (optional) 
    enabled: true,
    uri: '/health'  // Defaults to `/healthcheck`
  },
  version: {        // Adds version endpoint to see which version is running (optional)
    enabled: true,
    value: 'v0.1',  // Defaults to process.env.npm_package_version
  },
  catchAll: (_req, res) => res.sendStatus(404), // Catches all unmatched routes (optional)
})

Jest

Custom functionality added on top of built-in jest features.

toMatchObjectInArray

  import { enableCustomMatchers } from '@tree-house/core`;

  describe('Get users', () => {
    enableCustomMatchers();

    it('Should return list of users', async () => {
      const users = await getUsers()
      expect(users).toMatchObjectInArray({
        id: 12,
        name: 'John Doe',
      });
    });
  });

Swagger

This has become deprecated in favor of no-hassle package.

setSwagger(app, route, filePath, options)

Serve Swagger UI via the a provided Swagger yaml file OR folder with valid structure and yaml files.

YAML file implementation

const app = express();

treehouse.setSwagger(app, '/documentation', 'documentation/swagger.yml', {
  host: 'localhost:3000',
  schemes: ['http'],
};

Folder implementation with valid structure

Structure

.
├── validFolderName
|   ├── index.yml # contains basic info + definition models
|   └── routes
|          ├── route1.yml
|          └── randomName.yml
|          ├── ... # more yml files

Example code

const app = express();

treehouse.setSwagger(app, '/documentation', 'documentation/validFolderName', {
  host: 'localhost:3000',
  schemes: ['http'],
  concatenate : true, // The property to enable folder functionality
};

Tests

  • You can run npm run test to run all tests
  • You can run npm run test:coverage to run all tests with coverage report

Bugs

When you find issues, please report them:

Be sure to include all of the output from the npm command that didn't work as expected. The npm-debug.log file is also helpful to provide.

Authors

See the list of contributors who participated in this project.

License

This project is licensed under the ISC License - see the LICENSE.md file for details