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

@plumier/kernel

v1.0.0-beta.5

Published

Plumier kernel

Downloads

2

Readme

Plumier

Delightful Node.js Rest API Framework powered by Koa and TypeScript

Build Status Build status Coverage Status Greenkeeper badge

Motivation

Plumier primarily created for full stack developer who spend more time working on the UI side and focus on creating a good user experience. Plumier comes with some built-in production-ready features that make creating secure JSON Api fun and easy.

Lightweight

Plumier relatively has small code base which make it light and fast. It uses Koa as its core http handler which is quite fast, below is comparison result of Koa, Plumier and Express.

Benchmarks

The benchmark project forked from Fastify benchmark project, you can test it your self here.

Flexible

Almost every part of framework is fully configurable and easy to override. For example plumier route generation system provided flexibility using convention and also configuration.

Plumier traverse through the controller directories and generate routes based on directory name, controller name, method name and parameter names. This behavior make you easily separate your controllers based on version etc.

// path: controller/api/v1/users-controller.ts
export class UsersController {

    @route.put(":id")
    modify(id:number, data:User){
        //implementation
    }
}

Above class generated into

PUT /api/v1/users/:id
  • api is a directory
  • v1 is a directory
  • user is a controller UsersController
  • :id is method parameter, the method name is ignored

Plumier has a flexible decorator based routing configuration, it makes you easily create clean restful api routes and nested restful api with separate controller.

Check the route cheat sheet for detail information

Testable

Plumier controller is a plain TypeScript class it doesn't need to inherit from any base class, thats make it easily instantiated outside the framework.

Plumier provided powerful parameter binding to bound specific value of request object into method's parameter which eliminate usage of Request stub. Controller returned object or promised object or throw HttpStatusError and translated into http response which eliminate usage of Response mock.

export class AuthController {
    @route.post()
    login(userName:string, password:string){
        const user = await userDb.findByEmail(email)
        if (user && await bcrypt.compare(password, user.password)) {
            return { token: sign({ userId: user.id, role: user.role }, config.jwtSecret) }
        }
        else
            throw new HttpStatusError(403, "Invalid username or password")
    }
}

Controller above uses name binding, userName and password parameter will automatically bound with request body { "userName": "abcd", "password": "12345" } or url encoded form userName=abcd&password=12345.

Testing above controller is as simple as testing plain object:

it("Should return signed token if login successfully", async () => {
    const controller = new AuthController()
    const result = await controller.login("abcd", "12345")
    expect(result).toBe(<signed token>)
})

it("Should reject if provided invalid username or password", async () => {
    const controller = new AuthController()
    expect(controller.login("abcd", "1234578"))
        .rejects.toEqual(new HttpStatusError(403, "Invalid username or password"))
})

Secure

Plumier provided built-in type converter, validator, token based authentication, declarative authorization and parameter authorization which make creating secure JSON API trivial.

@domain()
export class User  {
    constructor(
        @val.email()
        public email: string,
        public displayName: string,
        public birthDate: Date,
        @authorize.role("Admin")
        public role: "Admin" | "User"
    ) { }
}

Above is User domain that will be used as controller parameter type. Its a plain TypeScript class using parameter properties decorated with some validation and parameter authorization.

Plumier aware of TypeScript type annotation and will make sure user provided the correct data type, @val.email() will validate the email, @authorize.role("Admin") will make sure only Admin can set the role field.

export class UsersController {
    private readonly repo = new Repository<User>("User")

    @authorize.role("Admin")
    @route.get("")
    all(offset: number, @val.optional() limit: number = 50) {
        return this.repo.find(offset, limit)
    }

    @authorize.public()
    @route.post("")
    save(data: User) {
        return this.repo.add(data)
    }
}

Above controller will generate routes below

POST /users
GET  /users?offset=0&limit=<optional>

Even if above controller implementation look so naive and vulnerable, but Plumier already done some security check before user input touching database. Get users route only accessible by Admin other user try accessing it will got 401 or 403 status. Save user is public so everyone can register to the service.

Plumier done some data conversion and security check, example below is list of user input and their appropriate status returned.

| User Input | Description | | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | | { "email": "[email protected]", "displayName": "John Doe", "birthDate": "1988-1-1" } | Valid, birthDate converted to Date | | { "birthDate": "1988-1-1" } | Invalid, email and displayName is required | | { "email": "abc", "displayName": "John Doe", "birthDate": "1988-1-1" } | Invalid email | | { "email": "[email protected]", "displayName": "John Doe", "birthDate": "abc" } | Invalid birthDate | | { "email": "[email protected]", "displayName": "John Doe", "birthDate": "1988-1-1", "hack": "lorem ipsum dolor sit amet" } | Valid, hack field removed | | { "email": "[email protected]", "displayName": "John Doe", "birthDate": "1988-1-1", "role" : "Admin" } | Setting role only valid if login user is Admin |

Friendly

Plumier enhanced with static route analysis which will print friendly message if you misconfigure controller or forgot some decorator.

static analysis

Documentation

Go to Plumier documentation for complete documentation and tutorial

Requirements

  • TypeScript
  • NodeJS >= 8.0.0
  • Visual Studio Code

Contributing

To run Plumier project on local machine, some setup/app required

App requirements

  • Visual Studio Code (Recommended)
  • Nodejs 8+
  • Yarn npm install -g yarn

Local Setup

  • Fork and clone the project
  • Install dependencies by yarn install
  • Run test by yarn test

Debugging

Plumier already provided vscode task and launch setting. To start debugging a test scenario:

  • Build the project
  • Locate the test file and narrow the test runs by using .only
  • Put breakpoint on any location you need on .ts file
  • Locate the .js version of the test file that will be run (important)
  • On start/debug configuration select Jest Current File and start debugging
  • Process will halt properly on the .ts file.