@tak-ps/node-cot 12.11.0 → 12.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,6 +6,7 @@ import {
6
6
  GeofenceAttributes,
7
7
  StatusAttributes,
8
8
  PrecisionLocationAttributes,
9
+ VideoConnectionEntryAttributes,
9
10
  MartiDestAttributes,
10
11
  TakVersionAttributes,
11
12
  FileShareAttributes,
@@ -88,7 +89,12 @@ export const InputProperties = Type.Object({
88
89
  attachments: Type.Optional(Type.Array(Type.String())),
89
90
  ackrequest: Type.Optional(ACKRequestAttributes),
90
91
  sensor: Type.Optional(SensorAttributes),
91
- video: Type.Optional(VideoAttributes),
92
+ video: Type.Optional(Type.Composite([
93
+ VideoAttributes,
94
+ Type.Optional(Type.Object({
95
+ connection: Type.Optional(VideoConnectionEntryAttributes)
96
+ }))
97
+ ])),
92
98
  links: Type.Optional(Type.Array(LinkAttributes)),
93
99
  chat: Type.Optional(Type.Object({
94
100
  parent: Type.Optional(Type.String()),
@@ -145,7 +151,12 @@ export const Properties = Type.Object({
145
151
  ackrequest: Type.Optional(ACKRequestAttributes),
146
152
  attachments: Type.Optional(Type.Array(Type.String())),
147
153
  sensor: Type.Optional(SensorAttributes),
148
- video: Type.Optional(VideoAttributes),
154
+ video: Type.Optional(Type.Composite([
155
+ VideoAttributes,
156
+ Type.Optional(Type.Object({
157
+ connection: Type.Optional(VideoConnectionEntryAttributes)
158
+ }))
159
+ ])),
149
160
  links: Type.Optional(Type.Array(LinkAttributes)),
150
161
  chat: Type.Optional(Type.Object({
151
162
  parent: Type.Optional(Type.String()),
@@ -261,6 +261,7 @@ export const Sensor = Type.Object({
261
261
  })
262
262
 
263
263
  export const VideoAttributes = Type.Object({
264
+ uid: Type.Optional(Type.String()),
264
265
  sensor: Type.Optional(Type.String()),
265
266
  spi: Type.Optional(Type.String()),
266
267
  url: Type.Optional(Type.String())
@@ -281,12 +282,12 @@ export const VideoConnectionEntryAttributes = Type.Object({
281
282
  })
282
283
 
283
284
  export const VideoConnectionEntry = Type.Object({
284
- _attributes: Type.Optional(VideoConnectionEntryAttributes)
285
+ _attributes: VideoConnectionEntryAttributes
285
286
  })
286
287
 
287
288
  export const Video = Type.Object({
288
289
  _attributes: Type.Optional(VideoAttributes),
289
- ConnectionEntry: Type.Optional(Type.Union([Type.Array(VideoConnectionEntry), VideoConnectionEntry]))
290
+ ConnectionEntry: Type.Optional(VideoConnectionEntry)
290
291
  })
291
292
 
292
293
  export const GeofenceAttributes = Type.Object({
@@ -391,6 +392,7 @@ export const MartiDestAttributes = Type.Object({
391
392
  callsign: Type.Optional(Type.String()),
392
393
 
393
394
  mission: Type.Optional(Type.String()),
395
+ 'mission-guid': Type.Optional(Type.String()),
394
396
  after: Type.Optional(Type.String()),
395
397
  path: Type.Optional(Type.String())
396
398
  })
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tak-ps/node-cot",
3
3
  "type": "module",
4
- "version": "12.11.0",
4
+ "version": "12.13.0",
5
5
  "description": "Lightweight JavaScript library for parsing and manipulating TAK messages",
6
6
  "author": "Nick Ingalls <nick@ingalls.ca>",
7
7
  "main": "dist/index.js",
@@ -1,6 +1,60 @@
1
1
  import test from 'tape';
2
2
  import CoT from '../index.js';
3
3
 
4
+ test('CoT.addVideo', (t) => {
5
+ const cot = new CoT(`<event version='2.0' uid='0ed16b9e-a0c8-480f-8860-284b9afb2b1d' type='b-m-p-s-p-loc' time='2023-11-15T20:48:16.097Z' start='2023-11-15T20:48:16.097Z' stale='2024-11-14T20:48:16.097Z' how='h-g-i-g-o' access='Undefined'><point lat='38.2089117' lon='-104.6282182' hae='1455.285' ce='9999999.0' le='9999999.0' /></event>`);
6
+
7
+ cot.addVideo({ uid: '123', url: 'https://publicstreamer3.cotrip.org/rtplive/123/playlist.m3u8' })
8
+
9
+ if (!cot.raw.event.detail) {
10
+ throw new Error('Detail Object must be populated');
11
+ }
12
+
13
+ t.ok(cot.raw.event.detail['_flow-tags_']);
14
+ delete cot.raw.event.detail['_flow-tags_'];
15
+
16
+ t.deepEquals(cot.raw, {
17
+ event: {
18
+ _attributes: {
19
+ version: '2.0',
20
+ uid: '0ed16b9e-a0c8-480f-8860-284b9afb2b1d',
21
+ type: 'b-m-p-s-p-loc',
22
+ time: '2023-11-15T20:48:16.097Z',
23
+ start: '2023-11-15T20:48:16.097Z',
24
+ stale: '2024-11-14T20:48:16.097Z',
25
+ how: 'h-g-i-g-o',
26
+ access: 'Undefined'
27
+ },
28
+ point: { _attributes: { lat: '38.2089117', lon: '-104.6282182', hae: '1455.285', ce: '9999999.0', le: '9999999.0' } },
29
+ detail: {
30
+ __video: {
31
+ _attributes: {
32
+ url: 'https://publicstreamer3.cotrip.org/rtplive/123/playlist.m3u8',
33
+ uid: '123'
34
+ },
35
+ ConnectionEntry: {
36
+ _attributes: {
37
+ uid: '123',
38
+ networkTimeout: 12000,
39
+ path: '',
40
+ protocol: 'raw',
41
+ bufferTime: -1,
42
+ address: 'https://publicstreamer3.cotrip.org/rtplive/123/playlist.m3u8',
43
+ port: -1,
44
+ roverPort: -1,
45
+ rtspReliable: 0,
46
+ ignoreEmbeddedKLV: false,
47
+ alias: 'UNKNOWN'
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+ });
54
+
55
+ t.end();
56
+ });
57
+
4
58
  test('Decode MultiMissionAircraft CoTs', (t) => {
5
59
  const cot = new CoT(`<event version='2.0' uid='0ed16b9e-a0c8-480f-8860-284b9afb2b1d' type='b-m-p-s-p-loc' time='2023-11-15T20:48:16.097Z' start='2023-11-15T20:48:16.097Z' stale='2024-11-14T20:48:16.097Z' how='h-g-i-g-o' access='Undefined'><point lat='38.2089117' lon='-104.6282182' hae='1455.285' ce='9999999.0' le='9999999.0' /><detail><status readiness='true'/><archive/><__video uid='05bf6c59-c7ea-465f-8337-da16ddcc82d4' url='https://publicstreamer3.cotrip.org/rtplive/123/playlist.m3u8'><ConnectionEntry networkTimeout='12000' uid='05bf6c59-c7ea-465f-8337-da16ddcc82d4' path='' protocol='raw' bufferTime='-1' address='https://publicstreamer3.cotrip.org/rtplive/123/playlist.m3u8' port='-1' roverPort='-1' rtspReliable='0' ignoreEmbeddedKLV='false' alias='I-25 .8 mi S CO-45'/></__video><color argb='-1'/><link uid='ANDROID-94e13cc4880cbcce' production_time='2022-01-31T17:35:49.565Z' type='a-f-G-U-C' parent_callsign='CO-DFPC-54-Schmidt' relation='p-p'/><sensor vfov='45' elevation='0' fovBlue='1.0' fovRed='1.0' strokeWeight='0.0' roll='0' range='100' azimuth='270' rangeLineStrokeWeight='0.0' fov='45' hideFov='true' rangeLineStrokeColor='-3355444' fovGreen='1.0' displayMagneticReference='0' strokeColor='-16777216' rangeLines='100' fovAlpha='0.2980392156862745'/><archive/><contact callsign='I-25 .8 mi S CO-45'/><remarks></remarks><precisionlocation altsrc='DTED2'/></detail></event>`);
6
60
  if (!cot.raw.event.detail) {
@@ -114,7 +168,23 @@ test('Decode MultiMissionAircraft CoTs', (t) => {
114
168
  rangeLines: 100,
115
169
  fovAlpha: 0.2980392156862745
116
170
  },
117
- video: { uid: '05bf6c59-c7ea-465f-8337-da16ddcc82d4', url: 'https://publicstreamer3.cotrip.org/rtplive/123/playlist.m3u8' },
171
+ video: {
172
+ uid: '05bf6c59-c7ea-465f-8337-da16ddcc82d4',
173
+ url: 'https://publicstreamer3.cotrip.org/rtplive/123/playlist.m3u8',
174
+ connection: {
175
+ "networkTimeout": 12000,
176
+ "uid": "05bf6c59-c7ea-465f-8337-da16ddcc82d4",
177
+ "path": "",
178
+ "protocol": "raw",
179
+ "bufferTime": -1,
180
+ "address": "https://publicstreamer3.cotrip.org/rtplive/123/playlist.m3u8",
181
+ "port": -1,
182
+ "roverPort": -1,
183
+ "rtspReliable": 0,
184
+ "ignoreEmbeddedKLV": false,
185
+ "alias": "I-25 .8 mi S CO-45"
186
+ }
187
+ },
118
188
  archived: true,
119
189
  status: { readiness: 'true' },
120
190
  precisionlocation: { altsrc: 'DTED2' },
@@ -0,0 +1,26 @@
1
+ {
2
+ "id": "123",
3
+ "type": "Feature",
4
+ "properties": {
5
+ "type": "a-f-G",
6
+ "how": "m-g",
7
+ "callsign": "BasicTest",
8
+ "center": [ 1.1, 2.2, 0 ],
9
+ "time": "2023-08-04T15:17:43.649Z",
10
+ "start": "2023-08-04T15:17:43.649Z",
11
+ "stale": "2023-08-04T15:17:43.649Z",
12
+ "video": {
13
+ "uid": "123",
14
+ "url": "rtsp://18.254.132.90:8554/money",
15
+ "connection": {
16
+ "uid": "123",
17
+ "address": "rtsp://18.254.132.90:8554/money"
18
+ }
19
+ },
20
+ "metadata": {}
21
+ },
22
+ "geometry": {
23
+ "type": "Point",
24
+ "coordinates": [1.1, 2.2, 0]
25
+ }
26
+ }
@@ -11,6 +11,7 @@ for (const fixturename of await fs.readdir(new URL('./fixtures/', import.meta.ur
11
11
  const fixture: Static<typeof Feature> = JSON.parse(String(await fs.readFile(path.join(path.parse(fileURLToPath(import.meta.url)).dir, 'fixtures/', fixturename))));
12
12
  const geo = CoT.from_geojson(fixture)
13
13
  const output = geo.to_geojson();
14
+
14
15
  t.deepEquals(fixture, output, fixturename);
15
16
 
16
17
  t.end();