UNPKG

@tak-ps/node-tak

Version:

Lightweight JavaScript library for communicating with TAK Server

173 lines (153 loc) 5.26 kB
import FormData from 'form-data'; import OAuth from './api/oauth.js'; import Package from './api/package.js'; import Query from './api/query.js'; import Locate from './api/locate.js'; import Mission from './api/mission.js'; import MissionLog from './api/mission-log.js'; import MissionLayer from './api/mission-layer.js'; import Credentials from './api/credentials.js'; import Security from './api/security.js'; import Contacts from './api/contacts.js'; import Profile from './api/profile.js'; import Files from './api/files.js'; import Injectors from './api/injectors.js'; import Repeater from './api/repeater.js'; import Group from './api/groups.js'; import Subscription from './api/subscriptions.js'; import Video from './api/video.js'; import Export from './api/export.js'; import Err from '@openaddresses/batch-error'; import * as auth from './auth.js'; export const CommandList: Record<string, keyof TAKAPI> = { package: 'Package', security: 'Security', profile: 'Profile', oauth: 'OAuth', mission: 'Mission', locate: 'Locate', 'mission-log': 'MissionLog', 'mission-layer': 'MissionLayer', credential: 'Credentials', contact: 'Contacts', subscription: 'Subscription', injector: 'Injectors', repeater: 'Repeater', group: 'Group', video: 'Video', export: 'Export', query: 'Query', file: 'Files' } /** * Handle TAK HTTP API Operations * @class */ export default class TAKAPI { auth: auth.APIAuth; url: URL; Package: Package; OAuth: OAuth; Mission: Mission; Locate: Locate; Security: Security; MissionLog: MissionLog; MissionLayer: MissionLayer; Credentials: Credentials; Contacts: Contacts; Subscription: Subscription; Profile: Profile; Injectors: Injectors; Repeater: Repeater; Group: Group; Video: Video; Export: Export; Query: Query; Files: Files; constructor(url: URL, auth: auth.APIAuth) { this.url = url; this.auth = auth; this.Query = new Query(this); this.Security = new Security(this); this.Locate = new Locate(this); this.Package = new Package(this); this.Profile = new Profile(this); this.OAuth = new OAuth(this); this.Export = new Export(this); this.Mission = new Mission(this); this.MissionLog = new MissionLog(this); this.MissionLayer = new MissionLayer(this); this.Credentials = new Credentials(this); this.Contacts = new Contacts(this); this.Subscription = new Subscription(this); this.Group = new Group(this); this.Video = new Video(this); this.Injectors = new Injectors(this); this.Repeater = new Repeater(this); this.Files = new Files(this); } static async init(url: URL, auth: auth.APIAuth): Promise<TAKAPI> { const api = new TAKAPI(url, auth); await api.auth.init(api); return api; } stdurl(url: string | URL) { try { url = new URL(url); // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (err) { url = new URL(url, this.url); } return url; } /** * Standardize interactions with the backend API * * @param {URL|String} url - Full URL or API fragment to request * @param {Object} [opts={}] - Options */ async fetch(url: URL, opts: any = {}, raw=false) { url = this.stdurl(url); try { if (!opts.headers) opts.headers = {}; if ( (isPlainObject(opts.body) || Array.isArray(opts.body)) && ( !opts.headers['Content-Type'] || opts.headers['Content-Type'].startsWith('application/json') ) ) { opts.body = JSON.stringify(opts.body); opts.headers['Content-Type'] = 'application/json'; } else if (opts.body instanceof FormData) { opts.headers = opts.body.getHeaders(); } else if (opts.body instanceof URLSearchParams) { opts.headers['Content-Type'] = 'application/x-www-form-urlencoded' opts.body = String(opts.body); } const res = await this.auth.fetch(this, url, opts) if (raw) return res; let bdy: any = {}; if ((res.status < 200 || res.status >= 400)) { try { bdy = await res.text(); } catch (err) { console.error(err); bdy = null; } throw new Err(res.status, null, bdy || `Status Code: ${res.status}`); } if (res.headers.get('content-type') === 'application/json') { return await res.json(); } else { return await res.text(); } } catch (err) { if (err instanceof Error && err.name === 'PublicError') throw err; throw new Err(400, null, err instanceof Error ? err.message : String(err)); } } } function isPlainObject(value: object) { return value?.constructor === Object; }