UNPKG

textiot

Version:

A framework for building web and native (IoT) Dapps on the IPFS network

201 lines (183 loc) 6.33 kB
import '@ef-carbon/fetch/install' import URL from 'url-parse' import { buildAbsoluteURL } from 'url-toolkit' import { KeyValue, ApiOptions } from '../models' export const DEFAULT_API_OPTIONS = { url: 'http://127.0.0.1', port: 40600, version: 0 } /** * Create 'args' like a CLI command would take * * @param {string[]} argsAr An array of arguments * @private */ export const getArgs = (argsAr?: string[]) => { if (!argsAr || !argsAr.length) { return '' } return argsAr.map((ar) => encodeValue(ar)).join(',') } /** * Create 'options' like a CLI command would take. * * @param {Object.<string, string>} opts A map of option keys and values * @private */ export const getOpts = (opts?: KeyValue) => { if (!opts) { return '' } return Object.keys(opts) .map((key) => `${key}=${encodeValue(opts[key])}`) .join(',') } const encodeValue = (val: string | number | boolean) => { return encodeURIComponent(val.toString()) } export const createHeaders = (args?: string[], opts?: KeyValue, headers?: KeyValue): Record<string, string> => { const h = headers || {} return { ...h, 'X-Textile-Args': getArgs(args), 'X-Textile-Opts': getOpts(opts) } } const handleErrors = (response: Response) => { if (!response.ok) { throw Error(response.statusText) } return response } /** * API is the base class for all SDK modules. * * @params {ApiOptions] opts API options object */ class API { private opts: ApiOptions private baseURL: string private gatewayURL: string constructor(opts: ApiOptions = DEFAULT_API_OPTIONS) { this.opts = opts const url = new URL(opts.url) if (opts.port) { url.set('port', opts.port) } url.set('pathname', `/api/v${opts.version || 0}/`) this.baseURL = url.toString() const gateway = new URL(this.opts.url) gateway.set('port', 5050) gateway.set('pathname', `/ipfs/`) this.gatewayURL = gateway.toString() } /** * Make a get request to the Textile node * * @param url The relative URL of the API endpoint * @param args An array of arguments to pass as Textile args headers * @param opts An object of options to pass as Textile options headers */ protected async sendGatewayGet(path: string, headers?: KeyValue) { return fetch(buildAbsoluteURL(this.gatewayURL, path), { method: 'GET', headers: createHeaders([], {}, headers) }) } /** * Make a post request to the Textile node * * @param url The relative URL of the API endpoint * @param args An array of arguments to pass as Textile args headers * @param opts An object of options to pass as Textile options headers * @param data An object of data to post */ protected async sendPost(url: string, args?: string[], opts?: KeyValue, data?: any, headers?: KeyValue, raw?: boolean) { const h = createHeaders(args, opts, headers) const response = await fetch(buildAbsoluteURL(this.baseURL, url), { method: 'POST', headers: new Headers(h), body: raw ? data : JSON.stringify(data) }) return handleErrors(response) } /** * Make a get request to the Textile node * * @param url The relative URL of the API endpoint * @param args An array of arguments to pass as Textile args headers * @param opts An object of options to pass as Textile options headers */ protected async sendGet(url: string, args?: string[], opts?: KeyValue, headers?: KeyValue) { const response = await fetch(buildAbsoluteURL(this.baseURL, url), { method: 'GET', headers: createHeaders(args, opts, headers) }) return handleErrors(response) } /** * Make a delete request to the Textile node * * @param url The relative URL of the API endpoint * @param args An array of arguments to pass as Textile args headers * @param opts An object of options to pass as Textile options headers */ protected async sendDelete(url: string, args?: string[], opts?: KeyValue, headers?: KeyValue) { const response = await fetch(buildAbsoluteURL(this.baseURL, url), { method: 'DELETE', headers: createHeaders(args, opts, headers) }) return handleErrors(response) } /** * Make a put request to the Textile node * * @param url The relative URL of the API endpoint * @param args An array of arguments to pass as Textile args headers * @param opts An object of options to pass as Textile options headers * @param data An object of data to put */ protected async sendPut(url: string, args?: string[], opts?: KeyValue, data?: any, headers?: KeyValue) { const response = await fetch(buildAbsoluteURL(this.baseURL, url), { method: 'PUT', headers: createHeaders(args, opts, headers), body: JSON.stringify(data) }) return handleErrors(response) } /** * Make a patch request to the Textile node * * @param url The relative URL of the API endpoint * @param args An array of arguments to pass as Textile args headers * @param opts An object of options to pass as Textile options headers * @param data An object of data to put */ protected async sendPatch(url: string, args?: string[], opts?: KeyValue, data?: any, headers?: KeyValue) { const response = await fetch(buildAbsoluteURL(this.baseURL, url), { method: 'patch', headers: createHeaders(args, opts, headers), body: JSON.stringify(data) }) return handleErrors(response) } /** * Make an EventSource request to the Textile node * * @param url The relative URL of the API endpoint * @param args An array of arguments to pass as query in native EventSource or Textile args headers in EventSourcePolyfill * @param opts An object of options to pass as Textile options headers */ protected sendEventSource(url: string, args?: string[], opts?: KeyValue, headers?: KeyValue) { // native EventSource can't set header, but can CORS return new EventSource(buildAbsoluteURL(this.baseURL, `${url}${opts ? `?${URL.qs.stringify(opts)}` : ''}`)) // EventSourcePolyfill of eventsource@1.0.7 can set header, but can't CORS // return new EventSourcePolyfill(buildAbsoluteURL(this.baseURL, url), { // headers: { // 'X-Textile-Opts': getOpts(opts), // } // }); } } export { API }