@tak-ps/node-cot 2.7.0 → 2.8.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/.github/workflows/release.yml +1 -1
- package/CHANGELOG.md +7 -5
- package/lib/util.js +12 -11
- package/lib/xml.js +8 -9
- package/package.json +1 -1
- package/test/from_geojson.test.js +57 -0
- package/test/util.test.js +34 -0
- package/package-lock.json +0 -4266
- package/test/styles.test.js +0 -33
package/CHANGELOG.md
CHANGED
|
@@ -10,14 +10,16 @@
|
|
|
10
10
|
|
|
11
11
|
## Version History
|
|
12
12
|
|
|
13
|
-
### v2.
|
|
13
|
+
### v2.8.1
|
|
14
14
|
|
|
15
|
-
- :
|
|
15
|
+
- :bug: Fix typo in error message
|
|
16
16
|
|
|
17
|
-
### v2.
|
|
17
|
+
### v2.8.0
|
|
18
18
|
|
|
19
|
-
- :
|
|
20
|
-
- :
|
|
19
|
+
- :bug: Significant improvements to start/time/stale parsing
|
|
20
|
+
- :white_check_mark: Add tests for date parsing
|
|
21
|
+
- :rocket: Support parsing `Date` types
|
|
22
|
+
- :arrow_up: General Dep Update
|
|
21
23
|
|
|
22
24
|
### v2.5.0
|
|
23
25
|
|
package/lib/util.js
CHANGED
|
@@ -10,10 +10,13 @@ export default class Util {
|
|
|
10
10
|
*
|
|
11
11
|
* @param {String} type CoT Type
|
|
12
12
|
* @param {String} how CoT how
|
|
13
|
+
* @param {Date|string|null} time Time of CoT Message - if omitted, current time is used
|
|
14
|
+
* @param {Date|string|null} start Start Time of CoT - if omitted, current time is used
|
|
15
|
+
* @param {Date|string|null|numeric} stale Expiration of CoT - if null now+20s is used. Alternative an integer representing the ms offset
|
|
13
16
|
*
|
|
14
17
|
* @returns {Object}
|
|
15
18
|
*/
|
|
16
|
-
static cot_event_attr(type, how) {
|
|
19
|
+
static cot_event_attr(type, how, time, start, stale) {
|
|
17
20
|
if (!type) throw new Error('type param required');
|
|
18
21
|
if (!how) throw new Error('how param required');
|
|
19
22
|
|
|
@@ -22,7 +25,7 @@ export default class Util {
|
|
|
22
25
|
...Util.cot_uuid(),
|
|
23
26
|
type,
|
|
24
27
|
how,
|
|
25
|
-
...Util.cot_date()
|
|
28
|
+
...Util.cot_date(time, start, stale)
|
|
26
29
|
};
|
|
27
30
|
}
|
|
28
31
|
|
|
@@ -85,24 +88,22 @@ export default class Util {
|
|
|
85
88
|
*
|
|
86
89
|
* cot_date() - Time: now, Start: now, Stale: now + 20s
|
|
87
90
|
*
|
|
88
|
-
* @param {Date|null} time Time of CoT Message - if omitted, current time is used
|
|
89
|
-
* @param {Date|null} start Start Time of CoT - if omitted, current time is used
|
|
90
|
-
* @param {Date|null|numeric} stale Expiration of CoT - if null now+20s is used. Alternative an integer representing the
|
|
91
|
+
* @param {Date|string|null} time Time of CoT Message - if omitted, current time is used
|
|
92
|
+
* @param {Date|string|null} start Start Time of CoT - if omitted, current time is used
|
|
93
|
+
* @param {Date|string|null|numeric} stale Expiration of CoT - if null now+20s is used. Alternative an integer representing the ms offset
|
|
91
94
|
*
|
|
92
95
|
* @returns {Object}
|
|
93
96
|
*/
|
|
94
97
|
static cot_date(time, start, stale) {
|
|
95
98
|
const now = Date.now();
|
|
96
99
|
|
|
97
|
-
|
|
98
|
-
|
|
100
|
+
time = new Date(time || now).toISOString();
|
|
101
|
+
start = new Date(start || now).toISOString();
|
|
99
102
|
|
|
100
103
|
if (!stale) {
|
|
101
|
-
stale = new Date(new Date(start)
|
|
104
|
+
stale = new Date(+new Date(start) + 20 * 1000).toISOString();
|
|
102
105
|
} else if (!isNaN(parseInt(stale))) {
|
|
103
|
-
stale = new Date(new Date(start)
|
|
104
|
-
} else if (typeof stale === 'string') {
|
|
105
|
-
stale = new Date(stale).toISOString();
|
|
106
|
+
stale = new Date(+new Date(start) + stale).toISOString();
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
return { time, start, stale };
|
package/lib/xml.js
CHANGED
|
@@ -52,7 +52,13 @@ export default class XMLCot {
|
|
|
52
52
|
|
|
53
53
|
const cot = {
|
|
54
54
|
event: {
|
|
55
|
-
_attributes: Util.cot_event_attr(
|
|
55
|
+
_attributes: Util.cot_event_attr(
|
|
56
|
+
feature.properties.type || 'a-f-G',
|
|
57
|
+
feature.properties.how || 'm-g',
|
|
58
|
+
feature.properties.time,
|
|
59
|
+
feature.properties.start,
|
|
60
|
+
feature.properties.stale
|
|
61
|
+
),
|
|
56
62
|
point: Util.cot_point(),
|
|
57
63
|
detail: Util.cot_event_detail(feature.properties.callsign)
|
|
58
64
|
}
|
|
@@ -61,15 +67,8 @@ export default class XMLCot {
|
|
|
61
67
|
if (feature.id) cot.event._attributes.uid = feature.id;
|
|
62
68
|
if (feature.properties.callsign && !feature.id) cot.event._attributes.uid = feature.properties.callsign;
|
|
63
69
|
|
|
64
|
-
for (const key of ['type', 'how']) {
|
|
65
|
-
if (feature.properties[key]) cot.event._attributes[key] = feature.properties[key];
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const dts = Util.cot_date(feature.properties.time, feature.properties.start, feature.properties.stale);
|
|
69
|
-
Object.assign(cot.event._attributes, dts);
|
|
70
|
-
|
|
71
70
|
if (!feature.geometry) throw new Error('Must have Geometry');
|
|
72
|
-
if (!['Point', 'Polygon', 'LineString'].includes(feature.geometry.type)) throw new Error('Unsupported
|
|
71
|
+
if (!['Point', 'Polygon', 'LineString'].includes(feature.geometry.type)) throw new Error('Unsupported Geometry Type');
|
|
73
72
|
|
|
74
73
|
if (feature.geometry.type === 'Point') {
|
|
75
74
|
cot.event.point._attributes.lon = feature.geometry.coordinates[0];
|
package/package.json
CHANGED
|
@@ -123,3 +123,60 @@ test('XML.from_geojson - LineString', (t) => {
|
|
|
123
123
|
|
|
124
124
|
t.end();
|
|
125
125
|
});
|
|
126
|
+
|
|
127
|
+
test('XML.from_geojson - Start', (t) => {
|
|
128
|
+
const geo = XML.from_geojson({
|
|
129
|
+
type: 'Feature',
|
|
130
|
+
properties: {
|
|
131
|
+
// 1hr in the future
|
|
132
|
+
start: new Date(+new Date() + 60 * 60 * 1000)
|
|
133
|
+
},
|
|
134
|
+
geometry: {
|
|
135
|
+
type: 'Point',
|
|
136
|
+
coordinates: [1.1, 2.2]
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Approx +/- 100ms + 1hr ahead of Now
|
|
141
|
+
t.ok(+new Date(geo.raw.event._attributes.start) > +new Date() + 60 * 60 * 1000 - 100);
|
|
142
|
+
t.ok(+new Date(geo.raw.event._attributes.start) < +new Date() + 60 * 60 * 1000 + 100);
|
|
143
|
+
|
|
144
|
+
// Approx +/- 100ms ahead of Now
|
|
145
|
+
t.ok(+new Date(geo.raw.event._attributes.time) > +new Date() - 100);
|
|
146
|
+
t.ok(+new Date(geo.raw.event._attributes.time) < +new Date() + 100);
|
|
147
|
+
|
|
148
|
+
// Approx +/- 100ms +1hr20s ahead of now
|
|
149
|
+
t.ok(+new Date(geo.raw.event._attributes.stale) > +new Date(geo.raw.event._attributes.start) - 100 + 20 * 1000);
|
|
150
|
+
t.ok(+new Date(geo.raw.event._attributes.stale) < +new Date(geo.raw.event._attributes.start) + 100 + 20 * 1000);
|
|
151
|
+
|
|
152
|
+
t.end();
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test('XML.from_geojson - Start/Stale', (t) => {
|
|
156
|
+
const geo = XML.from_geojson({
|
|
157
|
+
type: 'Feature',
|
|
158
|
+
properties: {
|
|
159
|
+
// 1hr in the future
|
|
160
|
+
start: new Date(+new Date() + 60 * 60 * 1000),
|
|
161
|
+
stale: 60 * 1000
|
|
162
|
+
},
|
|
163
|
+
geometry: {
|
|
164
|
+
type: 'Point',
|
|
165
|
+
coordinates: [1.1, 2.2]
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Approx +/- 100ms + 1hr ahead of Now
|
|
170
|
+
t.ok(+new Date(geo.raw.event._attributes.start) > +new Date() + 60 * 60 * 1000 - 100);
|
|
171
|
+
t.ok(+new Date(geo.raw.event._attributes.start) < +new Date() + 60 * 60 * 1000 + 100);
|
|
172
|
+
|
|
173
|
+
// Approx +/- 100ms ahead of Now
|
|
174
|
+
t.ok(+new Date(geo.raw.event._attributes.time) > +new Date() - 100);
|
|
175
|
+
t.ok(+new Date(geo.raw.event._attributes.time) < +new Date() + 100);
|
|
176
|
+
|
|
177
|
+
// Approx +/- 100ms +1hr60s ahead of now
|
|
178
|
+
t.ok(+new Date(geo.raw.event._attributes.stale) > +new Date(geo.raw.event._attributes.start) - 100 + 60 * 1000);
|
|
179
|
+
t.ok(+new Date(geo.raw.event._attributes.stale) < +new Date(geo.raw.event._attributes.start) + 100 + 60 * 1000);
|
|
180
|
+
|
|
181
|
+
t.end();
|
|
182
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
import Util from '../lib/util.js';
|
|
3
|
+
|
|
4
|
+
test('Util.cot_date - default', (t) => {
|
|
5
|
+
const res = Util.cot_date();
|
|
6
|
+
|
|
7
|
+
// Within 100ms of current time
|
|
8
|
+
t.ok(+new Date(res.time) > +new Date() - 100, 'res.time within 100ms of current time');
|
|
9
|
+
|
|
10
|
+
// res.start is the same as res.time
|
|
11
|
+
t.equals(+new Date(res.start), +new Date(res.time), 'by default res.start === res.time');
|
|
12
|
+
|
|
13
|
+
// Approx 20s ahead of start
|
|
14
|
+
t.ok(+new Date(res.stale) > +new Date(res.start) + 20 * 1000 - 100);
|
|
15
|
+
t.ok(+new Date(res.stale) < +new Date(res.start) + 20 * 1000 + 100);
|
|
16
|
+
|
|
17
|
+
t.end();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('Util.cot_date - stale', (t) => {
|
|
21
|
+
const res = Util.cot_date(null, null, 1000);
|
|
22
|
+
|
|
23
|
+
// Within 100ms of current time
|
|
24
|
+
t.ok(+new Date(res.time) > +new Date() - 100, 'res.time within 100ms of current time');
|
|
25
|
+
|
|
26
|
+
// res.start is the same as res.time
|
|
27
|
+
t.equals(+new Date(res.start), +new Date(res.time), 'by default res.start === res.time');
|
|
28
|
+
|
|
29
|
+
// Approx 1s ahead of start
|
|
30
|
+
t.ok(+new Date(res.stale) > +new Date(res.start) + 1 * 1000 - 100);
|
|
31
|
+
t.ok(+new Date(res.stale) < +new Date(res.start) + 1 * 1000 + 100);
|
|
32
|
+
|
|
33
|
+
t.end();
|
|
34
|
+
});
|