@tak-ps/node-cot 14.30.0 → 14.31.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 CHANGED
@@ -12,6 +12,15 @@
12
12
 
13
13
  ### Pending Fixed
14
14
 
15
+ ### v14.31.0 - 2025-03-26
16
+
17
+ - :tada: Introduce basic validation CLI
18
+ - :rocket: Normalize `False`/`True` boolean values to actual booleans when parsing XML
19
+
20
+ ### v14.30.1 - 2025-03-18
21
+
22
+ - :tada: Retain Non-TAK Server Flow Tags
23
+
15
24
  ### v14.30.0 - 2025-03-18
16
25
 
17
26
  - :tada: Add the ability to reset flow tags
package/cli.ts ADDED
@@ -0,0 +1,220 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ import fs from 'node:fs/promises'
4
+ import path from 'node:path'
5
+ import { CoTParser, DataPackage } from './index.js'
6
+
7
+ type CommandHandler = (args: string[]) => Promise<void>
8
+
9
+ interface PackageIssue {
10
+ entry: string;
11
+ uid?: string;
12
+ error: string;
13
+ }
14
+
15
+ function usage(): string {
16
+ return [
17
+ 'Usage:',
18
+ ' ./cli.ts package validate <file>.zip',
19
+ ' ./cli.ts feature convert <input.geojson|input.cot>'
20
+ ].join('\n')
21
+ }
22
+
23
+ function getErrorMessage(err: unknown): string {
24
+ if (err instanceof Error) return err.message;
25
+
26
+ return String(err);
27
+ }
28
+
29
+ async function withoutConsoleWarn<T>(fn: () => Promise<T> | T): Promise<T> {
30
+ const warn = console.warn;
31
+ console.warn = () => undefined;
32
+
33
+ try {
34
+ return await fn();
35
+ } finally {
36
+ console.warn = warn;
37
+ }
38
+ }
39
+
40
+ function extractUID(raw: string): string | undefined {
41
+ const match = raw.match(/<event\b[^>]*\buid=(['"])([^'"]+)\1/i);
42
+
43
+ return match?.[2];
44
+ }
45
+
46
+ function isJSONInput(inputPath: string, raw: string): boolean {
47
+ const ext = path.extname(inputPath).toLowerCase();
48
+
49
+ if (ext === '.geojson' || ext === '.json') return true;
50
+
51
+ return raw.trimStart().startsWith('{');
52
+ }
53
+
54
+ function normalizeGeoJSON(input: unknown): Record<string, unknown> {
55
+ if (!input || typeof input !== 'object' || Array.isArray(input)) {
56
+ throw new Error('GeoJSON input must be an object');
57
+ }
58
+
59
+ const geojson = input as Record<string, unknown>;
60
+
61
+ if (geojson.type === 'Feature') {
62
+ return geojson;
63
+ }
64
+
65
+ if (geojson.type === 'FeatureCollection') {
66
+ const features = geojson.features;
67
+
68
+ if (!Array.isArray(features) || features.length !== 1) {
69
+ throw new Error('FeatureCollection input must contain exactly one feature');
70
+ }
71
+
72
+ const [feature] = features;
73
+ if (!feature || typeof feature !== 'object' || Array.isArray(feature)) {
74
+ throw new Error('FeatureCollection contains an invalid feature');
75
+ }
76
+
77
+ return feature as Record<string, unknown>;
78
+ }
79
+
80
+ throw new Error('GeoJSON input must be a Feature or a single-feature FeatureCollection');
81
+ }
82
+
83
+ async function validatePackage(inputPath: string): Promise<void> {
84
+ const resolved = path.resolve(inputPath);
85
+ let pkg: DataPackage | undefined;
86
+
87
+ try {
88
+ pkg = await withoutConsoleWarn(async () => {
89
+ return await DataPackage.parse(resolved, {
90
+ cleanup: false,
91
+ strict: true
92
+ });
93
+ });
94
+
95
+ const issues: PackageIssue[] = [];
96
+
97
+ for (const content of pkg.contents) {
98
+ const entry = content._attributes.zipEntry;
99
+ const buffer = await pkg.getFileBuffer(entry);
100
+
101
+ if (path.extname(entry).toLowerCase() !== '.cot') continue;
102
+
103
+ const raw = buffer.toString('utf8');
104
+ try {
105
+ await withoutConsoleWarn(() => CoTParser.from_xml(raw));
106
+ } catch (err) {
107
+ issues.push({
108
+ entry,
109
+ uid: extractUID(raw),
110
+ error: getErrorMessage(err)
111
+ });
112
+ }
113
+ }
114
+
115
+ if (issues.length) {
116
+ console.error(JSON.stringify({
117
+ valid: false,
118
+ package: resolved,
119
+ errors: issues
120
+ }, null, 4));
121
+
122
+ process.exitCode = 1;
123
+ return;
124
+ }
125
+
126
+ const cots = await pkg.cots({
127
+ respectIgnore: false,
128
+ parseAttachments: true
129
+ });
130
+
131
+ const attachments = await pkg.attachments({
132
+ respectIgnore: false
133
+ });
134
+
135
+ const files = await pkg.files({
136
+ respectIgnore: false
137
+ });
138
+
139
+ const attachmentCount = Array.from(attachments.values())
140
+ .reduce((sum, entries) => sum + entries.length, 0);
141
+
142
+ console.log(JSON.stringify({
143
+ valid: true,
144
+ package: resolved,
145
+ manifest: pkg.settings,
146
+ counts: {
147
+ contents: pkg.contents.length,
148
+ cots: cots.length,
149
+ attachments: attachmentCount,
150
+ files: files.size
151
+ }
152
+ }, null, 4));
153
+ } finally {
154
+ if (pkg) {
155
+ await pkg.destroy();
156
+ }
157
+ }
158
+ }
159
+
160
+ async function convertFeature(inputPath: string): Promise<void> {
161
+ const resolved = path.resolve(inputPath);
162
+ const raw = await fs.readFile(resolved, 'utf8');
163
+
164
+ if (isJSONInput(resolved, raw)) {
165
+ const feature = normalizeGeoJSON(JSON.parse(raw));
166
+ const cot = await withoutConsoleWarn(async () => {
167
+ return await CoTParser.from_geojson(feature as never);
168
+ });
169
+ const xml = CoTParser.to_xml(cot);
170
+
171
+ await withoutConsoleWarn(() => CoTParser.from_xml(xml));
172
+ process.stdout.write(`${xml}\n`);
173
+ return;
174
+ }
175
+
176
+ const cot = await withoutConsoleWarn(() => CoTParser.from_xml(raw));
177
+ const feature = await CoTParser.to_geojson(cot);
178
+
179
+ process.stdout.write(`${JSON.stringify(feature, null, 4)}\n`);
180
+ }
181
+
182
+ const commands: Record<string, CommandHandler> = {
183
+ 'package validate': async (args) => {
184
+ if (args.length !== 1) {
185
+ throw new Error('package validate requires a single .zip file path');
186
+ }
187
+
188
+ await validatePackage(args[0]);
189
+ },
190
+ 'feature convert': async (args) => {
191
+ if (args.length !== 1) {
192
+ throw new Error('feature convert requires a single input path');
193
+ }
194
+
195
+ await convertFeature(args[0]);
196
+ }
197
+ }
198
+
199
+ try {
200
+ const args = process.argv.slice(2);
201
+
202
+ if (!args.length || args.includes('--help') || args.includes('-h')) {
203
+ console.log(usage());
204
+ process.exit(0);
205
+ }
206
+
207
+ const commandKey = args.slice(0, 2).join(' ');
208
+ const handler = commands[commandKey];
209
+
210
+ if (!handler) {
211
+ throw new Error(`Unknown command: ${args.join(' ')}`);
212
+ }
213
+
214
+ await handler(args.slice(2));
215
+ } catch (err) {
216
+ console.error(getErrorMessage(err));
217
+ console.error('');
218
+ console.error(usage());
219
+ process.exit(1);
220
+ }
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env tsx
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env tsx
2
+ import fs from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { CoTParser, DataPackage } from './index.js';
5
+ function usage() {
6
+ return [
7
+ 'Usage:',
8
+ ' ./cli.ts package validate <file>.zip',
9
+ ' ./cli.ts feature convert <input.geojson|input.cot>'
10
+ ].join('\n');
11
+ }
12
+ function getErrorMessage(err) {
13
+ if (err instanceof Error)
14
+ return err.message;
15
+ return String(err);
16
+ }
17
+ async function withoutConsoleWarn(fn) {
18
+ const warn = console.warn;
19
+ console.warn = () => undefined;
20
+ try {
21
+ return await fn();
22
+ }
23
+ finally {
24
+ console.warn = warn;
25
+ }
26
+ }
27
+ function extractUID(raw) {
28
+ const match = raw.match(/<event\b[^>]*\buid=(['"])([^'"]+)\1/i);
29
+ return match?.[2];
30
+ }
31
+ function isJSONInput(inputPath, raw) {
32
+ const ext = path.extname(inputPath).toLowerCase();
33
+ if (ext === '.geojson' || ext === '.json')
34
+ return true;
35
+ return raw.trimStart().startsWith('{');
36
+ }
37
+ function normalizeGeoJSON(input) {
38
+ if (!input || typeof input !== 'object' || Array.isArray(input)) {
39
+ throw new Error('GeoJSON input must be an object');
40
+ }
41
+ const geojson = input;
42
+ if (geojson.type === 'Feature') {
43
+ return geojson;
44
+ }
45
+ if (geojson.type === 'FeatureCollection') {
46
+ const features = geojson.features;
47
+ if (!Array.isArray(features) || features.length !== 1) {
48
+ throw new Error('FeatureCollection input must contain exactly one feature');
49
+ }
50
+ const [feature] = features;
51
+ if (!feature || typeof feature !== 'object' || Array.isArray(feature)) {
52
+ throw new Error('FeatureCollection contains an invalid feature');
53
+ }
54
+ return feature;
55
+ }
56
+ throw new Error('GeoJSON input must be a Feature or a single-feature FeatureCollection');
57
+ }
58
+ async function validatePackage(inputPath) {
59
+ const resolved = path.resolve(inputPath);
60
+ let pkg;
61
+ try {
62
+ pkg = await withoutConsoleWarn(async () => {
63
+ return await DataPackage.parse(resolved, {
64
+ cleanup: false,
65
+ strict: true
66
+ });
67
+ });
68
+ const issues = [];
69
+ for (const content of pkg.contents) {
70
+ const entry = content._attributes.zipEntry;
71
+ const buffer = await pkg.getFileBuffer(entry);
72
+ if (path.extname(entry).toLowerCase() !== '.cot')
73
+ continue;
74
+ const raw = buffer.toString('utf8');
75
+ try {
76
+ await withoutConsoleWarn(() => CoTParser.from_xml(raw));
77
+ }
78
+ catch (err) {
79
+ issues.push({
80
+ entry,
81
+ uid: extractUID(raw),
82
+ error: getErrorMessage(err)
83
+ });
84
+ }
85
+ }
86
+ if (issues.length) {
87
+ console.error(JSON.stringify({
88
+ valid: false,
89
+ package: resolved,
90
+ errors: issues
91
+ }, null, 4));
92
+ process.exitCode = 1;
93
+ return;
94
+ }
95
+ const cots = await pkg.cots({
96
+ respectIgnore: false,
97
+ parseAttachments: true
98
+ });
99
+ const attachments = await pkg.attachments({
100
+ respectIgnore: false
101
+ });
102
+ const files = await pkg.files({
103
+ respectIgnore: false
104
+ });
105
+ const attachmentCount = Array.from(attachments.values())
106
+ .reduce((sum, entries) => sum + entries.length, 0);
107
+ console.log(JSON.stringify({
108
+ valid: true,
109
+ package: resolved,
110
+ manifest: pkg.settings,
111
+ counts: {
112
+ contents: pkg.contents.length,
113
+ cots: cots.length,
114
+ attachments: attachmentCount,
115
+ files: files.size
116
+ }
117
+ }, null, 4));
118
+ }
119
+ finally {
120
+ if (pkg) {
121
+ await pkg.destroy();
122
+ }
123
+ }
124
+ }
125
+ async function convertFeature(inputPath) {
126
+ const resolved = path.resolve(inputPath);
127
+ const raw = await fs.readFile(resolved, 'utf8');
128
+ if (isJSONInput(resolved, raw)) {
129
+ const feature = normalizeGeoJSON(JSON.parse(raw));
130
+ const cot = await withoutConsoleWarn(async () => {
131
+ return await CoTParser.from_geojson(feature);
132
+ });
133
+ const xml = CoTParser.to_xml(cot);
134
+ await withoutConsoleWarn(() => CoTParser.from_xml(xml));
135
+ process.stdout.write(`${xml}\n`);
136
+ return;
137
+ }
138
+ const cot = await withoutConsoleWarn(() => CoTParser.from_xml(raw));
139
+ const feature = await CoTParser.to_geojson(cot);
140
+ process.stdout.write(`${JSON.stringify(feature, null, 4)}\n`);
141
+ }
142
+ const commands = {
143
+ 'package validate': async (args) => {
144
+ if (args.length !== 1) {
145
+ throw new Error('package validate requires a single .zip file path');
146
+ }
147
+ await validatePackage(args[0]);
148
+ },
149
+ 'feature convert': async (args) => {
150
+ if (args.length !== 1) {
151
+ throw new Error('feature convert requires a single input path');
152
+ }
153
+ await convertFeature(args[0]);
154
+ }
155
+ };
156
+ try {
157
+ const args = process.argv.slice(2);
158
+ if (!args.length || args.includes('--help') || args.includes('-h')) {
159
+ console.log(usage());
160
+ process.exit(0);
161
+ }
162
+ const commandKey = args.slice(0, 2).join(' ');
163
+ const handler = commands[commandKey];
164
+ if (!handler) {
165
+ throw new Error(`Unknown command: ${args.join(' ')}`);
166
+ }
167
+ await handler(args.slice(2));
168
+ }
169
+ catch (err) {
170
+ console.error(getErrorMessage(err));
171
+ console.error('');
172
+ console.error(usage());
173
+ process.exit(1);
174
+ }
175
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export type ParsedAttributeVisitor = (attributeKey: string, attributeValue: unknown, attributes: Record<string, unknown>, path: string[]) => void;
2
+ export declare function visitElementAttributes(input: unknown, visitor: ParsedAttributeVisitor, path?: string[]): void;
3
+ export declare function normalizeBooleanAttributeValues(input: unknown): void;
@@ -0,0 +1,38 @@
1
+ export function visitElementAttributes(input, visitor, path = []) {
2
+ if (Array.isArray(input)) {
3
+ for (const [index, value] of input.entries()) {
4
+ visitElementAttributes(value, visitor, [...path, String(index)]);
5
+ }
6
+ return;
7
+ }
8
+ if (!input || typeof input !== 'object') {
9
+ return;
10
+ }
11
+ const record = input;
12
+ for (const [key, value] of Object.entries(record)) {
13
+ if (key === '_attributes' && value && typeof value === 'object' && !Array.isArray(value)) {
14
+ const attributes = value;
15
+ for (const [attributeKey, attributeValue] of Object.entries(attributes)) {
16
+ visitor(attributeKey, attributeValue, attributes, [...path, key]);
17
+ visitElementAttributes(attributes[attributeKey], visitor, [...path, key, attributeKey]);
18
+ }
19
+ continue;
20
+ }
21
+ visitElementAttributes(value, visitor, [...path, key]);
22
+ }
23
+ }
24
+ export function normalizeBooleanAttributeValues(input) {
25
+ visitElementAttributes(input, (attributeKey, attributeValue, attributes) => {
26
+ if (typeof attributeValue !== 'string') {
27
+ return;
28
+ }
29
+ const normalized = attributeValue.toLowerCase();
30
+ if (normalized === 'true') {
31
+ attributes[attributeKey] = true;
32
+ }
33
+ else if (normalized === 'false') {
34
+ attributes[attributeKey] = false;
35
+ }
36
+ });
37
+ }
38
+ //# sourceMappingURL=parser-normalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser-normalize.js","sourceRoot":"","sources":["../../lib/parser-normalize.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,sBAAsB,CAClC,KAAc,EACd,OAA+B,EAC/B,OAAiB,EAAE;IAEnB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YAC3C,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACrE,CAAC;QAED,OAAO;IACX,CAAC;IAED,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO;IACX,CAAC;IAED,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,IAAI,GAAG,KAAK,aAAa,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACvF,MAAM,UAAU,GAAG,KAAgC,CAAC;YAEpD,KAAK,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBACtE,OAAO,CAAC,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;gBAClE,sBAAsB,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC;YAC5F,CAAC;YAED,SAAS;QACb,CAAC;QAED,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3D,CAAC;AACL,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,KAAc;IAC1D,sBAAsB,CAAC,KAAK,EAAE,CAAC,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,EAAE;QACvE,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE,CAAC;YACrC,OAAO;QACX,CAAC;QAED,MAAM,UAAU,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC;QAChD,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;YACxB,UAAU,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;QACpC,CAAC;aAAM,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;YAChC,UAAU,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC;QACrC,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -6,6 +6,7 @@ import { from_geojson } from './parser/from_geojson.js';
6
6
  import { normalize_geojson } from './parser/normalize_geojson.js';
7
7
  import { to_geojson } from './parser/to_geojson.js';
8
8
  import { InputFeature, } from './types/feature.js';
9
+ import { normalizeBooleanAttributeValues } from './parser-normalize.js';
9
10
  import JSONCoT, { Detail } from './types/types.js';
10
11
  import CoT from './cot.js';
11
12
  import AJV from 'ajv';
@@ -21,6 +22,27 @@ const checkXML = (new AJV({
21
22
  allowUnionTypes: true
22
23
  }))
23
24
  .compile(JSONCoT);
25
+ function resetFlowTags(cot) {
26
+ const flowTags = cot.raw.event.detail?.['_flow-tags_'];
27
+ if (!flowTags || typeof flowTags !== 'object' || Array.isArray(flowTags)) {
28
+ return;
29
+ }
30
+ const stripServerFlowTags = (tags) => {
31
+ for (const key of Object.keys(tags)) {
32
+ if (key !== '_attributes' && key.startsWith('TAK-Server')) {
33
+ delete tags[key];
34
+ }
35
+ }
36
+ };
37
+ stripServerFlowTags(flowTags);
38
+ if ('_attributes' in flowTags
39
+ && flowTags._attributes
40
+ && typeof flowTags._attributes === 'object'
41
+ && !Array.isArray(flowTags._attributes)) {
42
+ stripServerFlowTags(flowTags._attributes);
43
+ }
44
+ flowTags[`NodeCoT-${pkg.version}`] = new Date().toISOString();
45
+ }
24
46
  /**
25
47
  * Convert to and from an XML CoT message
26
48
  * @class
@@ -86,15 +108,14 @@ export class CoTParser {
86
108
  return diffs.length > 0;
87
109
  }
88
110
  static from_xml(raw, opts = {}) {
89
- const cot = new CoT(xml2js(String(raw), { compact: true }), opts);
111
+ const parsed = xml2js(String(raw), { compact: true });
112
+ normalizeBooleanAttributeValues(parsed);
113
+ const cot = new CoT(parsed, opts);
90
114
  return this.validate(cot);
91
115
  }
92
116
  static to_xml(cot, opts) {
93
117
  if (opts?.resetFlow) {
94
- if (cot.raw.event.detail && cot.raw.event.detail['_flow-tags_']) {
95
- cot.raw.event.detail['_flow-tags_'] = {};
96
- cot.raw.event.detail['_flow-tags_'][`NodeCoT-${pkg.version}`] = new Date().toISOString();
97
- }
118
+ resetFlowTags(cot);
98
119
  }
99
120
  return js2xml(cot.raw, { compact: true });
100
121
  }
@@ -106,10 +127,7 @@ export class CoTParser {
106
127
  throw new Err(400, null, `Unsupported Proto Version: ${version}`);
107
128
  const ProtoMessage = RootMessage.lookupType(`atakmap.commoncommo.protobuf.v${version}.TakMessage`);
108
129
  if (opts?.resetFlow) {
109
- if (cot.raw.event.detail && cot.raw.event.detail['_flow-tags_']) {
110
- cot.raw.event.detail['_flow-tags_'] = {};
111
- cot.raw.event.detail['_flow-tags_'][`NodeCoT-${pkg.version}`] = new Date().toISOString();
112
- }
130
+ resetFlowTags(cot);
113
131
  }
114
132
  // The spread operator is important to make sure the delete doesn't modify the underlying detail object
115
133
  const detail = { ...cot.raw.event.detail };
@@ -158,6 +176,7 @@ export class CoTParser {
158
176
  for (const key in msg.cotEvent.detail) {
159
177
  if (key === 'xmlDetail') {
160
178
  const parsed = xml2js(`<detail>${msg.cotEvent.detail.xmlDetail}</detail>`, { compact: true });
179
+ normalizeBooleanAttributeValues(parsed);
161
180
  Object.assign(detail, parsed.detail);
162
181
  if (detail.metadata) {
163
182
  for (const key in detail.metadata) {
@@ -1 +1 @@
1
- {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../lib/parser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../lib/parser.ts"],"names":[],"mappings":"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"}
package/dist/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@tak-ps/node-cot",
3
3
  "type": "module",
4
- "version": "14.30.0",
4
+ "version": "14.31.0",
5
5
  "description": "Lightweight JavaScript library for parsing and manipulating TAK messages",
6
6
  "author": "Nick Ingalls <nick@ingalls.ca>",
7
7
  "types": "index.ts",
8
+ "bin": {
9
+ "cot": "./cli.ts"
10
+ },
8
11
  "exports": {
9
12
  ".": {
10
13
  "types": "./dist/index.d.ts",
@@ -1 +1 @@
1
- {"root":["../index.ts","../test/2525.test.ts","../test/basemaps.test.ts","../test/basic.test.ts","../test/chat.test.ts","../test/cot-emergency.test.ts","../test/cot-fileshare.test.ts","../test/cot-itak.test.ts","../test/cot-mma.test.ts","../test/cot-range-and-bearing.test.ts","../test/cot-routes.test.ts","../test/cot-shapes.test.ts","../test/cot-spotted.test.ts","../test/cot-types.test.ts","../test/cot-uas-tool.test.ts","../test/cot-user-draw.test.ts","../test/cot-video.test.ts","../test/cot_is.test.ts","../test/creator.test.ts","../test/diff.test.ts","../test/flow-tags.test.ts","../test/force-delete.ts","../test/from_geojson.test.ts","../test/iconset.test.ts","../test/milicon.test.ts","../test/milsym.test.ts","../test/newlines.test.ts","../test/normalize_geojson.test.ts","../test/package.test.ts","../test/reversal-geojson.test.ts","../test/reversal-proto.test.ts","../test/stream.ts","../test/taskings-mission.test.ts","../test/util.test.ts","../test/validation.test.ts","../lib/cot.ts","../lib/data-package.ts","../lib/parser.ts","../lib/sensor.ts","../lib/type.ts","../lib/xml-document.ts","../lib/xml/basemap.ts","../lib/xml/iconset.ts"],"version":"5.9.3"}
1
+ {"root":["../index.ts","../cli.ts","../test/2525.test.ts","../test/basemaps.test.ts","../test/basic.test.ts","../test/chat.test.ts","../test/cli.test.ts","../test/cot-emergency.test.ts","../test/cot-fileshare.test.ts","../test/cot-itak.test.ts","../test/cot-mma.test.ts","../test/cot-range-and-bearing.test.ts","../test/cot-routes.test.ts","../test/cot-shapes.test.ts","../test/cot-spotted.test.ts","../test/cot-types.test.ts","../test/cot-uas-tool.test.ts","../test/cot-user-draw.test.ts","../test/cot-video.test.ts","../test/cot_is.test.ts","../test/creator.test.ts","../test/diff.test.ts","../test/flow-tags.test.ts","../test/force-delete.ts","../test/from_geojson.test.ts","../test/iconset.test.ts","../test/milicon.test.ts","../test/milsym.test.ts","../test/newlines.test.ts","../test/normalize_geojson.test.ts","../test/package.test.ts","../test/reversal-geojson.test.ts","../test/reversal-proto.test.ts","../test/stream.ts","../test/taskings-mission.test.ts","../test/util.test.ts","../test/validation.test.ts","../lib/cot.ts","../lib/data-package.ts","../lib/parser-normalize.ts","../lib/parser.ts","../lib/sensor.ts","../lib/type.ts","../lib/xml-document.ts","../lib/xml/basemap.ts","../lib/xml/iconset.ts"],"version":"5.9.3"}
@@ -0,0 +1,55 @@
1
+ export type ParsedAttributeVisitor = (
2
+ attributeKey: string,
3
+ attributeValue: unknown,
4
+ attributes: Record<string, unknown>,
5
+ path: string[]
6
+ ) => void;
7
+
8
+ export function visitElementAttributes(
9
+ input: unknown,
10
+ visitor: ParsedAttributeVisitor,
11
+ path: string[] = []
12
+ ): void {
13
+ if (Array.isArray(input)) {
14
+ for (const [index, value] of input.entries()) {
15
+ visitElementAttributes(value, visitor, [...path, String(index)]);
16
+ }
17
+
18
+ return;
19
+ }
20
+
21
+ if (!input || typeof input !== 'object') {
22
+ return;
23
+ }
24
+
25
+ const record = input as Record<string, unknown>;
26
+ for (const [key, value] of Object.entries(record)) {
27
+ if (key === '_attributes' && value && typeof value === 'object' && !Array.isArray(value)) {
28
+ const attributes = value as Record<string, unknown>;
29
+
30
+ for (const [attributeKey, attributeValue] of Object.entries(attributes)) {
31
+ visitor(attributeKey, attributeValue, attributes, [...path, key]);
32
+ visitElementAttributes(attributes[attributeKey], visitor, [...path, key, attributeKey]);
33
+ }
34
+
35
+ continue;
36
+ }
37
+
38
+ visitElementAttributes(value, visitor, [...path, key]);
39
+ }
40
+ }
41
+
42
+ export function normalizeBooleanAttributeValues(input: unknown): void {
43
+ visitElementAttributes(input, (attributeKey, attributeValue, attributes) => {
44
+ if (typeof attributeValue !== 'string') {
45
+ return;
46
+ }
47
+
48
+ const normalized = attributeValue.toLowerCase();
49
+ if (normalized === 'true') {
50
+ attributes[attributeKey] = true;
51
+ } else if (normalized === 'false') {
52
+ attributes[attributeKey] = false;
53
+ }
54
+ });
55
+ }
package/lib/parser.ts CHANGED
@@ -15,6 +15,7 @@ import type {
15
15
  import {
16
16
  InputFeature,
17
17
  } from './types/feature.js';
18
+ import { normalizeBooleanAttributeValues } from './parser-normalize.js';
18
19
  import JSONCoT, { Detail } from './types/types.js'
19
20
  import CoT from './cot.js';
20
21
  import type { CoTOptions } from './cot.js';
@@ -39,6 +40,35 @@ export interface SerializerOptions {
39
40
  resetFlow: boolean
40
41
  }
41
42
 
43
+ function resetFlowTags(cot: CoT): void {
44
+ const flowTags = cot.raw.event.detail?.['_flow-tags_'];
45
+
46
+ if (!flowTags || typeof flowTags !== 'object' || Array.isArray(flowTags)) {
47
+ return;
48
+ }
49
+
50
+ const stripServerFlowTags = (tags: Record<string, unknown>): void => {
51
+ for (const key of Object.keys(tags)) {
52
+ if (key !== '_attributes' && key.startsWith('TAK-Server')) {
53
+ delete tags[key];
54
+ }
55
+ }
56
+ };
57
+
58
+ stripServerFlowTags(flowTags as Record<string, unknown>);
59
+
60
+ if (
61
+ '_attributes' in flowTags
62
+ && flowTags._attributes
63
+ && typeof flowTags._attributes === 'object'
64
+ && !Array.isArray(flowTags._attributes)
65
+ ) {
66
+ stripServerFlowTags(flowTags._attributes as Record<string, unknown>);
67
+ }
68
+
69
+ flowTags[`NodeCoT-${pkg.version}`] = new Date().toISOString();
70
+ }
71
+
42
72
  /**
43
73
  * Convert to and from an XML CoT message
44
74
  * @class
@@ -128,8 +158,11 @@ export class CoTParser {
128
158
  raw: Buffer | string,
129
159
  opts: CoTOptions = {}
130
160
  ): CoT {
161
+ const parsed = xml2js(String(raw), { compact: true }) as Static<typeof JSONCoT>;
162
+ normalizeBooleanAttributeValues(parsed);
163
+
131
164
  const cot = new CoT(
132
- xml2js(String(raw), { compact: true }) as Static<typeof JSONCoT>,
165
+ parsed,
133
166
  opts
134
167
  );
135
168
 
@@ -141,10 +174,7 @@ export class CoTParser {
141
174
  opts?: SerializerOptions
142
175
  ): string {
143
176
  if (opts?.resetFlow) {
144
- if (cot.raw.event.detail && cot.raw.event.detail['_flow-tags_']) {
145
- cot.raw.event.detail['_flow-tags_'] = {}
146
- cot.raw.event.detail['_flow-tags_'][`NodeCoT-${pkg.version}`] = new Date().toISOString()
147
- }
177
+ resetFlowTags(cot);
148
178
  }
149
179
 
150
180
  return js2xml(cot.raw, { compact: true });
@@ -162,10 +192,7 @@ export class CoTParser {
162
192
  const ProtoMessage = RootMessage.lookupType(`atakmap.commoncommo.protobuf.v${version}.TakMessage`)
163
193
 
164
194
  if (opts?.resetFlow) {
165
- if (cot.raw.event.detail && cot.raw.event.detail['_flow-tags_']) {
166
- cot.raw.event.detail['_flow-tags_'] = {}
167
- cot.raw.event.detail['_flow-tags_'][`NodeCoT-${pkg.version}`] = new Date().toISOString()
168
- }
195
+ resetFlowTags(cot);
169
196
  }
170
197
 
171
198
  // The spread operator is important to make sure the delete doesn't modify the underlying detail object
@@ -226,6 +253,7 @@ export class CoTParser {
226
253
  for (const key in msg.cotEvent.detail) {
227
254
  if (key === 'xmlDetail') {
228
255
  const parsed: any = xml2js(`<detail>${msg.cotEvent.detail.xmlDetail}</detail>`, { compact: true });
256
+ normalizeBooleanAttributeValues(parsed);
229
257
  Object.assign(detail, parsed.detail);
230
258
 
231
259
  if (detail.metadata) {
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@tak-ps/node-cot",
3
3
  "type": "module",
4
- "version": "14.30.0",
4
+ "version": "14.31.0",
5
5
  "description": "Lightweight JavaScript library for parsing and manipulating TAK messages",
6
6
  "author": "Nick Ingalls <nick@ingalls.ca>",
7
7
  "types": "index.ts",
8
+ "bin": {
9
+ "cot": "./cli.ts"
10
+ },
8
11
  "exports": {
9
12
  ".": {
10
13
  "types": "./dist/index.d.ts",
package/tsconfig.json CHANGED
@@ -22,7 +22,8 @@
22
22
  }
23
23
  },
24
24
  "include": [
25
- "index.ts",
25
+ "index.ts",
26
+ "cli.ts",
26
27
  "test/**/*",
27
28
  "lib/*.ts",
28
29
  "lib/xml/*.ts",