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 🙏

© 2024 – Pkg Stats / Ryan Hefner

awilix-router-core

v2.0.0

Published

[![npm](https://img.shields.io/npm/v/awilix-router-core.svg?maxAge=1000)](https://www.npmjs.com/package/awilix-router-core) [![dependency Status](https://img.shields.io/david/jeffijoe/awilix-router-core.svg?maxAge=1000)](https://david-dm.org/jeffijoe/awil

Downloads

36,929

Readme

awilix-router-core

npm dependency Status devDependency Status Build Status Coveralls npm npm

This package is intended for use with HTTP libraries that want to configure routes using ESNext decorators or a builder pattern.

Table of Contents

Install

With npm:

npm install awilix-router-core

Or with yarn

yarn add awilix-router-core

Example

The end-user of the routing library will be able to use decorators or a builder pattern to declaratively set up their routes, middleware and methods.

Note: in the examples below, an ES6 default export is used, but named exports and multiple exports per file are supported.

With decorators

// You may re-export these as well.
import { route, before, GET, verbs, HttpVerbs } from 'awilix-router-core'

import bodyParser from 'your-framework-body-parser'
import authenticate from 'your-framework-authentication'

@before(bodyParser())
@route('/news')
export default class NewsController {
  constructor({ service }) {
    this.service = service
  }

  @GET()
  async find(ctx) {
    ctx.body = await this.service.doSomethingAsync()
  }

  @route('/:id')
  @GET()
  async get(ctx) {
    ctx.body = await this.service.getNewsOrWhateverAsync(ctx.params.id)
  }

  @route('(/:id)')
  @verbs([HttpVerbs.POST, HttpVerbs.PUT])
  @before(authenticate())
  async save(ctx) {
    ctx.body = await this.service.saveNews(ctx.params.id, ctx.request.body)
  }
}

With builder pattern

// You may re-export these as well.
import { createController } from 'awilix-router-core'

import bodyParser from 'your-framework-body-parser'
import authenticate from 'your-framework-authentication'

// Can use a factory function or a class.
const api = ({ service }) => ({
  find: async () => (ctx.body = await service.doSomethingAsync()),
  get: async (ctx) =>
    (ctx.body = await service.getNewsOrWhateverAsync(ctx.params.id)),
  save: async (ctx) =>
    (ctx.body = await service.saveNews(ctx.params.id, ctx.request.body)),
})

export default createController(api)
  .before(bodyParser())
  .prefix('/news')
  .get('', 'find') // <- "find" is the method on the result from `api`
  .get('/:id', 'get') // <- "get" is the method on the result from `api`
  .verbs([HttpVerbs.POST, HttpVerbs.PUT], '/:id', 'save', {
    // "save" is the method on the result from `api`
    before: [authenticate()],
  })

For framework adapter authors

The framework adapter will use the tools provided by this package to extract routing config from decorated classes and register it in the router of choice.

Check out the awilix-koa reference implementation, as well as the API docs here.

API

As mentioned earlier, this package exposes the user-facing route declaration API, as well as utilities needed for framework adapter authors.

Route Declaration

There are 2 flavors of route declaration: builder and ESNext decorators.

Builder

The builder API's public top level exports are:

import { createController, HttpVerbs } from 'awilix-router-core'

createController(targetClassOrFunction)

Creates a controller that will invoke methods on an instance of the specified targetClassOrFunction.

The controller exposes the following builder methods:

  • .get|post|put|patch|delete|head|options|connect|all(path, method, opts): shorthands for .verbs([HttpVerbs.POST], ...) - see HttpVerbs for possible values.
  • .verbs(verbs, path, method, opts): registers a path mapping for the specified controller method.
  • .prefix(path): registers a prefix for the controller. Calling this multiple times adds multiple prefix options.
  • .before(middlewares): registers one or more middlewares that runs before any of the routes are processed.
  • .after(middlewares): registers one or more middlewares that runs after the routes are processed.

The optional opts object passed to .verbs can have the following properties:

  • before: one or more middleware that runs before the route handler.
  • after: one or more middleware that runs after the route handler.

Note: all builder methods returns a new builder - this means the builder is immutable! This allows you to have a common builder setup that you can reuse for multiple controllers.

Decorators

If you have enabled decorator support in your transpiler, you can use the decorator API.

The decorator API exports are:

import {
  route,
  before,
  after,
  verbs,
  HttpVerbs,

  // The following are just shortcuts for `verbs([HttpVerbs..])`
  GET,
  HEAD,
  POST,
  PUT,
  DELETE,
  CONNECT,
  OPTIONS,
  PATCH,
  ALL,
} from 'awilix-router-core'

route(path)

Class-level: adds a prefix to all routes in this controller.

Method-level: adds a route for the decorated method in the controller.

Has no effect if no verbs are configured.

Example:

@route('/todos')
class Controller {
  // GET /todos
  // POST /todos
  @GET()
  @POST()
  method1() {}

  // PATCH /todos/:id
  @route('/:id')
  @PATCH()
  method2() {}
}

before(middlewares) and after(middlewares)

Class-level: adds middleware to run before/after the routes are processed.

Method-level: adds middleware to run before/after the decorated method is processed.

Example:

@before([bodyParser()])
class Controller {
  @before([authenticate()])
  @after([compress()])
  method() {}
}

verbs(httpVerbs)

Class-level: not allowed.

Method-level: adds HTTP verbs that the route will match.

Has no effect if no routes are configured.

Example:

@verbs([HttpVerbs.GET, HttpVerbs.POST])
method() {}

Verb shorthands

GET, POST, etc.

Example:

@route('/todos')
class Controller {
  // GET /todos
  // POST /todos
  @GET()
  @POST()
  method1() {}

  // PATCH /todos/:id
  @route('/:id')
  @PATCH()
  method2() {}
}

Extracting route config

This section is for framework adapter authors. Please see awilix-koa for a reference implementation. If you need any help, please feel free to reach out!

The primary functions needed for this are getStateAndTarget, rollUpState, and findControllers.

NOTE: when referring to "state-target tuple", it means an object containing state and target properties, where target is the class/function to build up (using container.build) in order to get an object to call methods on.

import {
  getStateAndTarget,
  rollUpState,
  findControllers,
} from 'awilix-router-core'

getStateAndTarget(functionOrClassOrController)

Given a controller (either from createController or a decorated class), returns a state-target tuple.

rollUpState(state)

This will return a map where the key is the controller method name and the value is the routing config to set up for that method, with root paths + middleware stacks pre-merged.

findControllers(pattern, globOptions)

Using fast-glob, loads controllers from matched files.

Note: This uses require and so currently is not compatible with ESM.

Returns an array of state-target tuples.

Author

Jeff Hansen — @Jeffijoe