@tak-ps/node-cot 5.4.0 → 5.5.1
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/README.md +6 -5
- package/dist/lib/chat.js.map +1 -1
- package/dist/lib/cot.js +6 -4
- package/dist/lib/cot.js.map +1 -1
- package/dist/lib/types.js +159 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/util.js.map +1 -1
- package/dist/package.json +4 -4
- package/dist/test/chat.test.js +9 -4
- package/dist/test/chat.test.js.map +1 -1
- package/lib/chat.ts +2 -1
- package/lib/cot.ts +17 -12
- package/lib/types.ts +182 -175
- package/lib/util.ts +6 -5
- package/package.json +4 -4
- package/test/chat.test.ts +10 -4
- package/dist/lib/schema.json +0 -544
- package/lib/schema.json +0 -545
package/lib/types.ts
CHANGED
|
@@ -1,177 +1,184 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export
|
|
69
|
-
_attributes: {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
callsign
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
1
|
+
import { Type } from '@sinclair/typebox';
|
|
2
|
+
|
|
3
|
+
export const EventAttributes = Type.Object({
|
|
4
|
+
version: Type.String(),
|
|
5
|
+
uid: Type.String(),
|
|
6
|
+
type: Type.String(),
|
|
7
|
+
how: Type.String(),
|
|
8
|
+
|
|
9
|
+
time: Type.String(),
|
|
10
|
+
stale: Type.String(),
|
|
11
|
+
start: Type.String(),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const TogAttributes = Type.Object({
|
|
15
|
+
_attributes: Type.Optional(Type.Object({
|
|
16
|
+
enabled: Type.Optional(Type.String())
|
|
17
|
+
}))
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
export const LinkAttributes = Type.Object({
|
|
21
|
+
_attributes: Type.Object({
|
|
22
|
+
point: Type.Optional(Type.String()),
|
|
23
|
+
|
|
24
|
+
uid: Type.Optional(Type.String()),
|
|
25
|
+
type: Type.Optional(Type.String()),
|
|
26
|
+
relation: Type.Optional(Type.String()),
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
export const ServerVersionAttributes = Type.Object({
|
|
31
|
+
_attributes: Type.Optional(Type.Object({
|
|
32
|
+
serverVersion: Type.Optional(Type.String())
|
|
33
|
+
}))
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
export const GenericAttributes = Type.Object({
|
|
37
|
+
_attributes: Type.Optional(Type.Object({
|
|
38
|
+
value: Type.Optional(Type.String())
|
|
39
|
+
}))
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
export const TrackAttributes = Type.Object({
|
|
43
|
+
speed: Type.Optional(Type.String()),
|
|
44
|
+
course: Type.Optional(Type.String()),
|
|
45
|
+
slope: Type.Optional(Type.String()),
|
|
46
|
+
eCourse: Type.Optional(Type.String()),
|
|
47
|
+
eSpeed: Type.Optional(Type.String()),
|
|
48
|
+
eSlope: Type.Optional(Type.String())
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
export const Track = Type.Object({
|
|
53
|
+
_attributes: TrackAttributes
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
export const Chat = Type.Object({
|
|
57
|
+
_attributes: Type.Object({
|
|
58
|
+
parent: Type.Optional(Type.String()),
|
|
59
|
+
groupOwner: Type.Optional(Type.String()),
|
|
60
|
+
messageId: Type.Optional(Type.String()),
|
|
61
|
+
chatroom: Type.String(),
|
|
62
|
+
id: Type.String(),
|
|
63
|
+
senderCallsign: Type.String()
|
|
64
|
+
}),
|
|
65
|
+
chatgrp: Type.Any()
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
export const TakVersion = Type.Object({
|
|
69
|
+
_attributes: Type.Object({
|
|
70
|
+
device: Type.Optional(Type.String()),
|
|
71
|
+
platform: Type.Optional(Type.String()),
|
|
72
|
+
os: Type.Optional(Type.String()),
|
|
73
|
+
version: Type.Optional(Type.String())
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
export const FlowTags = Type.Any();
|
|
78
|
+
|
|
79
|
+
export const Group = Type.Object({
|
|
80
|
+
_attributes: Type.Optional(Type.Object({
|
|
81
|
+
name: Type.String(),
|
|
82
|
+
role: Type.String()
|
|
83
|
+
}))
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
export const Status = Type.Object({
|
|
87
|
+
_attributes: Type.Object({
|
|
88
|
+
battery: Type.Optional(Type.String()),
|
|
89
|
+
readiness: Type.Optional(Type.String())
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
export const Uid = Type.Object({
|
|
94
|
+
_attributes: Type.Object({
|
|
95
|
+
Droid: Type.String()
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
export const Contact = Type.Object({
|
|
100
|
+
_attributes: Type.Object({
|
|
101
|
+
phone: Type.Optional(Type.String()),
|
|
102
|
+
callsign: Type.String(),
|
|
103
|
+
endpoint: Type.Optional(Type.String())
|
|
104
|
+
})
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
export const MartiDest = Type.Object({
|
|
108
|
+
_attributes: Type.Object({
|
|
109
|
+
uid: Type.Optional(Type.String()),
|
|
110
|
+
mission: Type.Optional(Type.String()),
|
|
111
|
+
callsign: Type.Optional(Type.String())
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
export const Marti = Type.Object({
|
|
116
|
+
_attributes: Type.Optional(Type.Object({})),
|
|
117
|
+
dest: Type.Optional(Type.Union([MartiDest, Type.Array(MartiDest)]))
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
export const Remarks = Type.Object({
|
|
121
|
+
_attributes: Type.Optional(Type.Object({
|
|
122
|
+
source: Type.Optional(Type.String()),
|
|
123
|
+
to: Type.Optional(Type.String()),
|
|
124
|
+
time: Type.Optional(Type.String())
|
|
125
|
+
})),
|
|
126
|
+
_text: Type.Optional(Type.String())
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
export const PrecisionLocation = Type.Object({
|
|
130
|
+
_attributes: Type.Object({
|
|
131
|
+
geopointsrc: Type.Optional(Type.String()),
|
|
132
|
+
altsrc: Type.Optional(Type.String())
|
|
133
|
+
})
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
export const UserIcon = Type.Object({
|
|
137
|
+
_attributes: Type.Object({
|
|
138
|
+
iconsetpath: Type.String()
|
|
139
|
+
})
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
export const Detail = Type.Object({
|
|
143
|
+
contact: Type.Optional(Contact),
|
|
144
|
+
tog: Type.Optional(TogAttributes),
|
|
145
|
+
'__group': Type.Optional(Group),
|
|
146
|
+
'__chat': Type.Optional(Chat),
|
|
147
|
+
'_flow-tags_': Type.Optional(FlowTags),
|
|
148
|
+
uid: Type.Optional(Uid),
|
|
149
|
+
status: Type.Optional(Status),
|
|
150
|
+
remarks: Type.Optional(Remarks),
|
|
151
|
+
precisionlocation: Type.Optional(PrecisionLocation),
|
|
152
|
+
strokeColor: Type.Optional(GenericAttributes),
|
|
153
|
+
archived: Type.Optional(GenericAttributes),
|
|
154
|
+
strokeWeight: Type.Optional(GenericAttributes),
|
|
155
|
+
strokeStyle: Type.Optional(GenericAttributes),
|
|
156
|
+
labels_on: Type.Optional(GenericAttributes),
|
|
157
|
+
fillColor: Type.Optional(GenericAttributes),
|
|
158
|
+
link: Type.Optional(Type.Union([LinkAttributes, Type.Array(LinkAttributes)])),
|
|
159
|
+
usericon: Type.Optional(UserIcon),
|
|
160
|
+
track: Type.Optional(Track),
|
|
161
|
+
takv: Type.Optional(TakVersion),
|
|
162
|
+
marti: Type.Optional(Marti),
|
|
163
|
+
TakControl: Type.Optional(Type.Object({
|
|
164
|
+
TakServerVersionInfo: Type.Optional(ServerVersionAttributes)
|
|
165
|
+
}))
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
export const Point = Type.Object({
|
|
169
|
+
_attributes: Type.Object({
|
|
170
|
+
lat: Type.Union([Type.String(), Type.Number()]),
|
|
171
|
+
lon: Type.Union([Type.String(), Type.Number()]),
|
|
172
|
+
hae: Type.Union([Type.String(), Type.Number()]),
|
|
173
|
+
ce: Type.Union([Type.String(), Type.Number()]),
|
|
174
|
+
le: Type.Union([Type.String(), Type.Number()]),
|
|
175
|
+
})
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
export default Type.Object({
|
|
179
|
+
event: Type.Object({
|
|
171
180
|
_attributes: EventAttributes,
|
|
172
|
-
detail
|
|
181
|
+
detail: Type.Optional(Detail),
|
|
173
182
|
point: Point,
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
[k: string]: unknown
|
|
177
|
-
}
|
|
183
|
+
}),
|
|
184
|
+
})
|
package/lib/util.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto'
|
|
2
|
-
import
|
|
2
|
+
import { Static } from '@sinclair/typebox';
|
|
3
|
+
import {
|
|
3
4
|
EventAttributes,
|
|
4
5
|
TrackAttributes,
|
|
5
6
|
Detail,
|
|
@@ -26,7 +27,7 @@ export default class Util {
|
|
|
26
27
|
time?: Date | string | null,
|
|
27
28
|
start?: Date | string | null,
|
|
28
29
|
stale?: Date | string | number | null
|
|
29
|
-
): EventAttributes {
|
|
30
|
+
): Static<typeof EventAttributes> {
|
|
30
31
|
if (!type) throw new Error('type param required');
|
|
31
32
|
if (!how) throw new Error('how param required');
|
|
32
33
|
|
|
@@ -44,7 +45,7 @@ export default class Util {
|
|
|
44
45
|
*
|
|
45
46
|
* @param [callsign=UNKNOWN] Display Callsign
|
|
46
47
|
*/
|
|
47
|
-
static cot_event_detail(callsign = 'UNKNOWN'): Detail {
|
|
48
|
+
static cot_event_detail(callsign = 'UNKNOWN'): Static<typeof Detail> {
|
|
48
49
|
return {
|
|
49
50
|
contact: {
|
|
50
51
|
_attributes: { callsign }
|
|
@@ -58,7 +59,7 @@ export default class Util {
|
|
|
58
59
|
* @param [course] Speed in degrees from north
|
|
59
60
|
* @param [speed=0] Speed in m/s
|
|
60
61
|
*/
|
|
61
|
-
static cot_track_attr(course: number, speed = 0): TrackAttributes {
|
|
62
|
+
static cot_track_attr(course: number, speed = 0): Static<typeof TrackAttributes> {
|
|
62
63
|
return {
|
|
63
64
|
course: String(course || 0),
|
|
64
65
|
speed: String(speed || 0)
|
|
@@ -82,7 +83,7 @@ export default class Util {
|
|
|
82
83
|
/**
|
|
83
84
|
* Generate Null Island CoT point object
|
|
84
85
|
*/
|
|
85
|
-
static cot_point(): Point {
|
|
86
|
+
static cot_point(): Static<typeof Point> {
|
|
86
87
|
return {
|
|
87
88
|
'_attributes': {
|
|
88
89
|
'lat': '0.000000',
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tak-ps/node-cot",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.5.1",
|
|
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",
|
|
@@ -10,10 +10,11 @@
|
|
|
10
10
|
"test": "ts-node-test test/",
|
|
11
11
|
"lint": "eslint *.ts lib/*.ts",
|
|
12
12
|
"doc": "typedoc index.ts",
|
|
13
|
-
"build": "
|
|
13
|
+
"build": "tsc --build && cp package.json dist/",
|
|
14
14
|
"pretest": "npm run lint"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
+
"@sinclair/typebox": "^0.32.20",
|
|
17
18
|
"@turf/helpers": "^6.5.0",
|
|
18
19
|
"@turf/point-on-feature": "^6.5.0",
|
|
19
20
|
"@types/color": "^3.0.3",
|
|
@@ -34,8 +35,7 @@
|
|
|
34
35
|
"ts-node": "^10.9.1",
|
|
35
36
|
"ts-node-test": "^0.4.0",
|
|
36
37
|
"typedoc": "^0.25.0",
|
|
37
|
-
"typescript": "^5.0.0"
|
|
38
|
-
"typescript-json-schema": "^0.62.0"
|
|
38
|
+
"typescript": "^5.0.0"
|
|
39
39
|
},
|
|
40
40
|
"repository": {
|
|
41
41
|
"type": "git",
|
package/test/chat.test.ts
CHANGED
|
@@ -25,10 +25,12 @@ test('DirectChat - Basic', (t) => {
|
|
|
25
25
|
t.ok(cot.raw.event.detail['_flow-tags_']);
|
|
26
26
|
delete cot.raw.event.detail['_flow-tags_'];
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
t.equals(typeof cot.raw.event._attributes.time, 'string');
|
|
29
|
+
cot.raw.event._attributes.time = '2024-04-01'
|
|
30
|
+
t.equals(typeof cot.raw.event._attributes.start, 'string');
|
|
31
|
+
cot.raw.event._attributes.start = '2024-04-01'
|
|
32
|
+
t.equals(typeof cot.raw.event._attributes.stale, 'string');
|
|
33
|
+
cot.raw.event._attributes.stale = '2024-04-01'
|
|
32
34
|
|
|
33
35
|
if (!cot.raw.event.detail.__chat) {
|
|
34
36
|
t.fail('No Detail Section')
|
|
@@ -51,6 +53,10 @@ test('DirectChat - Basic', (t) => {
|
|
|
51
53
|
version: '2.0',
|
|
52
54
|
type: 'b-t-f',
|
|
53
55
|
how: 'h-g-i-g-o',
|
|
56
|
+
|
|
57
|
+
time: '2024-04-01',
|
|
58
|
+
stale: '2024-04-01',
|
|
59
|
+
start: '2024-04-01'
|
|
54
60
|
},
|
|
55
61
|
point: {
|
|
56
62
|
_attributes: { lat: '0.000000', lon: '0.000000', hae: '0.0', ce: '9999999.0', le: '9999999.0' }
|