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

@zakkudo/open-api-tree

v1.0.0

Published

Make working with swagger/openapi api trees enjoyable.

Downloads

70

Readme

@zakkudo/open-api-tree

Make working with backend api trees enjoyable from swagger/openapi.

Build Status Coverage Status Known Vulnerabilities Node License

Generate an easy to use api tree that includes format checking using JSON Schema for the body and params with only a single configuration object. Network calls are executed using a thin convenience wrapper around fetch.

This library is a thin wrapper for @zakkudo/api-tree if you need the same functionality but don't use Swagger.

Why use this?

  • Consistancy with simplicity
  • No longer need to maintain a set of functions for accessing apis
  • Automatic validation of the body/params against the Swagger definition
  • Support for Swagger 1.2, Swagger 2.0 and OpenApi 3.0.x definitions
  • Leverages native fetch, adding a thin convenience layer in the form of Fetch Functions
  • Share authorization handling using a single location that can be updated dynamically
  • Share a single transform for the responses and request in a location that can be updated dynamically
  • Supports overloading the tree methods so that you can use the same method for getting a single item or a collection of items

The api tree is based off of the path name

  • [POST] /users -> api.users.post({body: data})
  • [GET] /users/{id} -> api.users.get({params: {id: 1}})
  • [GET] /users -> api.users.get()
  • [PUT] /users/{id} -> api.users.put({params: {id: 1}, body: data})
  • [GET] /users/{userId}/roles/{roleId} -> api.users.roles.get({params: {userId: 1, roleId: 3}})

Install

# Install using npm
npm install @zakkudo/open-api-tree
# Install using yarn
yarn add @zakkudo/open-api-tree

Examples

Parse a swagger schema at runtime

import OpenApiTree from '@zakkudo/open-api-tree';
import fetch from '@zakkudo/fetch';

fetch('https://petstore.swagger.io/v2/swagger.json').then((configuration) => {
    const api = new OpenApiTree(configuration, {
        headers: {
             'X-AUTH-TOKEN': '1234'
        }
    });

    // GET http://petstore.swagger.io/api/pets?limit=10
    api.pets.get({params: {limit: 10}})

    // GET http://petstore.swagger.io/api/pets/1
    api.pets.get({params: {id: 1}})

    // POST http://petstore.swagger.io/api/pets
    api.pets.post({})

    // DELETE http://petstore.swagger.io/api/pets/1
    api.pets.delete({params: {id: 1}});
});

Parse a swagger schema at buildtime in webpack

//In webpack.conf.js////////////////////////////
import ApiTree from '@zakkudo/api-tree';

const toApiTreeSchema = require('@zakkudo/open-api-tree/toApiTreeSchema').default;
const execSync = require('child_process').execSync;
const configuration = JSON.parse(String(execSync('curl https://petstore.swagger.io/v2/swagger.json'));

module.exports = {
    plugins: [
        new DefinePlugin({
            __API_CONFIGURATION__: JSON.stringify(toApiTreeSchema(configuration))
        })
    }
}

//In src/api.js////////////////////////////////
import ApiTree from '@zakkudo/api-tree';

export default new ApiTree(__API_CONFIGURATION__);

//In src/index.js////////////////////////////
import api from './api';

// GET http://petstore.swagger.io/api/pets?limit=10
api.pets.get({params: {limit: 10}})

// GET http://petstore.swagger.io/api/pets/1
api.pets.get({params: {id: 1}})

// POST http://petstore.swagger.io/api/pets
api.pets.post({})

// DELETE http://petstore.swagger.io/api/pets/1
api.pets.delete({params: {id: 1}});

Validation error failure example

import ValidationError from '@zakkudo/open-api-tree/ValidationError';

api.pets.get({params: {id: 'lollipops'}}).catch((reason) => {
    if (reason instanceof ValidationError) {
        console.log(reason)
        // ValidationError: [
        //     "<http://petstore.swagger.io/api/pets/:id> .params.id: should be integer"
        // ]
    }

    throw reason;
});

Handling validation errors

import ValidationError from '@zakkudo/open-api-tree/ValidationError';

// Try fetching without an id
api.users.get().catch((reason) => {
    if (reason instanceof ValidationError) {
        console.log(reason); // "params: should have required property 'userId'
    }

    throw reason;
})

// Try using an invalidly formatted id
api.users.get({params: {userId: 'invalid format'}}).catch((reason) => {
    if (reason instanceof ValidationError) {
        console.log(reason); // "params.userId: should match pattern \"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\""
    }

    throw reason;
});

// Skip the validation by passing false to the network call
api.users.get({params: {userId: 'invalid format'}}, false).catch((reason) => {
    if (reason instanceof HttpError) {
        console.log(reason.status); // 500
    }

    throw reason;
});

Don't include validation schemas in api tree

import OpenApiTree from '@zakkudo/open-api-tree';
import HttpError from '@zakkudo/open-api-tree/HttpError';

fetch('https://petstore.swagger.io/v2/swagger.json').then((configuration) => {
    const api = new OpenApiTree(configuration, {
        headers: {
             'X-AUTH-TOKEN': '1234'
        }
    }, {validation: false});

    // Try fetching without an id
    api.users.get().catch((reason) => {
        if (reason instanceof HttpError) {
            console.log(reason.status); // 500
        }

        throw reason;
    })

    // Try using an invalidly formatted id
    api.users.get({params: {userId: 'invalid format'}}).catch((reason) => {
        if (reason instanceof HttpError) {
            console.log(reason.status); // 500
        }

        throw reason;
    });

    // Skip the validation by passing false to the network call
    api.users.get({params: {userId: 'invalid format'}}, false).catch((reason) => {
        if (reason instanceof HttpError) {
            console.log(reason.status); // 500
        }

        throw reason;
    });
});

Handling network errors

import HttpError from '@zakkudo/open-api-tree/HttpError';

// Force execution with an invalidly formatted id
api.users.get({params: {userId: 'invalid format'}}, false).catch((reason) => {
    if (reason instanceof HttpError) {
        console.log(reason.status); // 500
        console.log(reason.response); // response body from the server, often json
    }

    throw reason;
});

Overriding options

import HttpError from '@zakkudo/open-api-tree/HttpError';
import ValidationError from '@zakkudo/open-api-tree/ValidationError';

//Set headers after the fact
api.options.headers['X-AUTH-TOKEN'] = '5678';

//Get 10 users
api.users.get({params: {limit: 10}}).then((users) => {
     console.log(users); // [{id: ...}, ...]
});

//Create a user
api.users.post({first_name: 'John', last_name: 'Doe'}).then((response) => {
     console.log(response); // {id: 'ff599c67-1cac-4167-927e-49c02c93625f', first_name: 'John', last_name: 'Doe'}
});

// Try using a valid id
api.users.get({params: {userId: 'ff599c67-1cac-4167-927e-49c02c93625f'}}).then((user) => {
     console.log(user); // {id: 'ff599c67-1cac-4167-927e-49c02c93625f', first_name: 'john', last_name: 'doe'}
})

// Override the global options at any time
api.users.get({transformResponse: () => 'something else'}).then((response) => {
   console.log(response); // 'something else'
});

API

@zakkudo/open-api-tree~OpenApiTree ⏏

Kind: Exported class

new OpenApiTree(schema, [options], [include])

Returns: Object - The generated api tree

| Param | Type | Default | Description | | --- | --- | --- | --- | | schema | Object | | The swagger/openapi schema, usually accessible from a url path like v2/swagger.json where swagger is run | | [options] | Options | | Options modifying the network call, mostly analogous to fetch | | [include] | Object | | Modifiers for the conversion of the swagger schema to an api tree schema | | [include.validation] | Boolean | true | Set to false to not include json schemas for client side validation of api requests |

OpenApiTree~FetchFunction : function

Executes the network request using the api tree configuration. Generated from the triplets of the form [url, options, jsonschema] where only url is required.

Kind: inner typedef of OpenApiTree

| Param | Type | Default | Description | | --- | --- | --- | --- | | [options] | Options | | The override options for the final network call | | [validate] | Boolean | true | Set to false to force validation to be skipped, even if there is a schema |

OpenApiTree~Options : Object

Options modifying the network call, mostly analogous to fetch

Kind: inner typedef of OpenApiTree
Properties

| Name | Type | Default | Description | | --- | --- | --- | --- | | [options.method] | String | 'GET' | GET, POST, PUT, DELETE, etc. | | [options.mode] | String | 'same-origin' | no-cors, cors, same-origin | | [options.cache] | String | 'default' | default, no-cache, reload, force-cache, only-if-cached | | [options.credentials] | String | 'omit' | include, same-origin, omit | | [options.headers] | String | | "application/json; charset=utf-8". | | [options.redirect] | String | 'follow' | manual, follow, error | | [options.referrer] | String | 'client' | no-referrer, client | | [options.body] | String | Object | | JSON.stringify is automatically run for non-string types | | [options.params] | String | Object | | Query params to be appended to the url. The url must not already have params. The serialization uses the same rules as used by @zakkudo/query-string | | [options.unsafe] | Boolean | | Disable escaping of params in the url | | [options.transformRequest] | function | Array.<function()> | | Transforms for the request body. When not supplied, it by default json serializes the contents if not a simple string. Also accepts promises as return values for asynchronous work. | | [options.transformResponse] | function | Array.<function()> | | Transform the response. Also accepts promises as return values for asynchronous work. | | [options.transformError] | function | Array.<function()> | | Transform the error response. Return the error to keep the error state. Return a non Error to recover from the error in the promise chain. A good place to place a login handler when recieving a 401 from a backend endpoint or redirect to another page. It's preferable to never throw an error here which will break the error transform chain in a non-graceful way. Also accepts promises as return values for asynchronous work. |

@zakkudo/open-api-tree/toApiTreeSchema~toApiTreeSchema(schema, [include]) ⇒ Object

Converts an open-api/swagger schema to an api tree configuration.

Kind: Exported function

Returns: Object - The converted schema that can be passed to ApiTree from @zakkudo/api-tree
Throws:

  • Error when trying to convert an unsupported schema

| Param | Type | Default | Description | | --- | --- | --- | --- | | schema | Object | | The schema as such that comes from swagger.json | | [include] | Object | | Modifiers for the conversion of the swagger schema to an api tree schema | | [include.validation] | Boolean | true | Set to false to not include json schemas for client side validation of api requests |

@zakkudo/open-api-tree/ValidationError~ValidationError ⏏

Aliased error from package @zakkudo/api-tree/ValidationError

Kind: Exported class

@zakkudo/open-api-tree/HttpError~HttpError ⏏

Aliased error from package @zakkudo/api-tree/HttpError

Kind: Exported class

@zakkudo/open-api-tree/UrlError~UrlError ⏏

Aliased error from package @zakkudo/api-tree/UrlError

Kind: Exported class

@zakkudo/open-api-tree/QueryStringError~QueryStringError ⏏

Aliased error from package @zakkudo/api-tree/QueryStringError

Kind: Exported class