@tak-ps/node-cot 10.2.0 → 10.4.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/dist/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tak-ps/node-cot",
3
3
  "type": "module",
4
- "version": "10.2.0",
4
+ "version": "10.4.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",
@@ -33,15 +33,15 @@
33
33
  "xml-js": "^1.6.11"
34
34
  },
35
35
  "devDependencies": {
36
- "@types/node": "^20.0.0",
36
+ "@types/node": "^22.0.0",
37
37
  "@types/tape": "^5.6.0",
38
- "eslint": "^8.57.0",
38
+ "eslint": "^9.0.0",
39
39
  "tape": "^5.6.1",
40
40
  "ts-node": "^10.9.1",
41
41
  "ts-node-test": "^0.4.0",
42
42
  "typedoc": "^0.26.0",
43
43
  "typescript": "^5.5.0",
44
- "typescript-eslint": "^7.6.0"
44
+ "typescript-eslint": "^8.0.0"
45
45
  },
46
46
  "repository": {
47
47
  "type": "git",
@@ -116,10 +116,10 @@ test(`DataPackage CoT Parsing: QuickPic.zip`, async (t) => {
116
116
  t.equal(cots.length, 1);
117
117
  const attachments = await pkg.attachments();
118
118
  t.equals(attachments.size, 1);
119
- t.deepEquals(attachments.get('3b758d3c-5b7a-4fba-a0dc-bbde18e895b5'), {
120
- _attributes: { ignore: false, zipEntry: 'e63e920689815c961ec9d873c83f08a6/20240702_144514.jpg' },
121
- Parameter: { _attributes: { name: 'uid', value: '3b758d3c-5b7a-4fba-a0dc-bbde18e895b5' } }
122
- });
119
+ t.deepEquals(attachments.get('3b758d3c-5b7a-4fba-a0dc-bbde18e895b5'), [{
120
+ _attributes: { ignore: false, zipEntry: 'e63e920689815c961ec9d873c83f08a6/20240702_144514.jpg' },
121
+ Parameter: { _attributes: { name: 'uid', value: '3b758d3c-5b7a-4fba-a0dc-bbde18e895b5' } }
122
+ }]);
123
123
  await pkg.destroy();
124
124
  t.end();
125
125
  });
@@ -149,4 +149,37 @@ test(`DataPackage CoT Parsing: addFile,getFile`, async (t) => {
149
149
  await pkg.destroy();
150
150
  t.end();
151
151
  });
152
+ test(`DataPackage CoT Parsing: AttachmentInManifest.zip`, async (t) => {
153
+ const pkg = await DataPackage.parse(new URL('./packages/AttachmentInManifest.zip', import.meta.url).pathname);
154
+ t.equals(await DataPackage.hash(new URL('./packages/QuickPic.zip', import.meta.url).pathname), 'bd13db0f18ccb423833cc21c0678e0224dd15ff504c1f16c43aff03e216b82a7');
155
+ t.equals(pkg.version, '2');
156
+ t.ok(pkg.path);
157
+ t.deepEquals(pkg.settings, {
158
+ uid: 'c7f90966-f048-41fd-8951-70cd9a380cd2',
159
+ name: '1000001544.jpg',
160
+ onReceiveImport: 'true',
161
+ onReceiveDelete: 'true',
162
+ callsign: 'excl 1'
163
+ });
164
+ t.deepEquals(pkg.contents, [
165
+ {
166
+ _attributes: { ignore: false, zipEntry: 'c7f90966-f048-41fd-8951-70cd9a380cd2/c7f90966-f048-41fd-8951-70cd9a380cd2.cot' },
167
+ Parameter: { _attributes: { name: 'uid', value: 'c7f90966-f048-41fd-8951-70cd9a380cd2' } }
168
+ }, {
169
+ _attributes: { ignore: false, zipEntry: '6988443373b26e519cfd1096665b8eaa/1000001544.jpg' },
170
+ Parameter: { _attributes: { name: 'uid', value: 'c7f90966-f048-41fd-8951-70cd9a380cd2' } }
171
+ }
172
+ ]);
173
+ const cots = await pkg.cots();
174
+ t.equal(cots.length, 1);
175
+ t.deepEquals(cots[0].raw.event.detail.attachment_list, ['6988443373b26e519cfd1096665b8eaa']);
176
+ const attachments = await pkg.attachments();
177
+ t.equals(attachments.size, 1);
178
+ t.deepEquals(attachments.get('c7f90966-f048-41fd-8951-70cd9a380cd2'), [{
179
+ _attributes: { ignore: false, zipEntry: '6988443373b26e519cfd1096665b8eaa/1000001544.jpg' },
180
+ Parameter: { _attributes: { name: 'uid', value: 'c7f90966-f048-41fd-8951-70cd9a380cd2' } }
181
+ }]);
182
+ await pkg.destroy();
183
+ t.end();
184
+ });
152
185
  //# sourceMappingURL=data-package.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"data-package.test.js","sourceRoot":"","sources":["../../test/data-package.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"data-package.test.js","sourceRoot":"","sources":["../../test/data-package.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import test from 'tape';
2
+ import CoT from '../index.js';
3
+ test('Decode MultiMissionAircraft CoTs', (t) => {
4
+ const cot = new CoT({ "event": { "_attributes": { "how": "h-g-i-g-o", "type": "t-x-m-c", "version": "2.0", "uid": "f205227b-2e23-40bf-8948-711566116365", "start": "2024-07-17T18:49:03Z", "time": "2024-07-17T18:49:03Z", "stale": "2024-07-17T18:49:23Z" }, "point": { "_attributes": { "ce": "9999999", "le": "9999999", "hae": "0", "lat": "0", "lon": "0" } }, "detail": { "mission": { "_attributes": { "type": "CHANGE", "tool": "public", "name": "2024-07-17 - Lost Hiker", "guid": "4ce8e41d-21e4-4471-a303-09d12bb93bcf", "authorUid": "CN=mesasar-machine-user@ingalls.ca,OU=WILDFIRE,O=CO-TAK" }, "MissionChanges": { "MissionChange": { "contentUid": { "_text": "8fb7b41f-77c5-4537-9a4c-5b7a76a71cb9" }, "creatorUid": { "_text": "CN=mesasar-machine-user@ingalls.ca,OU=WILDFIRE,O=CO-TAK" }, "isFederatedChange": { "_text": "false" }, "missionName": { "_text": "2024-07-17 - Lost Hiker" }, "timestamp": { "_text": "2024-07-17T18:49:03.606Z" }, "type": { "_text": "ADD_CONTENT" }, "details": { "_attributes": { "type": "u-d-p", "callsign": "Third Test", "color": "-65536" }, "location": { "_attributes": { "lat": "39.118611111111115", "lon": "-108.31361111111111" } } } } } } } } });
5
+ if (!cot.raw.event.detail) {
6
+ t.fail('No Detail Section');
7
+ }
8
+ else {
9
+ t.ok(cot.raw.event.detail['_flow-tags_']);
10
+ delete cot.raw.event.detail['_flow-tags_'];
11
+ t.deepEquals({
12
+ id: 'f205227b-2e23-40bf-8948-711566116365',
13
+ type: 'Feature',
14
+ properties: {
15
+ callsign: 'UNKNOWN',
16
+ center: [0, 0, 0],
17
+ type: 't-x-m-c',
18
+ how: 'h-g-i-g-o',
19
+ time: '2024-07-17T18:49:03Z',
20
+ start: '2024-07-17T18:49:03Z',
21
+ stale: '2024-07-17T18:49:23Z',
22
+ mission: {
23
+ type: 'CHANGE',
24
+ tool: 'public',
25
+ name: '2024-07-17 - Lost Hiker',
26
+ guid: '4ce8e41d-21e4-4471-a303-09d12bb93bcf',
27
+ authorUid: 'CN=mesasar-machine-user@ingalls.ca,OU=WILDFIRE,O=CO-TAK',
28
+ missionChanges: [{
29
+ contentUid: '8fb7b41f-77c5-4537-9a4c-5b7a76a71cb9',
30
+ creatorUid: 'CN=mesasar-machine-user@ingalls.ca,OU=WILDFIRE,O=CO-TAK',
31
+ isFederatedChange: 'false',
32
+ missionName: '2024-07-17 - Lost Hiker',
33
+ timestamp: '2024-07-17T18:49:03.606Z',
34
+ type: 'ADD_CONTENT',
35
+ details: {
36
+ type: 'u-d-p',
37
+ callsign: 'Third Test',
38
+ color: '-65536',
39
+ lat: '39.118611111111115',
40
+ lon: '-108.31361111111111'
41
+ }
42
+ }]
43
+ },
44
+ metadata: {}
45
+ },
46
+ geometry: {
47
+ type: 'Point',
48
+ coordinates: [0, 0, 0]
49
+ }
50
+ }, cot.to_geojson());
51
+ }
52
+ t.end();
53
+ });
54
+ //# sourceMappingURL=taskings-mission.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taskings-mission.test.js","sourceRoot":"","sources":["../../test/taskings-mission.test.ts"],"names":[],"mappings":"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"}
package/lib/chat.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import Util from './util.js'
2
2
  import CoT from './cot.js';
3
- import JSONCoT from './types.js';
3
+ import type JSONCoT from './types.js';
4
4
  import { Static } from '@sinclair/typebox';
5
5
  import { randomUUID } from 'node:crypto';
6
6
 
package/lib/cot.ts CHANGED
@@ -3,14 +3,23 @@ import Err from '@openaddresses/batch-error';
3
3
  import { diff } from 'json-diff-ts';
4
4
  import xmljs from 'xml-js';
5
5
  import { Static } from '@sinclair/typebox';
6
- import { Feature, Polygon, InputFeature, FeaturePropertyMission, FeaturePropertyMissionLayer } from './feature.js';
6
+ import type {
7
+ Feature,
8
+ Polygon,
9
+ FeaturePropertyMission,
10
+ FeaturePropertyMissionLayer,
11
+ } from './feature.js';
12
+ import {
13
+ InputFeature,
14
+ } from './feature.js';
7
15
  import { AllGeoJSON } from "@turf/helpers";
8
16
  import PointOnFeature from '@turf/point-on-feature';
9
17
  import Truncate from '@turf/truncate';
10
18
  import Ellipse from '@turf/ellipse';
11
19
  import Util from './util.js';
12
20
  import Color from './color.js';
13
- import JSONCoT, { MartiDest, MartiDestAttributes, Link, LinkAttributes } from './types.js'
21
+ import JSONCoT from './types.js'
22
+ import type { MartiDest, MartiDestAttributes, Link, LinkAttributes } from './types.js'
14
23
  import AJV from 'ajv';
15
24
  import fs from 'fs';
16
25
 
@@ -286,6 +295,7 @@ export default class CoT {
286
295
  cot.event.detail.mission = {
287
296
  _attributes: {
288
297
  type: feature.properties.mission.type,
298
+ guid: feature.properties.mission.guid,
289
299
  tool: feature.properties.mission.tool,
290
300
  name: feature.properties.mission.name,
291
301
  authorUid: feature.properties.mission.authorUid,
@@ -643,6 +653,30 @@ export default class CoT {
643
653
  ...raw.event.detail.mission._attributes
644
654
  };
645
655
 
656
+ if (raw.event.detail.mission && raw.event.detail.mission.MissionChanges) {
657
+ const changes =
658
+ Array.isArray(raw.event.detail.mission.MissionChanges)
659
+ ? raw.event.detail.mission.MissionChanges
660
+ : [ raw.event.detail.mission.MissionChanges ]
661
+
662
+ mission.missionChanges = []
663
+ for (const change of changes) {
664
+ mission.missionChanges.push({
665
+ contentUid: change.MissionChange.contentUid._text,
666
+ creatorUid: change.MissionChange.creatorUid._text,
667
+ isFederatedChange: change.MissionChange.isFederatedChange._text,
668
+ missionName: change.MissionChange.missionName._text,
669
+ timestamp: change.MissionChange.timestamp._text,
670
+ type: change.MissionChange.type._text,
671
+ details: {
672
+ ...change.MissionChange.details._attributes,
673
+ ...change.MissionChange.details.location._attributes
674
+ }
675
+ })
676
+ }
677
+ }
678
+
679
+
646
680
  if (raw.event.detail.mission && raw.event.detail.mission.missionLayer) {
647
681
  const missionLayer: Static<typeof FeaturePropertyMissionLayer> = {};
648
682
 
@@ -797,6 +831,15 @@ export default class CoT {
797
831
  });
798
832
  }
799
833
 
834
+ /**
835
+ * Determines if the CoT message represents a Tasking Message
836
+ *
837
+ * @return {boolean}
838
+ */
839
+ is_tasking(): boolean {
840
+ return !!this.raw.event._attributes.type.match(/^t-/)
841
+ }
842
+
800
843
  /**
801
844
  * Determines if the CoT message represents a Chat Message
802
845
  *
@@ -194,32 +194,61 @@ export class DataPackage {
194
194
 
195
195
  /**
196
196
  * Return CoT objects for all CoT type features in the Data Package
197
+ *
198
+ * CoTs have their `attachment_list` field populated if parseAttachments is set to true.
199
+ * While this field is populated automatically by some ATAK actions such as QuickPic
200
+ other attachment actions do not automatically populate this field other than the link
201
+ provided between a CoT and it's attachment in the MANIFEST file
197
202
  */
198
- async cots(opts = { respectIgnore: true }): Promise<Array<CoT>> {
203
+ async cots(opts = {
204
+ respectIgnore: true,
205
+ parseAttachments: true
206
+ }): Promise<Array<CoT>> {
199
207
  if (this.destroyed) throw new Err(400, null, 'Attempt to access Data Package after it has been destroyed');
200
208
 
209
+ const cotsMap: Map<string, CoT> = new Map();
210
+
201
211
  const cots: CoT[] = [];
202
212
  for (const content of this.contents) {
203
213
  if (path.parse(content._attributes.zipEntry).ext !== '.cot') continue;
204
214
  if (opts.respectIgnore && content._attributes.ignore) continue;
205
215
 
206
- cots.push(new CoT(await fsp.readFile(this.path + '/raw/' + content._attributes.zipEntry)));
216
+ const cot = new CoT(await fsp.readFile(this.path + '/raw/' + content._attributes.zipEntry));
217
+
218
+ cotsMap.set(cot.uid(), cot);
219
+
220
+ cots.push(cot);
207
221
  }
208
222
 
209
- return cots;
210
- }
223
+ if (opts.parseAttachments) {
224
+ const attachments = this.#attachments(cotsMap, {
225
+ respectIgnore: opts.respectIgnore
226
+ });
211
227
 
212
- /**
213
- * Return attachments that are associated in the Manifest with a given CoT
214
- * Note: this does not return files that are not associated with a CoT
215
- */
216
- async attachments(opts = { respectIgnore: true }): Promise<Map<string, Static<typeof ManifestContent>>> {
217
- const cots: Map<string, CoT> = new Map();
218
- for (const cot of await this.cots(opts)) {
219
- cots.set(cot.uid(), cot);
228
+ for (const cot of cots) {
229
+ const attaches = attachments.get(cot.uid());
230
+ if (!attaches) continue;
231
+
232
+ for (const attach of attaches) {
233
+ if (!cot.raw.event.detail.attachment_list) {
234
+ cot.raw.event.detail.attachment_list = [];
235
+ }
236
+
237
+ // Until told otherwise the FileHash appears to always be the directory name
238
+ const hash = path.parse(attach._attributes.zipEntry).dir;
239
+
240
+ if (!cot.raw.event.detail.attachment_list.includes(hash)) {
241
+ cot.raw.event.detail.attachment_list.push(hash)
242
+ }
243
+ }
244
+ }
220
245
  }
221
246
 
222
- const attachments: Map<string, Static<typeof ManifestContent>> = new Map();
247
+ return cots;
248
+ }
249
+
250
+ #attachments(cots: Map<string, CoT>, opts = { respectIgnore: true }): Map<string, Array<Static<typeof ManifestContent>>> {
251
+ const attachments: Map<string, Array<Static<typeof ManifestContent>>> = new Map();
223
252
 
224
253
  for (const content of this.contents) {
225
254
  if (path.parse(content._attributes.zipEntry).ext === '.cot') continue;
@@ -229,7 +258,12 @@ export class DataPackage {
229
258
 
230
259
  for (const param of params) {
231
260
  if (param._attributes.name === 'uid' && cots.has(param._attributes.value)) {
232
- attachments.set(param._attributes.value, content);
261
+ const existing = attachments.get(param._attributes.value);
262
+ if (existing) {
263
+ existing.push(content);
264
+ } else {
265
+ attachments.set(param._attributes.value, [content]);
266
+ }
233
267
  break;
234
268
  }
235
269
  }
@@ -238,6 +272,22 @@ export class DataPackage {
238
272
  return attachments;
239
273
  }
240
274
 
275
+ /**
276
+ * Return attachments that are associated in the Manifest with a given CoT
277
+ * Note: this does not return files that are not associated with a CoT
278
+ */
279
+ async attachments(opts = { respectIgnore: true }): Promise<Map<string, Array<Static<typeof ManifestContent>>>> {
280
+ const cots: Map<string, CoT> = new Map();
281
+ for (const cot of await this.cots({
282
+ respectIgnore: opts.respectIgnore,
283
+ parseAttachments: false
284
+ })) {
285
+ cots.set(cot.uid(), cot);
286
+ }
287
+
288
+ return this.#attachments(cots, opts);
289
+ }
290
+
241
291
  /**
242
292
  * Get any file from a Package
243
293
  */
package/lib/feature.ts CHANGED
@@ -27,12 +27,30 @@ export const FeaturePropertyMissionLayer = Type.Object({
27
27
  uid: Type.Optional(Type.String()),
28
28
  })
29
29
 
30
+ export const FeaturePropertyMissionChange = Type.Object({
31
+ contentUid: Type.String(),
32
+ creatorUid: Type.String(),
33
+ isFederatedChange: Type.String(),
34
+ missionName: Type.String(),
35
+ timestamp: Type.String(),
36
+ type: Type.String(),
37
+ details: Type.Object({
38
+ type: Type.String(),
39
+ callsign: Type.String(),
40
+ color: Type.String(),
41
+ lat: Type.String(),
42
+ lon: Type.String()
43
+ })
44
+ })
45
+
30
46
  export const FeaturePropertyMission = Type.Object({
31
47
  type: Type.Optional(Type.String()),
32
48
  tool: Type.Optional(Type.String()),
49
+ guid: Type.Optional(Type.String()),
33
50
  name: Type.Optional(Type.String()),
34
51
  authorUid: Type.Optional(Type.String()),
35
- missionLayer: Type.Optional(FeaturePropertyMissionLayer)
52
+ missionLayer: Type.Optional(FeaturePropertyMissionLayer),
53
+ missionChanges: Type.Optional(Type.Array(FeaturePropertyMissionChange))
36
54
  });
37
55
 
38
56
  export const InputProperties = Type.Object({
package/lib/fileshare.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import Util from './util.js'
2
2
  import CoT from './cot.js';
3
- import JSONCoT, { FileShareAttributes } from './types.js';
3
+ import type JSONCoT from './types.js';
4
+ import type { FileShareAttributes } from './types.js';
4
5
  import { Static } from '@sinclair/typebox';
5
6
 
6
7
  export class FileShare extends CoT {
package/lib/types.ts CHANGED
@@ -135,6 +135,7 @@ export const MissionAttributes = Type.Object({
135
135
  type: Type.Optional(Type.String()),
136
136
  tool: Type.Optional(Type.String()),
137
137
  name: Type.Optional(Type.String()),
138
+ guid: Type.Optional(Type.String()),
138
139
  authorUid: Type.Optional(Type.String()),
139
140
  });
140
141
 
@@ -145,9 +146,38 @@ export const MissionLayer = Type.Object({
145
146
  uid: Type.Optional(GenericText),
146
147
  })
147
148
 
149
+ export const MissionChangeDetails = Type.Object({
150
+ _attributes: Type.Object({
151
+ type: Type.String(),
152
+ callsign: Type.String(),
153
+ color: Type.String()
154
+ }),
155
+ location: Type.Object({
156
+ _attributes: Type.Object({
157
+ lat: Type.String(),
158
+ lon: Type.String()
159
+ })
160
+ })
161
+ })
162
+
163
+ export const MissionChange = Type.Object({
164
+ contentUid: GenericText,
165
+ creatorUid: GenericText,
166
+ isFederatedChange: GenericText,
167
+ missionName: GenericText,
168
+ timestamp: GenericText,
169
+ type: GenericText,
170
+ details: MissionChangeDetails
171
+ })
172
+
173
+ export const MissionChanges = Type.Object({
174
+ MissionChange: Type.Union([Type.Array(MissionChange), MissionChange])
175
+ })
176
+
148
177
  export const Mission = Type.Object({
149
178
  _attributes: Type.Optional(MissionAttributes),
150
179
  missionLayer: Type.Optional(MissionLayer),
180
+ MissionChanges: Type.Optional(MissionChanges),
151
181
  })
152
182
 
153
183
  export const SensorAttributes = Type.Object({
package/lib/util.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { randomUUID } from 'crypto'
2
2
  import { Static } from '@sinclair/typebox';
3
- import {
3
+ import type {
4
4
  EventAttributes,
5
5
  TrackAttributes,
6
6
  Detail,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tak-ps/node-cot",
3
3
  "type": "module",
4
- "version": "10.2.0",
4
+ "version": "10.4.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",
@@ -33,15 +33,15 @@
33
33
  "xml-js": "^1.6.11"
34
34
  },
35
35
  "devDependencies": {
36
- "@types/node": "^20.0.0",
36
+ "@types/node": "^22.0.0",
37
37
  "@types/tape": "^5.6.0",
38
- "eslint": "^8.57.0",
38
+ "eslint": "^9.0.0",
39
39
  "tape": "^5.6.1",
40
40
  "ts-node": "^10.9.1",
41
41
  "ts-node-test": "^0.4.0",
42
42
  "typedoc": "^0.26.0",
43
43
  "typescript": "^5.5.0",
44
- "typescript-eslint": "^7.6.0"
44
+ "typescript-eslint": "^8.0.0"
45
45
  },
46
46
  "repository": {
47
47
  "type": "git",
@@ -154,10 +154,10 @@ test(`DataPackage CoT Parsing: QuickPic.zip`, async (t) => {
154
154
 
155
155
  t.equals(attachments.size, 1)
156
156
 
157
- t.deepEquals(attachments.get('3b758d3c-5b7a-4fba-a0dc-bbde18e895b5'), {
157
+ t.deepEquals(attachments.get('3b758d3c-5b7a-4fba-a0dc-bbde18e895b5'), [{
158
158
  _attributes: { ignore: false, zipEntry: 'e63e920689815c961ec9d873c83f08a6/20240702_144514.jpg' },
159
159
  Parameter: { _attributes: { name: 'uid', value: '3b758d3c-5b7a-4fba-a0dc-bbde18e895b5' } }
160
- });
160
+ }]);
161
161
 
162
162
  await pkg.destroy();
163
163
 
@@ -201,3 +201,48 @@ test(`DataPackage CoT Parsing: addFile,getFile`, async (t) => {
201
201
 
202
202
  t.end();
203
203
  });
204
+
205
+ test(`DataPackage CoT Parsing: AttachmentInManifest.zip`, async (t) => {
206
+ const pkg = await DataPackage.parse(new URL('./packages/AttachmentInManifest.zip', import.meta.url).pathname);
207
+
208
+ t.equals(await DataPackage.hash(new URL('./packages/QuickPic.zip', import.meta.url).pathname), 'bd13db0f18ccb423833cc21c0678e0224dd15ff504c1f16c43aff03e216b82a7');
209
+
210
+ t.equals(pkg.version, '2');
211
+ t.ok(pkg.path);
212
+ t.deepEquals(pkg.settings, {
213
+ uid: 'c7f90966-f048-41fd-8951-70cd9a380cd2',
214
+ name: '1000001544.jpg',
215
+ onReceiveImport: 'true',
216
+ onReceiveDelete: 'true',
217
+ callsign: 'excl 1'
218
+ });
219
+
220
+ t.deepEquals(pkg.contents, [
221
+ {
222
+ _attributes: { ignore: false, zipEntry: 'c7f90966-f048-41fd-8951-70cd9a380cd2/c7f90966-f048-41fd-8951-70cd9a380cd2.cot' },
223
+ Parameter: { _attributes: { name: 'uid', value: 'c7f90966-f048-41fd-8951-70cd9a380cd2' } }
224
+ }, {
225
+ _attributes: { ignore: false, zipEntry: '6988443373b26e519cfd1096665b8eaa/1000001544.jpg' },
226
+ Parameter: { _attributes: { name: 'uid', value: 'c7f90966-f048-41fd-8951-70cd9a380cd2' } }
227
+ }
228
+ ]);
229
+
230
+ const cots = await pkg.cots();
231
+
232
+ t.equal(cots.length, 1);
233
+
234
+ t.deepEquals(cots[0].raw.event.detail.attachment_list, [ '6988443373b26e519cfd1096665b8eaa' ]);
235
+
236
+ const attachments = await pkg.attachments();
237
+
238
+ t.equals(attachments.size, 1)
239
+
240
+ t.deepEquals(attachments.get('c7f90966-f048-41fd-8951-70cd9a380cd2'), [{
241
+ _attributes: { ignore: false, zipEntry: '6988443373b26e519cfd1096665b8eaa/1000001544.jpg' },
242
+ Parameter: { _attributes: { name: 'uid', value: 'c7f90966-f048-41fd-8951-70cd9a380cd2' } }
243
+ }]);
244
+
245
+ await pkg.destroy();
246
+
247
+ t.end();
248
+ });
@@ -1,5 +1,5 @@
1
1
  import { Static } from '@sinclair/typebox';
2
- import { Feature } from '../lib/feature.js';
2
+ import type { Feature } from '../lib/feature.js';
3
3
  import fs from 'node:fs/promises';
4
4
  import path from 'node:path';
5
5
  import test from 'tape';
@@ -1,5 +1,5 @@
1
1
  import { Static } from '@sinclair/typebox';
2
- import { Feature } from '../lib/feature.js';
2
+ import type { Feature } from '../lib/feature.js';
3
3
  import fs from 'node:fs/promises';
4
4
  import path from 'node:path';
5
5
  import test from 'tape';
@@ -0,0 +1,56 @@
1
+ import test from 'tape';
2
+ import CoT from '../index.js';
3
+
4
+ test('Decode MultiMissionAircraft CoTs', (t) => {
5
+ const cot = new CoT({"event":{"_attributes":{"how":"h-g-i-g-o","type":"t-x-m-c","version":"2.0","uid":"f205227b-2e23-40bf-8948-711566116365","start":"2024-07-17T18:49:03Z","time":"2024-07-17T18:49:03Z","stale":"2024-07-17T18:49:23Z"},"point":{"_attributes":{"ce":"9999999","le":"9999999","hae":"0","lat":"0","lon":"0"}},"detail":{"mission":{"_attributes":{"type":"CHANGE","tool":"public","name":"2024-07-17 - Lost Hiker","guid":"4ce8e41d-21e4-4471-a303-09d12bb93bcf","authorUid":"CN=mesasar-machine-user@ingalls.ca,OU=WILDFIRE,O=CO-TAK"},"MissionChanges":{"MissionChange":{"contentUid":{"_text":"8fb7b41f-77c5-4537-9a4c-5b7a76a71cb9"},"creatorUid":{"_text":"CN=mesasar-machine-user@ingalls.ca,OU=WILDFIRE,O=CO-TAK"},"isFederatedChange":{"_text":"false"},"missionName":{"_text":"2024-07-17 - Lost Hiker"},"timestamp":{"_text":"2024-07-17T18:49:03.606Z"},"type":{"_text":"ADD_CONTENT"},"details":{"_attributes":{"type":"u-d-p","callsign":"Third Test","color":"-65536"},"location":{"_attributes":{"lat":"39.118611111111115","lon":"-108.31361111111111"}}}}}}}}});
6
+
7
+ if (!cot.raw.event.detail) {
8
+ t.fail('No Detail Section')
9
+ } else {
10
+ t.ok(cot.raw.event.detail['_flow-tags_']);
11
+ delete cot.raw.event.detail['_flow-tags_'];
12
+
13
+ t.deepEquals({
14
+ id: 'f205227b-2e23-40bf-8948-711566116365',
15
+ type: 'Feature',
16
+ properties: {
17
+ callsign: 'UNKNOWN',
18
+ center: [ 0, 0, 0 ],
19
+ type: 't-x-m-c',
20
+ how: 'h-g-i-g-o',
21
+ time: '2024-07-17T18:49:03Z',
22
+ start: '2024-07-17T18:49:03Z',
23
+ stale: '2024-07-17T18:49:23Z',
24
+ mission: {
25
+ type: 'CHANGE',
26
+ tool: 'public',
27
+ name: '2024-07-17 - Lost Hiker',
28
+ guid: '4ce8e41d-21e4-4471-a303-09d12bb93bcf',
29
+ authorUid: 'CN=mesasar-machine-user@ingalls.ca,OU=WILDFIRE,O=CO-TAK',
30
+ missionChanges: [{
31
+ contentUid: '8fb7b41f-77c5-4537-9a4c-5b7a76a71cb9',
32
+ creatorUid: 'CN=mesasar-machine-user@ingalls.ca,OU=WILDFIRE,O=CO-TAK',
33
+ isFederatedChange: 'false',
34
+ missionName: '2024-07-17 - Lost Hiker',
35
+ timestamp: '2024-07-17T18:49:03.606Z',
36
+ type: 'ADD_CONTENT',
37
+ details: {
38
+ type: 'u-d-p',
39
+ callsign: 'Third Test',
40
+ color: '-65536',
41
+ lat: '39.118611111111115',
42
+ lon: '-108.31361111111111'
43
+ }
44
+ }]
45
+ },
46
+ metadata: {}
47
+ },
48
+ geometry: {
49
+ type: 'Point',
50
+ coordinates: [ 0, 0, 0 ]
51
+ }
52
+ }, cot.to_geojson());
53
+ }
54
+
55
+ t.end();
56
+ });