UNPKG

kitsu

Version:

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

277 lines (273 loc) 7.07 kB
'use strict'; var kitsuCore = require('kitsu-core'); var axios = require('axios'); var pluralise = require('pluralize'); class Kitsu { constructor(options = {}) { const traditional = typeof options.query === 'string' ? options.query === 'traditional' : true; this.query = typeof options.query === 'function' ? options.query : obj => kitsuCore.query(obj, undefined, traditional); if (options.camelCaseTypes === false) this.camel = s => s;else this.camel = kitsuCore.camel; if (options.resourceCase === 'none') this.resCase = s => s;else if (options.resourceCase === 'snake') this.resCase = kitsuCore.snake;else this.resCase = kitsuCore.kebab; if (options.pluralize === false) this.plural = s => s;else this.plural = pluralise; this.headers = { ...{ Accept: 'application/vnd.api+json', 'Content-Type': 'application/vnd.api+json' }, ...options.headers }; this.axios = axios.create({ ...{ baseURL: options.baseURL || 'https://kitsu.app/api/edge', timeout: options.timeout || 30000 }, paramsSerializer: { serialize: p => this.query(p) }, ...options.axiosOptions }); this.fetch = this.get; this.update = this.patch; this.create = this.post; this.remove = this.delete; this.interceptors = this.axios.interceptors; } async get(model, config = {}) { try { const headers = { ...this.headers, ...config.headers }; const params = { ...{}, ...config.params }; const [res, id, relationship, subRelationship] = model.split('/'); let url = this.plural(this.resCase(res)); if (id) url += `/${this.resCase(id)}`; if (relationship) url += `/${this.resCase(relationship)}`; if (subRelationship) url += `/${this.resCase(subRelationship)}`; const { data, headers: responseHeaders, status } = await this.axios.get(url, { headers, params, ...config.axiosOptions }); return { ...kitsuCore.deserialise(data), status, ...(responseHeaders && Object.keys(responseHeaders).length ? { headers: responseHeaders } : {}) }; } catch (E) { throw kitsuCore.error(E); } } async patch(model, body, config = {}) { try { const headers = { ...this.headers, ...config.headers }; const params = { ...{}, ...config.params }; const [resourceModel, url] = kitsuCore.splitModel(model, { resourceCase: this.resCase, pluralModel: this.plural }); const serialData = kitsuCore.serialise(resourceModel, body, 'PATCH', { camelCaseTypes: this.camel, pluralTypes: this.plural }); const fullURL = body?.id ? `${url}/${body.id}` : url; const { data, headers: responseHeaders, status } = await this.axios.patch(fullURL, serialData, { headers, params, ...config.axiosOptions }); return { ...kitsuCore.deserialise(data), status, ...(responseHeaders && Object.keys(responseHeaders).length ? { headers: responseHeaders } : {}) }; } catch (E) { throw kitsuCore.error(E); } } async post(model, body, config = {}) { try { const headers = { ...this.headers, ...config.headers }; const params = { ...{}, ...config.params }; const [resourceModel, url] = kitsuCore.splitModel(model, { resourceCase: this.resCase, pluralModel: this.plural }); const { data, headers: responseHeaders, status } = await this.axios.post(url, kitsuCore.serialise(resourceModel, body, 'POST', { camelCaseTypes: this.camel, pluralTypes: this.plural }), { headers, params, ...config.axiosOptions }); return { ...kitsuCore.deserialise(data), status, ...(responseHeaders && Object.keys(responseHeaders).length ? { headers: responseHeaders } : {}) }; } catch (E) { throw kitsuCore.error(E); } } async delete(model, id, config = {}) { try { const headers = { ...this.headers, ...config.headers }; const params = { ...{}, ...config.params }; const [resourceModel, url] = kitsuCore.splitModel(model, { resourceCase: this.resCase, pluralModel: this.plural }); const isBulk = Array.isArray(id); let path, payload; if (isBulk) { path = url; payload = id.map(id => ({ id })); } else { path = `${url}/${id}`; payload = { id }; } const { data, headers: responseHeaders, status } = await this.axios.delete(path, { data: kitsuCore.serialise(resourceModel, payload, 'DELETE', { camelCaseTypes: this.camel, pluralTypes: this.plural }), headers, params, ...config.axiosOptions }); return { ...kitsuCore.deserialise(data), status, ...(responseHeaders && Object.keys(responseHeaders).length ? { headers: responseHeaders } : {}) }; } catch (E) { throw kitsuCore.error(E); } } async self(config = {}) { try { const headers = { ...this.headers, ...config.headers }; const params = { ...config.params, ...{ filter: { self: true } } }; const res = await this.get('users', { ...{ headers }, ...{ params }, ...config.axiosOptions }); return { ...(res.headers && { headers: res.headers }), ...(res.data?.[0] && { data: res.data[0] }) }; } catch (E) { throw kitsuCore.error(E); } } async request({ body, method, params, type, url, headers, axiosOptions }) { try { method = method?.toUpperCase() || 'GET'; const { data, headers: responseHeaders, status } = await this.axios.request({ method, url, data: ['GET', 'DELETE'].includes(method) ? undefined : kitsuCore.serialise(type, body, method, { camelCaseTypes: this.camel, pluralTypes: this.plural }), headers: { ...this.headers, ...headers }, params, ...axiosOptions }); return { ...kitsuCore.deserialise(data), status, ...(responseHeaders && Object.keys(responseHeaders).length ? { headers: responseHeaders } : {}) }; } catch (E) { throw kitsuCore.error(E); } } } module.exports = Kitsu;