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

koa-semver

v1.0.2

Published

Semantic Versioning middleware for Koa

Downloads

4

Readme

koa-semver

npm NPM Downloads Node.js Version Build Status styled with prettier

Match middleware with Semantic Versioning.

Built with npm/node-semver to match familiar npm style dependency syntax and usage, but for middleware and routes.

Requisites:

Installation

npm install --save koa-semver

# with yarn:
yarn add koa-semver

Usage

koa-semver allows multiple usage options, but it is strongly recommended to use with koa-router.

Basic Versioning

A sample Koa server would be:

"use strict";

const Koa = require("koa");
const Router = require("koa-router");
const Semver = require("koa-semver");

const app = new Koa();
const router = new Router();

// Add handlers by priority
// (Descending order)
const ver = new Semver([
  Semver.handlers.header("X-Semver"),
  Semver.handlers.param(":version"),
  Semver.handlers.query("version"),
]);

// Newer middleware or routes should be placed on top
// (Descending order)
router.get("/:version/users", ver.match("~2.10.0", ctx => {
  ctx.body = { // Latest
    users: {
      administrators: [],
      clients: [],
    },
  };
}));

router.get("/:version/users", ver.match("^1.2.0", ctx => {
  ctx.body = { // Legacy
    users: []
  };
}));

app.use(router.routes());

app.listen(3000);

Client side usage:

# Latest version
$ curl http://localhost:3000/_/users
$ curl -H "X-Semver: 2.10.1" http://localhost:3000/_/users
{
    "users": {
        "administrators": [],
        "clients": []
    }
}

# Latest version (headers has more priority than route param)
$ curl -H "X-Semver: 2.10.1" http://localhost:3000/1.2.5/users
{
    "users": {
        "administrators": [],
        "clients": []
    }
}
# Specific version
$ curl http://localhost:3000/1.3.0/users
$ curl http://localhost:3000/_/users?version=1.4.0
{
    "users": []
}
# Unknown version
$ curl http://localhost:3000/3.0.0/users
$ curl http://localhost:3000/0.1.0/users
Not Found

Semver state variable

It is possible to know about the requested and matching versions:

router.get("/:version/users", ver.match("^1.2.0", ctx => {
  ctx.body = ctx.state.semver;
}));

Create a matcher

Sometimes we want to reuse the matching version, so we can:

const ver = new Semver();
ver.use(Semver.handlers.header("X-Semver"));

const matcher = ver.matcher("^1.0.0");

const router = new Router();
router.get("/users", matcher(async ctx => {
  // ...
}));
router.post("/users/:id/comments", matcher(async ctx => {
  // ...
}));

Another way is:

const app = new Koa();

const ver = new Semver();
ver.use(Semver.handlers.header("X-Semver"));

const router = new Router();
router.get("/users", async ctx => {
  // ...
});
router.post("/users/:id/comments", async ctx => {
  // ...
});

app.use(ver.match("^1.0.0", router.routes()));

Multiple matching

It is responsibility of the developer to stop the middleware propagation. So it is possible to match multiples routes or add conditional middleware using koa-semver;

const app = new Koa();
const router = new Router();
const ver = new Semver();
ver.use(Semver.handlers.header("X-Semver"));

app.use(ver.match("1.x || >=2.5.0 || 5.0.0 - 7.2.3", (ctx, next) => {
  // Patch some buggy versions
  ctx.state.something = true;
  ctx.body = [];
  return next(); // <- Continue middleware chain
}));

router.get("/endpoint", ver.match("^1.2.0", async (ctx, next) => {
  ctx.body.append("Hello!");
  await next(); // <- Continue middleware chain
}));

router.get("/endpoint", ver.match("^1.1.0", async ctx => {
  ctx.body.append("World!");
  // We broke the chain
}));

router.get("/endpoint", ver.match("^1.0.1", async ctx => {
  // This would never match
}));

// ...

app.use(router.routes());

In this case a GET request to /endpoint with X-Semver: 1.2.0 will match the first two routes and will return:

["Hello!", "World!"]

Testing

Run Jest test suite with:

yarn test

# With coverage
yarn test -- --coverage

# Watch for changes
yarn test -- --watch