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

kitsu

v10.1.5

Published

A simple, lightweight & framework agnostic JSON:API client using Axios

Downloads

20,815

Readme

Features

  • JSON-API 1.0 compliant
  • Automatically links relationships to data
  • Works in Node & browsers
  • Uses the Promise API

Node / Browser Support

| Package | Package Size* | ESM Size† | Node | Chrome | Firefox | Safari | Edge | | ------: | :----------------: | :-------: | :--: | :----: | :-----: | :----: | :--: | | kitsu | ≤ 8.7 kb | ≤ 8.6 KB | 14+ | 83+ | 78+ | 13.1+ | 95+ |

* Including all dependencies & minified with brotli † EcmaScript Modules package size*

Response Comparison

{
  data: {
    id: '1'
    type: 'articles'
    attributes: {
      title: 'JSON API paints my bikeshed'
    }
    relationships: {
      author: {
        data: {
          id: '42'
          type: 'people'
        }
      }
    }
  }
  included: [
    {
      id: '42'
      type: 'people'
      attributes: {
        name: 'John'
      }
    }
  ]
}
{
  data: {
    id: '1'
    type: 'articles'
    title: 'JSON API paints my bikeshed'
    author: {
      data: {
        id: '42'
        type: 'people'
        name: 'John'
      }
    }
  }
}

Install

Yarn / NPM

yarn add kitsu
npm install kitsu
import Kitsu from "kitsu"; // ES Modules & Babel
const Kitsu = require("kitsu"); // CommonJS & Browserify

Quick Start

// Kitsu.io's API
const api = new Kitsu()

// Other JSON:API servers
const api = new Kitsu({
  baseURL: 'https://api.example/2'
})

// Using with async/await
const res = await api.get('anime')

// Using with Promises
api.get('anime')
  .then(res => { ... })
  .catch(err => { ... })

// Fetching resources (get/fetch)
api.fetch('anime')
api.fetch('anime', { params: { filter: { id: 1 } } })
api.fetch('anime/1/episodes')
api.fetch('anime/1/relationships/episodes')

// Creating resources (post/create)
api.create('post', {
  content: 'some content'
})

// Updating resources (patch/update)
api.update('post', {
  id: '1',
  content: 'new content'
})

// Deleting resources (delete/remove)
api.remove('post', 1)

// JSON:API parameters
api.get('users', {
  params: {
    include: 'followers,waifu.character',
    fields: {
      users: 'slug,followers,waifu'
    },
    filter: {
      slug: 'wopian'
    },
    sort: '-id',
    page: {
      limit: 5,
      offset: 0
    }
  }
})

More Examples

If you're working with Kitsu.io's API, their API docs lists all available resources with their attributes & relationships

Contributing

See CONTRIBUTING

Releases

See CHANGELOG

License

All code released under MIT

API

Table of Contents

Kitsu

packages/kitsu/src/index.js:31-532

Creates a new kitsu instance

Parameters

  • options Object? Options (optional, default {})

    • options.baseURL string Set the API endpoint (optional, default https://kitsu.io/api/edge)
    • options.headers Object? Additional headers to send with the requests
    • options.query ("traditional" | "modern" | Function) Query serializer function to use. This will impact the way keys are serialized when passing arrays as query parameters. 'modern' is recommended for new projects. (optional, default traditional)
    • options.camelCaseTypes boolean If enabled, type will be converted to camelCase from kebab-casae or snake_case (optional, default true)
    • options.resourceCase ("kebab" | "snake" | "none") Case to convert camelCase to. kebab - /library-entries; snake - /library_entries; none-/libraryEntries` (optional, default kebab)
    • options.pluralize boolean If enabled, /user will become /users in the URL request and type will be pluralized in POST, PATCH and DELETE requests (optional, default true)
    • options.timeout number Set the request timeout in milliseconds (optional, default 30000)
    • options.axiosOptions Object? Additional options for the axios instance (see axios/axios#request-config for details)

Examples

Using with Kitsu.io's API

const api = new Kitsu()

Using another API server

const api = new Kitsu({
  baseURL: 'https://api.example.org/2'
})

Setting headers

const api = new Kitsu({
  headers: {
    'User-Agent': 'MyApp/1.0.0 (github.com/username/repo)',
    Authorization: 'Bearer 1234567890'
  }
})

plural

packages/kitsu/src/index.js:58-59

If pluralization is enabled (default, see Kitsu constructor docs) then pluralization rules can be added

Examples

Adding an uncountable pluralization rule

api.plural.plural('paper') //=> 'papers'
api.plural.addUncountableRule('paper')
api.plural.plural('paper') //=> 'paper'

headers

packages/kitsu/src/index.js:73-73

Get the current headers or add additional headers

Examples

Get all headers

api.headers

Get a single header's value

api.headers['User-Agent']

Add or update a header's value

api.headers['Authorization'] = 'Bearer 1234567890'

Returns Object All the current headers

interceptors

packages/kitsu/src/index.js:120-120

Axios Interceptors (alias of axios.interceptors)

You can intercept responses before they are handled by get, post, patch and delete and before requests are sent to the API server.

Examples

Request Interceptor

// Add a request interceptor
api.interceptors.request.use(config => {
   // Do something before request is sent
   return config
}, error => {
   // Do something with the request error
   return Promise.reject(error)
})

Response Interceptor

// Add a response interceptor
api.interceptors.response.use(response => {
   // Any status code that lie within the range of 2xx cause this function to trigger
   // Do something with response data
   return response
}, error => {
   // Any status codes that falls outside the range of 2xx cause this function to trigger
   // Do something with response error
   return Promise.reject(error)
})

Removing Interceptors

const myInterceptor = api.interceptors.request.use(function () {...})
api.interceptors.request.eject(myInterceptor)

get

packages/kitsu/src/index.js:218-246

Fetch resources (alias fetch)

Parameters
  • model string Resource to fetch data from. Expected formats are :resource, :resource/:id, :resource/:id/:relationship or :resource/:id/relationships/:relationship

  • config Object? Additional configuration (optional, default {})

    • config.headers Object? Additional headers to send with the request

    • config.params Object? JSON:API request queries. JSON:API query parameters not listed are supported

      • config.params.fields Object? Return a sparse fieldset with only the included attributes/relationships - JSON:API Sparse Fieldsets

      • config.params.filter Object? Filter dataset by attribute values - JSON:API Filtering

      • config.params.include string? Include relationship data - JSON:API Includes

      • config.params.sort string? Sort dataset by one or more comma separated attributes (prepend - for descending order) - JSON:API Sorting

      • config.params.page Object? JSON:API Pagination. All pagination strategies are supported, even if they are not listed below.

        • config.params.page.limit number? Number of resources to return in request (Offset-based) - Note: For Kitsu.io, max is 20 except on libraryEntries which has a max of 500
        • config.params.page.offset number? Number of resources to offset the dataset by (Offset-based)
        • config.params.page.number number? Page of resources to return in request (Page-based) - Note: Not supported on Kitsu.io
        • config.params.page.size number? Number of resources to return in request (Page-based and cursor-based) - Note: Not supported on Kitsu.io
        • config.params.page.before string? Get the previous page of resources (Cursor-based) - Note: Not Supported on Kitsu.io
        • config.params.page.after string? Get the next page of resources (Cursor-based) - Note: Not Supported on Kitsu.io
    • config.axiosOptions Object? Additional options for the axios instance (see axios/axios#request-config for details)

Examples

Getting a resource with JSON:API parameters

api.get('users', {
  params: {
    fields: {
      users: 'name,birthday'
    },
    filter: {
      name: 'wopian'
    }
  }
})

Getting a collection of resources with their relationships

api.get('anime', {
  params: {
    include: 'categories'
  }
})

Getting a single resource by ID (method one)

api.get('anime/2', {
  params: {
    include: 'categories'
  }
})

Getting a single resource by ID (method two)

api.get('anime', {
  params: {
    include: 'categories',
    filter: { id: '2' }
 }
})

Getting a resource's relationship data only

api.get('anime/2/categories')

Getting a resource with nested JSON:API filters (not supported by Kitsu.io's API)

// resource?filter[x][y]=value
api.get('resource', {
  params: {
    filter: {
      x: {
        y: 'value'
      }
    }
  }
}

Handling errors (async/await)

try {
  const { data } = await api.get('anime')
} catch (err) {
  // Array of JSON:API errors: http://jsonapi.org/format/#error-objects
  if (err.errors) err.errors.forEach(error => { ... })
  // Error type (Error, TypeError etc.)
  err.name
  // Error message
  err.message
  // Axios request parameters
  err.config
  // Axios response parameters
  err.response
}

Handling errors (Promises)

api.get('anime')
  .then(({ data }) => { ... })
  .catch(err => {
    // Array of JSON:API errors: http://jsonapi.org/format/#error-objects
    if (err.errors) err.errors.forEach(error => { ... })
    // Error type (Error, TypeError etc.)
    err.name
    // Error message
    err.message
    // Axios request parameters
    err.config
    // Axios response parameters
    err.response
  })

Returns Object JSON-parsed response

patch

packages/kitsu/src/index.js:282-309

Update a resource (alias update)

Parameters
Examples

Update a resource

api.update('posts', {
  id: '1',
  content: 'Goodbye World'
})

Update a resource with relationships

api.update('posts', {
  content: 'Hello World',
  uploads: {
    id: '167585',
    type: 'uploads'
  }
})

Clear to-one relationships from a resource

api.update('posts/1/relationships/uploads', null)

Clear to-many relationships from a resource

api.update('posts/1/relationships/uploads', [])

Update multiple resources (API must support the Bulk Extension)

api.update('posts', [
  { id: '1', content: 'Hello World' },
  { id: '2', content: 'Another post' }
])

Returns (Object | Array<Object>) JSON-parsed response

post

packages/kitsu/src/index.js:344-369

Create a new resource (alias create)

Parameters
Examples

Create a post on a user's profile feed

api.create('posts', {
  content: 'Hello World',
  targetUser: {
    data: {
      id: '42603',
      type: 'users'
    }
  },
  user: {
    data: {
      id: '42603',
      type: 'users'
    }
  }
})

Create multiple resources (API must support the Bulk Extension)

api.create('posts', [
  { content: 'Hello World' },
  { content: 'Another post' }
])

Returns (Object | Array<Object>) JSON-parsed response

delete

packages/kitsu/src/index.js:389-422

Remove a resource (alias remove)

Parameters
Examples

Remove one or more relationships from a resource

api.delete('posts/1/relationships/uploads', [456, 789])

Remove a single resource

api.delete('posts', 123)

Remove multiple resources (API must support the Bulk Extension)

api.delete('posts', [ 1, 2 ])

Returns (Object | Array<Object>) JSON-parsed response

self

packages/kitsu/src/index.js:446-455

Get the authenticated user's data

Note Requires the JSON:API server to support filter[self]=true

Parameters
  • config Object? Additional configuration (optional, default {})

    • config.params Object? JSON:API request queries. See #get for documentation
    • config.headers Object? Additional headers to send with the request
    • config.axiosOptions Object? Additional options for the axios instance (see axios/axios#request-config for details)
Examples

Get the authenticated user's resource

api.self()

Using JSON:API parameters

api.self({
  params: {
    fields: {
      users: 'name,birthday'
    }
  }
})

Returns Object JSON-parsed response

request

packages/kitsu/src/index.js:510-531

Send arbitrary requests

Note Planned changes to the get, patch, post and delete methods in a future major release may make this method redundent. See https://github.com/wopian/kitsu/issues/415 for details.

Parameters
  • config Object? Request configuration

    • config.body (Object | Array<Object>)? Data to send in the request
    • config.method string? Request method - GET, PATCH, POST or DELETE (defaults to GET, case-insensitive)
    • config.params Object? JSON:API request queries. See #get for documentation
    • config.type string The resource type
    • config.url string The URL path of the resource
    • config.headers Object? Additional headers to send with the request
    • config.axiosOptions Object? Additional options for the axios instance (see axios/axios#request-config for details)
Examples

Raw GET request

api.request({
  url: 'anime/1/mappings',
  type: 'mappings',
  params: { filter: { externalSite: 'aozora' } }
})

Raw PATCH request

api.request({
  method: 'PATCH',
  url: 'anime',
  type: 'anime',
  body: { id: '1', subtype: 'tv' }
})

Raw POST request

api.request({
  method: 'PATCH',
  url: 'anime',
  type: 'anime',
  body: { subtype: 'tv' }
})

Raw DELETE request

api.request({
  method: 'DELETE',
  url: 'anime/1',
  type: 'anime',
  body: { id: '1' }
})

Bulk Extension support (PATCH, POST & DELETE)

api.request({
  method: 'PATCH',
  url: 'anime',
  type: 'anime',
  body: [
    { id: '1', subtype: 'tv' }
    { id: '2', subtype: 'ona' }
  ]
})

Returns Object JSON-parsed response