@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.
- package/CHANGELOG.md +8 -0
- package/dist/lib/cot.js +368 -292
- package/dist/lib/cot.js.map +1 -1
- package/dist/lib/types/feature.js +13 -3
- package/dist/lib/types/feature.js.map +1 -1
- package/dist/lib/types/types.js +4 -2
- package/dist/lib/types/types.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/test/cot-video.test.js +65 -1
- package/dist/test/cot-video.test.js.map +1 -1
- package/dist/test/reversal-geojson.test.js.map +1 -1
- package/lib/cot.ts +766 -674
- package/lib/types/feature.ts +13 -2
- package/lib/types/types.ts +4 -2
- package/package.json +1 -1
- package/test/cot-video.test.ts +71 -1
- package/test/fixtures/video-connection.geojson +26 -0
- package/test/reversal-geojson.test.ts +1 -0
package/lib/types/feature.ts
CHANGED
|
@@ -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(
|
|
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(
|
|
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()),
|
package/lib/types/types.ts
CHANGED
|
@@ -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:
|
|
285
|
+
_attributes: VideoConnectionEntryAttributes
|
|
285
286
|
})
|
|
286
287
|
|
|
287
288
|
export const Video = Type.Object({
|
|
288
289
|
_attributes: Type.Optional(VideoAttributes),
|
|
289
|
-
ConnectionEntry: Type.Optional(
|
|
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
package/test/cot-video.test.ts
CHANGED
|
@@ -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: {
|
|
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();
|