@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 +9 -0
- package/cli.ts +220 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +175 -0
- package/dist/cli.js.map +1 -0
- package/dist/lib/parser-normalize.d.ts +3 -0
- package/dist/lib/parser-normalize.js +38 -0
- package/dist/lib/parser-normalize.js.map +1 -0
- package/dist/lib/parser.js +28 -9
- package/dist/lib/parser.js.map +1 -1
- package/dist/package.json +4 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/lib/parser-normalize.ts +55 -0
- package/lib/parser.ts +37 -9
- package/package.json +4 -1
- package/tsconfig.json +2 -1
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
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
|
package/dist/cli.js.map
ADDED
|
@@ -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"}
|
package/dist/lib/parser.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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) {
|
package/dist/lib/parser.js.map
CHANGED
|
@@ -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":"AAAA,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,GAAG,MAAM,4BAA4B,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAOpD,OAAO,EACH,YAAY,GACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,+BAA+B,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,GAAG,MAAM,UAAU,CAAC;AAE3B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC;AACvG,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAEnD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAE7F,MAAM,QAAQ,GAAG,CAAC,IAAI,GAAG,CAAC;IACtB,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,IAAI;IACjB,eAAe,EAAE,IAAI;CACxB,CAAC,CAAC;KACE,OAAO,CAAC,OAAO,CAAC,CAAC;AAMtB,SAAS,aAAa,CAAC,GAAQ;IAC3B,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,aAAa,CAAC,CAAC;IAEvD,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvE,OAAO;IACX,CAAC;IAED,MAAM,mBAAmB,GAAG,CAAC,IAA6B,EAAQ,EAAE;QAChE,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,IAAI,GAAG,KAAK,aAAa,IAAI,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBACxD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;YACrB,CAAC;QACL,CAAC;IACL,CAAC,CAAC;IAEF,mBAAmB,CAAC,QAAmC,CAAC,CAAC;IAEzD,IACI,aAAa,IAAI,QAAQ;WACtB,QAAQ,CAAC,WAAW;WACpB,OAAO,QAAQ,CAAC,WAAW,KAAK,QAAQ;WACxC,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EACzC,CAAC;QACC,mBAAmB,CAAC,QAAQ,CAAC,WAAsC,CAAC,CAAC;IACzE,CAAC;IAED,QAAQ,CAAC,WAAW,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,SAAS;IAClB,MAAM,CAAC,QAAQ,CACX,GAAQ,EACR,OAEI;QACA,IAAI,EAAE,IAAI;KACb;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;YAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAE9C,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClB,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC;QACnG,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM;gBAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;YAErD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;gBACvC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC;YAC7C,CAAC;YAED,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,WAAW,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QAC5F,CAAC;QAED,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,CACf,IAAS,EACT,IAAS,EACT,IAAI,GAAG;QACH,YAAY,EAAE,KAAK;QACnB,kBAAkB,EAAE,KAAK;QACzB,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,KAAK;KAClB;QAED,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAgC,CAAC;QACrE,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAgC,CAAC;QAErE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACjB,OAAO,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;YACzB,OAAO,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;QAC7B,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACrB,OAAO,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC7B,OAAO,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;QACjC,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACjB,OAAO,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;YACzB,OAAO,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;QAC7B,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC3B,OAAO,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;YACzB,OAAO,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;YAC1B,OAAO,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;YAC1B,OAAO,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;YACzB,OAAO,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;YAC1B,OAAO,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;QAC9B,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEzB,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5B,CAAC;IAGD,MAAM,CAAC,QAAQ,CACX,GAAoB,EACpB,OAAmB,EAAE;QAErB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAA2B,CAAC;QAChF,+BAA+B,CAAC,MAAM,CAAC,CAAC;QAExC,MAAM,GAAG,GAAG,IAAI,GAAG,CACf,MAAM,EACN,IAAI,CACP,CAAC;QAEF,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,CAAC,MAAM,CACT,GAAQ,EACR,IAAwB;QAExB,IAAI,IAAI,EAAE,SAAS,EAAE,CAAC;YAClB,aAAa,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;QAED,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,QAAQ,CACjB,GAAQ,EACR,OAAO,GAAG,CAAC,EACX,IAAwB;QAExB,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC;YAAE,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,8BAA8B,OAAO,EAAE,CAAC,CAAC;QAClG,MAAM,YAAY,GAAG,WAAW,CAAC,UAAU,CAAC,iCAAiC,OAAO,aAAa,CAAC,CAAA;QAElG,IAAI,IAAI,EAAE,SAAS,EAAE,CAAC;YAClB,aAAa,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;QAED,uGAAuG;QACvG,MAAM,MAAM,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAC3C,MAAM,GAAG,GAAQ;YACb,QAAQ,EAAE;gBACN,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW;gBAC5B,QAAQ,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE;gBAC5D,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE;gBAC9D,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE;gBAC9D,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW;gBAClC,MAAM,EAAE;oBACJ,SAAS,EAAE,EAAE;iBAChB;aACJ;SACJ,CAAC;QAEF,IAAI,GAAgC,CAAC;QACrC,KAAK,GAAG,IAAI,MAAM,EAAE,CAAC;YACjB,IAAG,CAAC,SAAS,EAAE,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACpF,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC;gBACnD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAA;YACtB,CAAC;QACL,CAAC;QAED,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC;YACnC,GAAG,MAAM;YACT,QAAQ,EAAE,GAAG,CAAC,QAAQ;SACzB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAEtB,OAAO,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,GAAQ;QAC5B,OAAO,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,UAAU,CACnB,GAAe,EACf,OAAO,GAAG,CAAC,EACX,OAAmB,EAAE;QAErB,MAAM,YAAY,GAAG,WAAW,CAAC,UAAU,CAAC,iCAAiC,OAAO,aAAa,CAAC,CAAA;QAElG,iBAAiB;QACjB,MAAM,GAAG,GAAQ,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAE1C,IAAI,CAAC,GAAG,CAAC,QAAQ;YAAE,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,kBAAkB,CAAC,CAAC;QAEhE,MAAM,MAAM,GAAwB,EAAE,CAAC;QACvC,MAAM,QAAQ,GAA4B,EAAE,CAAC;QAC7C,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpC,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;gBACtB,MAAM,MAAM,GAAQ,MAAM,CAAC,WAAW,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBACnG,+BAA+B,CAAC,MAAM,CAAC,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;gBAErC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;oBAClB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;wBAChC,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;oBAC/C,CAAC;oBACD,OAAO,MAAM,CAAC,QAAQ,CAAC;gBAC3B,CAAC;YACL,CAAC;iBAAM,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;gBACzB,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC3B,MAAM,CAAC,OAAO,GAAG,EAAE,WAAW,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/D,CAAC;YACL,CAAC;iBAAM,IAAI,CAAC,SAAS,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnF,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC3B,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC5D,CAAC;YACL,CAAC;QACL,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC;YAChB,KAAK,EAAE;gBACH,WAAW,EAAE;oBACT,OAAO,EAAE,KAAK;oBACd,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG;oBACrE,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM;oBAC3E,IAAI,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,WAAW,EAAE;oBAC9D,KAAK,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,WAAW,EAAE;oBAChE,KAAK,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,WAAW,EAAE;iBACnE;gBACD,MAAM;gBACN,KAAK,EAAE;oBACH,WAAW,EAAE;wBACT,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG;wBACrB,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG;wBACrB,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG;wBACrB,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE;wBACnB,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE;qBACtB;iBACJ;aACJ;SACJ,EAAE,IAAI,CAAC,CAAC;QAET,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAExB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAC1B,OAAsC;QAEtC,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,CAAC,YAAY,CACrB,OAAoC,EACpC,OAAmB,EAAE;QAErB,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAE9C,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;CACJ"}
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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",
|