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

bissle

v4.1.1

Published

Minimalist HALicious pagination reply interface for HapiJS

Downloads

257

Readme

bissle

Minimalist HALicious pagination response toolkit interface for hapi.js

Travis node npm standard npm

  1. Introduction
  2. Installation
  3. Usage
  4. API
  5. Example
  6. Testing
  7. Contribution

Introduction

This hapi.js plugin enables an additional response toolkit interface to paginate a response in a RESTful and HAL compliant manner. So the plugin accordingly splices the initial response; extends it with meta information about the count of entries per page, the total count and the current page; adds a link map for HALicious navigation and appends the corresponding Link header. It is not a middleware-like plugin, so you are allowed to control the usage explicitly by yourself. Because of this, it works perfectly in combination with HAL plugins like halacious, as it is shown in the example below.

The modules standard and ava are used to grant a high quality implementation.

Compatibility

| Major Release | hapi.js version | node version | | --- | --- | --- | | v4 | >=18.4 @hapi/hapi | >=12 | | v3.1 | >=18.3.1 @hapi/hapi | >=8 | | v3 | >=18 hapi | >=8 | | v2 | >=17 hapi | >=8 | | v1 | >=13 hapi | >=6 |

bissle is the Swabian term for a little bit, it should visualize the sense of pagination.

Installation

For installation use the Node Package Manager:

$ npm install --save bissle

or clone the repository:

$ git clone https://github.com/felixheck/bissle

Usage

Import

First you have to import the module and the peer dependency akaya:

const bissle = require('bissle');
const akaya = require('akaya');

Create Hapi server

Afterwards create your Hapi.js server if not already done:

const hapi = require('@hapi/hapi');
const server = hapi.server({
  port: 1337,
  host: 'localhost',
});

Registration

Finally register the plugins per server.register():

await server.register([akaya, bissle]);
await server.start();

After registering bissle, the hapi.js response toolkit will be decorated with the new method h.bissle().

Joi Validation

If you use Joi for request validation, simply add the parameters to the query scheme. The plugin exposes the all bissle related scheme via server.plugins.bissle.scheme. Alternatively it is possible to enable the allowUnknown option.The exposed object contains additionally the scheme for plugin related options.

API

Plugin Options

While the plugin registration it is possible to pass a plugin specific options object:

  • options {Object} - The plugin specific options object.
    • host {string} - The host to use in the URLDefault: undefined (utilizes request.info.host)
    • absolute {boolean} - If the pagination links (not the Link header) should be absolute or not.Default: false.
    • paramNames {Object} - Config object for overriding default parameter names output in the response
      • perPage {string} - Parameter name for describing the page limit Default: per_page
      • page {string} - Parameter name for describing the current page Default: page
      • total {string} - Parameter name for describing the total item count Default: total

toolkit.bissle(response, [options])

An additional response toolkit for paginated responses.

  • response {Object} - The result to be decorated and replied.
  • options {Object} - The custom default values.
    • key {string} - The access key of response to get the result to be paginated.Default: 'result'.
    • perPage {number} - The default entries per page if none is defined in the query string.Default: 100.Range: 1-500.
    • total {number} - Overwrite the internally generated total value and avoid data splicing. The passed response get returned without internally done pagination. Just meta information and the Link header get added.Default: null.Range: >=0.

Example

The following example demonstrates the usage of bissle in combination with mongoose, halacious and various utilities.

const hapi = require('@hapi/hapi');
const bissle = require('bissle');
const halacious = require('halacious');
const akaya = require('akaya');
const Boom = require('@hapi/boom');
const _ = require('lodash');
const YourModel = require('./models/yourModel');

const server = hapi.server({ port: 1337 });

server.route({
  method: 'GET',
  path: '/',
  config: {
    id: 'root',
    handler (request, h) {
      YourModel.find({}, (err, result) => {
        if (err) throw Boom.badRequest(err);
        if (!result) throw Boom.notFound();

        return h.bissle({ result });
      });
    },
    plugins: {
      hal: {
        prepare(rep) {
          _.forEach(rep.entity.result, task => {
            rep.embed('task', `./${task._id}`, task);
          });
        },
        ignore: ['result']
      }
    }
});

(async () => {
  try {
    await server.register([akaya, halacious, {
      plugin: bissle,
      options: { absolute: false }
    }]);
    await server.start();
    console.log('Server started successfully');
  } catch (err) {
    console.error(err);
  }
})();

Assuming that mongoose's find() returns the following data as result:

[
  {
    _id: "abc",
    title: "abc"
  },
  {
    _id: "def",
    title: "def"
  },
  {
    _id: "ghi",
    title: "ghi"
  },
  {
    _id: "jkl",
    title: "jkl"
  },
  {
    _id: "mno",
    title: "mno"
  }
]

Requesting the route /items?page=2&per_page=2, the plugin replies:

{
  _links: {
    self: {
      href: "/items?page=2&per_page=2"
    },
    first: {
      href: "/items?per_page=2"
    },
    prev: {
      href: "/items?per_page=2"
    },
    next: {
      href: "/items?page=3&per_page=2"
    },
    last: {
      href: "/items?page=3&per_page=2"
    },
  },
  page: 2,
  per_page: 2,
  total: 5,
  result: [
    {
      _id: "ghi",
      title: "ghi"
    },
    {
      _id: "jkl",
      title: "jkl"
    }
  ]
}

Additionally the plugin sets the corresponding Link header.


The halacious plugin enables to extend this response to:

{
  _links: {
    self: {
      href: "/items?page=2&per_page=2"
    },
    first: {
      href: "/items?per_page=2"
    },
    prev: {
      href: "/items?per_page=2"
    },
    next: {
      href: "/items?page=3&per_page=2"
    },
    last: {
      href: "/items?page=3&per_page=2"
    },
  },
  page: 2,
  per_page: 2,
  total: 5,
  _embedded: [
    {
      _links: {
        self: {
          href: "/items/ghi"
        }
      },
      _id: "ghi",
      title: "ghi"
    },
    {
      _links: {
        self: {
          href: "/items/jkl"
        }
      },
      _id: "jkl",
      title: "jkl"
    }
  ]
}

So in the end the combination of bissle and a HAL plugin results in a REST/HAL compliant and paginated response.

Testing

First you have to install all dependencies:

$ npm install

To execute all unit tests once, use:

$ npm test

or to run tests based on file watcher, use:

$ npm start

To get information about the test coverage, use:

$ npm run coverage

Contribution

Fork this repository and push in your ideas.

Do not forget to add corresponding tests to keep up 100% test coverage.