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

@superhero/oas

v4.0.0

Published

OpenAPI Specification (OAS) router

Downloads

71

Readme

OAS

A Node.js library for integrating OpenAPI specifications into an application. With @superhero/oas, you can define, validate, and route API operations using OpenAPI's structured standard.

OBS! This is an early release of this component.

Features

  • Builds API routes from OpenAPI specifications.
  • Validate request parameters, bodies, and responses using OpenAPI schemas.
  • Supports OpenAPI components for modular and reusable specifications.
  • Middlewares for handling parameters, request bodies, and responses.

Installation

Install via npm:

npm install @superhero/oas

Usage

Defining an OpenAPI Specification

For detailed information about how to define an OpenAPI Specification, refer to the OpenAPI Specification Documentation.

Bootstrapping the Library

Set up and bootstrap the @superhero/oas library with your specification:

import HttpServer from '@superhero/http-server';
import Locator    from '@superhero/locator';
import OAS        from '@superhero/oas';
import Router     from '@superhero/router';

// Instantiate the service locator
const locator = new Locator();

// Instantiate the router
const router = new Router(locator);

// Instantiate the server
const server = new HttpServer(router);

// Instantiate the OAS instance
const oas = new OAS(router)

// Register the route dispatcher service
locator.set('hello-dispatcher', {
  dispatch: (request, session) => {
    session.view.body.message = 'Hello, World!';
  },
});

// Bootstrap and start the server
await server.bootstrap();
await server.listen(3000);

// Routes
const specification = {
  paths: {
    '/example': {
      get: {
        operationId: 'hello-dispatcher',
        responses: { 200: { description: 'Hello World' } },
      },
    },
  },
};

oas.bootstrap(specification)

Adding Middleware for Parameters and Request Bodies

The library automatically adds middleware for validating request parameters, request bodies, and responses as defined in the specification.

For example:

const specification = {
  paths: {
    '/example': {
      post: {
        operationId: 'example',
        requestBody: {
          required: true,
          content: {
            'application/json': {
              schema: {
                type: 'object',
                properties: {
                  name: { type: 'string', minLength: 1 },
                  age: { type: 'integer', minimum: 0 },
                },
                required: ['name'],
              },
            },
          },
        },
        responses: {
          201: { description: 'Created' },
          400: { description: 'Validation Error' },
        },
      },
    },
  },
};

oas.bootstrap(specification);

This will ensure:

  • Request parameters are validated.
  • Request bodies are checked against the defined schema.
  • Responses are validated according to the specification.
  • A dispatcher called example will dispatch the request.

Setting Up a Dispatcher

Map the operationId from your specification to a dispatcher:

locate.set('example-reader', {
  dispatch: (request, session) => {
    session.view.body = { message: `Fetched data for ID: ${request.param.id}` };
  },
});

locate.set('example-writer', {
  dispatch: (request, session) => {
    session.view.body = { message: `Created data for ${request.body.name}` };
  },
});

Error Handling

The library throws descriptive errors (will be improved on in comming versions) for invalid specifications or operations.

Testing

The test suite uses Node.js's built-in testing module.

Running Tests

To run the tests, execute:

npm test

Test Coverage

▶ @superhero/oas/schemas
  ▶ Supported attributes
    ▶ type:boolean
      ✔ nullable enum (3.35678ms)
      ✔ throws if invalid enum type (0.300923ms)
      ✔ casts strings that can be interpreted as a boolean value to boolean (0.325861ms)
      ✔ throws if invalid (0.270627ms)
    ✔ type:boolean (6.104481ms)

    ▶ type:integer
      ✔ nullable enum (0.455196ms)
      ✔ minimum (0.190364ms)
      ✔ maximum (0.276653ms)
      ✔ exclusiveMinimum (0.311391ms)
      ✔ exclusiveMaximum (0.678551ms)
      ✔ multipleOf (0.457454ms)
      ✔ format int32 (0.319436ms)
      ✔ format int64 (0.357137ms)
      ✔ throws if invalid format (0.152509ms)
      ✔ throws if invalid enum type (0.134188ms)
      ✔ throws if a decimal (0.217675ms)
    ✔ type:integer (5.643484ms)

    ▶ type:number
      ✔ nullable enum (0.549315ms)
      ✔ format float (0.21403ms)
      ✔ format double (0.186924ms)
      ✔ throws if invalid enum type (0.221865ms)
      ✔ casts strings that can be interpreted as a number value to number (0.107354ms)
    ✔ type:number (2.023555ms)

    ▶ type:string
      ✔ nullable enum (1.457643ms)
      ✔ minLength (0.20732ms)
      ✔ maxLength (0.154873ms)
      ✔ pattern (0.303383ms)
      ✔ format date (1.632527ms)
      ✔ format time (0.389043ms)
      ✔ format datetime (0.413008ms)
      ✔ format base64 (0.432533ms)
      ✔ format email (0.23688ms)
      ✔ format ipv4 (1.006419ms)
      ✔ format ipv6 (6.590692ms)
      ✔ url (0.494795ms)
      ✔ format uuid (0.340933ms)
      ✔ throws if invalid enum type (0.139166ms)
    ✔ type:string (15.599415ms)

    ▶ type:null
      ✔ throws if not null (0.296927ms)
      ✔ throws if value is null and type is not null (0.210403ms)
    ✔ type:null (0.874171ms)

    ✔ type:undefined (0.140063ms)

    ▶ type:array
      ✔ throws if invalid type (0.359969ms)
      ✔ items (1.020706ms)
      ✔ additionalItems (0.21037ms)
      ✔ minItems (0.248753ms)
      ✔ maxItems (0.329635ms)
      ✔ uniqueItems (0.890805ms)
      ✔ enum (0.259908ms)
      ✔ throws if invalid enum type (0.304887ms)
      ✔ nullable enum (0.764214ms)
      ✔ nullable items (0.265034ms)
      ✔ nullable enum items (0.169632ms)
    ✔ type:array (6.446302ms)

    ▶ type:object
      ✔ throws if invalid type (0.282162ms)
      ✔ additionalProperties (0.33254ms)
      ✔ minProperties (0.22744ms)
      ✔ maxProperties (0.203384ms)
      ✔ propertyNames pattern (0.313919ms)
      ✔ nullable (0.111406ms)
      ✔ enum (0.243711ms)
      ✔ nullable enum (0.304399ms)
      ✔ throws if invalid enum type (0.132201ms)
    ✔ type:object (3.92496ms)

    ✔ type:invalid throws (0.146378ms)

    ▶ readOnly
      ✔ when is reading (0.130151ms)
      ✔ when is writing (0.166433ms)
    ✔ readOnly (0.514571ms)

    ▶ writeOnly
      ✔ when is reading (0.19847ms)
      ✔ when is writing (0.111985ms)
    ✔ writeOnly (0.519254ms)

    ▶ default
      ✔ when no value (0.122471ms)
      ✔ when value (0.109269ms)
    ✔ default (0.423953ms)

    ▶ if/then/else
      ✔ then (0.116916ms)
      ✔ else (0.202285ms)
      ✔ throws if invalid (0.391854ms)
    ✔ if/then/else (1.17015ms)

    ✔ not (0.250797ms)

    ▶ allOf
      ✔ result only what is expected (0.181802ms)
      ✔ throws if all are not valid (0.168471ms)
    ✔ allOf (1.106621ms)

    ▶ anyOf
      ✔ conforms to valid schema (0.147225ms)
      ✔ throws if none is valid (0.170714ms)
    ✔ anyOf (0.547187ms)

    ▶ oneOf
      ✔ conforms to valid schema (0.157463ms)
      ✔ throws if none is valid (0.12812ms)
      ✔ throws if more than one is valid (0.129512ms)
    ✔ oneOf (0.726333ms)

    ✔ const (0.305981ms)
    ✔ deep const (1.424227ms)
    ✔ throws on invalid $ref (0.605318ms)
    ✔ throws on invalid schema (0.147341ms)
  ✔ Supported attributes (49.751109ms)
✔ @superhero/oas/schemas (50.297111ms)

▶ @superhero/oas
  ✔ Can set a simple specification (79.360931ms)
  ✔ Can add middleware for requestBody content (10.793273ms)
  ✔ Can add middleware for parameters (8.350745ms)

  ▶ Specification with reference to components
    ✔ GET method using default parameter (31.754399ms)
    ✔ GET method not using required parameter (6.148027ms)
    ✔ GET method using path parameter (5.035696ms)
    ✔ GET method using query parameter (5.464326ms)
    ✔ GET method using header parameter (4.530933ms)
    ✔ POST method using request body (4.042791ms)
  ✔ Specification with reference to components (72.699754ms)

  ✔ Throws error for invalid paths type in specification (8.362196ms)
  ✔ Throws error for missing response (4.73213ms)
  ✔ Throws error for missing operationId in operation (7.265388ms)
  ✔ Throws error for missing responses in operation (7.791663ms)
  ✔ Throws error for missing response code (7.583666ms)
  ✔ Throws error for unsupported content type in requestBody (7.55338ms)
  ✔ Throws error for invalid parameters type (5.039937ms)
✔ @superhero/oas (222.477838ms)

tests 110
suites 3
pass 110

-----------------------------------------------------------------------------------------------------
file                 | line % | branch % | funcs % | uncovered lines
-----------------------------------------------------------------------------------------------------
components           |        |          |         | 
 abstraction.js      |  76.10 |    72.00 |  100.00 | 42-48 63-68 71-76 89-93 100-104 111-115 140-143
 headers.js          |  69.14 |    64.29 |   66.67 | 30-33 37-38 43-46 53-54 63-66 70-75 78-80
 parameters.js       |  70.43 |    77.78 |  100.00 | 65-69 98-101 128-132 142-164 167-184
 request-bodies.js   |  78.38 |    65.00 |  100.00 | 50-55 58-61 70-73 90-94 105-109
 responses.js        |  86.26 |    80.00 |  100.00 | 40-44 67-71 88-91 116-119
 schemas.js          | 100.00 |    98.00 |  100.00 | 
 schemas.test.js     | 100.00 |   100.00 |  100.00 | 
index.js             |  93.24 |    86.36 |  100.00 | 112-115 118-123
index.test.js        | 100.00 |   100.00 |   96.55 | 
middleware           |        |          |         | 
 parameters.js       |  90.91 |    88.89 |  100.00 | 39-42
 request-bodies.js   | 100.00 |   100.00 |  100.00 | 
 responses.js        | 100.00 |   100.00 |  100.00 | 
-----------------------------------------------------------------------------------------------------
all files            |  94.81 |    94.28 |   99.26 | 
-----------------------------------------------------------------------------------------------------

License

This project is licensed under the MIT License.

Contributing

Feel free to submit issues or pull requests for improvements or additional features.