4.6.10 • Published 9 months ago

@superhero/oas v4.6.10

Weekly downloads
-
License
MIT
Repository
github
Last release
9 months ago

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.

4.6.7

9 months ago

4.6.6

10 months ago

4.6.9

9 months ago

4.6.8

9 months ago

4.6.3

10 months ago

4.5.4

10 months ago

4.4.5

11 months ago

4.0.9

11 months ago

4.6.2

10 months ago

4.5.3

10 months ago

4.4.4

11 months ago

4.0.8

11 months ago

4.6.5

10 months ago

4.6.4

10 months ago

4.5.0

11 months ago

4.4.1

11 months ago

4.0.5

11 months ago

4.4.0

11 months ago

4.0.4

11 months ago

4.6.1

10 months ago

4.5.2

11 months ago

4.4.3

11 months ago

4.0.7

11 months ago

4.6.10

9 months ago

4.6.0

10 months ago

4.5.1

11 months ago

4.4.2

11 months ago

4.0.6

11 months ago

4.0.3

12 months ago

4.0.2

12 months ago

4.0.1

1 year ago

4.0.0

1 year ago