UNPKG

@tak-ps/node-tak

Version:

Lightweight JavaScript library for communicating with TAK Server

186 lines (158 loc) 5.52 kB
import Err from '@openaddresses/batch-error'; import type { ParsedArgs } from 'minimist' import { Static, Type } from '@sinclair/typebox'; import { randomUUID } from 'node:crypto'; import Commands, { CommandOutputFormat } from '../commands.js'; export const FeedInput = Type.Object({ uuid: Type.Optional(Type.String()), active: Type.Boolean({ default: true }), alias: Type.String(), url: Type.String(), }); export const VideoConnectionCreateInput = Type.Object({ groups: Type.Optional(Type.Array(Type.String())), uuid: Type.Optional(Type.String()), active: Type.Boolean({ default: true }), alias: Type.String(), feeds: Type.Array(FeedInput) }); export const VideoConnectionUpdateInput = Type.Object({ uuid: Type.Optional(Type.String()), active: Type.Boolean({ default: true }), alias: Type.String(), feeds: Type.Array(FeedInput) }); export const Feed = Type.Object({ uuid: Type.String(), active: Type.Boolean(), alias: Type.String(), url: Type.String(), order: Type.Union([Type.Integer(), Type.Null()]), macAddress: Type.String(), roverPort: Type.String(), ignoreEmbeddedKLV: Type.String(), source: Type.Union([Type.String(), Type.Null()]), networkTimeout: Type.String(), bufferTime: Type.String(), rtspReliable: Type.String(), thumbnail: Type.Union([Type.String(), Type.Null()]), classification: Type.Union([Type.String(), Type.Null()]), latitude: Type.Union([Type.String(), Type.Null()]), longitude: Type.Union([Type.String(), Type.Null()]), fov: Type.Union([Type.String(), Type.Null()]), heading: Type.Union([Type.String(), Type.Null()]), range: Type.Union([Type.String(), Type.Null()]), width: Type.Union([Type.Integer(), Type.Null()]), height: Type.Union([Type.Integer(), Type.Null()]), bitrate: Type.Union([Type.Integer(), Type.Null()]), }); export const VideoConnection = Type.Object({ uuid: Type.String(), active: Type.Boolean(), alias: Type.String(), thumbnail: Type.Union([Type.String(), Type.Null()]), classification: Type.Union([Type.String(), Type.Null()]), feeds: Type.Array(Feed) }) export const VideoConnectionList = Type.Object({ videoConnections: Type.Array(VideoConnection) }); export const VideoConnectionListInput = Type.Object({ protocol: Type.Optional(Type.String()) }) export default class VideoCommands extends Commands { schema = { list: { description: 'List V2 Video Configs', params: Type.Object({}), query: Type.Object({}), formats: [ CommandOutputFormat.JSON ] } } async cli(args: ParsedArgs): Promise<object | string> { if (args._[3] === 'list') { return await this.list() } else { throw new Error('Unsupported Subcommand'); } } async list( query: Static<typeof VideoConnectionListInput> = {} ): Promise<Static<typeof VideoConnectionList>> { const url = new URL(`/Marti/api/video`, this.api.url); let q: keyof Static<typeof VideoConnectionListInput>; for (q in query) { if (query[q] !== undefined) { url.searchParams.append(q, String(query[q])); } } return await this.api.fetch(url, { method: 'GET' }); } async update( connection: Static<typeof VideoConnectionUpdateInput> ): Promise<Static<typeof VideoConnection>> { const url = new URL(`/Marti/api/video/${connection.uuid}`, this.api.url); if (!connection.uuid) throw new Err(400, null, 'UUID must be set when updating Video'); await this.api.fetch(url, { method: 'PUT', body: { ...connection, feeds: connection.feeds.map((feed) => { if (!feed.uuid) feed.uuid = randomUUID(); return feed; }) } }); return await this.get(connection.uuid); } async create( connection: Static<typeof VideoConnectionCreateInput> ): Promise<Static<typeof VideoConnection>> { const url = new URL(`/Marti/api/video`, this.api.url); const uuid = connection.uuid || randomUUID(); if (connection.groups) { for (const group of connection.groups) { url.searchParams.append('group', group); } delete connection.groups; } await this.api.fetch(url, { method: 'POST', body: { videoConnections: [{ uuid, ...connection, feeds: connection.feeds.map((feed) => { return { uuid: randomUUID(), ...feed, } }) }] } }); return await this.get(uuid); } async get( uid: string ): Promise<Static<typeof VideoConnection>> { const url = new URL(`/Marti/api/video/${encodeURIComponent(uid)}`, this.api.url); return await this.api.fetch(url, { method: 'GET' }); } async delete( uid: string ): Promise<void> { const url = new URL(`/Marti/api/video/${encodeURIComponent(uid)}`, this.api.url); await this.api.fetch(url, { method: 'DELETE' }); } }