@tak-ps/node-cot 12.30.0 → 12.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 +8 -0
- package/dist/package.json +2 -1
- package/lib/utils/2525.ts +53 -0
- package/lib/utils/type.ts +53 -0
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
package/dist/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tak-ps/node-cot",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "12.
|
|
4
|
+
"version": "12.31.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",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"archiver": "^7.0.1",
|
|
31
31
|
"color": "^5.0.0",
|
|
32
32
|
"json-diff-ts": "^4.0.1",
|
|
33
|
+
"milsymbol": "^3.0.2",
|
|
33
34
|
"node-stream-zip": "^1.15.0",
|
|
34
35
|
"protobufjs": "^7.3.0",
|
|
35
36
|
"rimraf": "^6.0.0",
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @class
|
|
3
|
+
*
|
|
4
|
+
* Convert a COT Atom Type to/from Symbol Identification Code (SIDC)
|
|
5
|
+
* Migrated to TypeScript from the original Kotlin verison
|
|
6
|
+
* @ https://github.com/cyberpython/kotcot under the MIT License
|
|
7
|
+
*/
|
|
8
|
+
export default class Type2525 {
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Given a COT Atom Type, return an SIDC
|
|
12
|
+
* @param cotType - Cursor On Target Type (Note must start with atomic "a")
|
|
13
|
+
*/
|
|
14
|
+
static to2525B(cotType: string): string {
|
|
15
|
+
if (!cotType.match(/^a-[puafnshjkox]-[PAGSUFXZ](-\w+)*$/)) {
|
|
16
|
+
throw new TypeError("CoT to 2525B can only be applied to well-formed Atom type CoT Events.")
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const m2525bChars = cotType.substring(4).replace(/[^A-Z0-9]+/g, "");
|
|
20
|
+
const m2525bBattleDim = m2525bChars.substring(0, 1);
|
|
21
|
+
|
|
22
|
+
const cotAffiliation = cotType.substring(2, 3);
|
|
23
|
+
const m2525bAffiliation = (cotAffiliation === "o" || cotAffiliation === "x")
|
|
24
|
+
? "U"
|
|
25
|
+
: cotAffiliation.toUpperCase();
|
|
26
|
+
|
|
27
|
+
const m2525bFuncId = m2525bChars.length > 1
|
|
28
|
+
? m2525bChars.substring(1).padEnd(6, "-").substring(0, 6)
|
|
29
|
+
: "------";
|
|
30
|
+
|
|
31
|
+
return `S${m2525bAffiliation}${m2525bBattleDim}P${m2525bFuncId}-----`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static from2525B(sidc : string) : string {
|
|
35
|
+
if (!/^S[PUAFNSHGWMDLJK-][PAGSUFXZ-][AP-][A-Z0-9-]{10}[AECGNS-]$/.test(sidc)) {
|
|
36
|
+
throw new Error("2525B to CoT can only be applied to well-formed warfighting 2525B SIDCs.");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const m2525bAffiliation = sidc.substring(1, 2);
|
|
40
|
+
const cotAffiliation = ["G", "W", "M", "D", "L"].includes(m2525bAffiliation)
|
|
41
|
+
? "f"
|
|
42
|
+
: m2525bAffiliation === "-"
|
|
43
|
+
? "o"
|
|
44
|
+
: m2525bAffiliation.toLowerCase();
|
|
45
|
+
|
|
46
|
+
const cotBattleDim = sidc.substring(2, 3);
|
|
47
|
+
const cotFuncId = Array.from(sidc.substring(4, 10).replace(/[^A-Z0-9]+/g, ""))
|
|
48
|
+
.map((x) => `-${x}`)
|
|
49
|
+
.join("");
|
|
50
|
+
|
|
51
|
+
return `a-${cotAffiliation}-${cotBattleDim}${cotFuncId}`;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Static, TSchema, TUnknown } from '@sinclair/typebox'
|
|
2
|
+
import { Value } from '@sinclair/typebox/value'
|
|
3
|
+
|
|
4
|
+
export type TypeOpts = {
|
|
5
|
+
verbose?: boolean;
|
|
6
|
+
default?: boolean;
|
|
7
|
+
convert?: boolean;
|
|
8
|
+
clean?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default class TypeValidator {
|
|
12
|
+
/**
|
|
13
|
+
* Arbitrary JSON objects occasionally need to get typed as part of an ETL
|
|
14
|
+
* This function provides the ability to strictly type unknown objects at runtime
|
|
15
|
+
*/
|
|
16
|
+
static type<T extends TSchema = TUnknown>(
|
|
17
|
+
type: T,
|
|
18
|
+
body: unknown,
|
|
19
|
+
opts?: TypeOpts
|
|
20
|
+
): Static<T> {
|
|
21
|
+
if (!opts) opts = {};
|
|
22
|
+
if (opts.verbose === undefined) opts.verbose = false;
|
|
23
|
+
if (opts.default === undefined) opts.default = true;
|
|
24
|
+
if (opts.convert === undefined) opts.convert = true;
|
|
25
|
+
if (opts.clean === undefined) opts.clean = true;
|
|
26
|
+
|
|
27
|
+
if (opts.default) {
|
|
28
|
+
Value.Default(type, body)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (opts.clean) {
|
|
32
|
+
Value.Clean(type, body)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (opts.convert) {
|
|
36
|
+
Value.Convert(type, body)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const result = Value.Check(type, body)
|
|
40
|
+
|
|
41
|
+
if (result) return body;
|
|
42
|
+
|
|
43
|
+
const errors = Value.Errors(type, body);
|
|
44
|
+
|
|
45
|
+
const firstError = errors.First();
|
|
46
|
+
|
|
47
|
+
if (opts.verbose) {
|
|
48
|
+
throw new Error(`Internal Validation Error: ${JSON.stringify(firstError)} -- Body: ${JSON.stringify(body)}`);
|
|
49
|
+
} else {
|
|
50
|
+
throw new Error(`Internal Validation Error`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tak-ps/node-cot",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "12.
|
|
4
|
+
"version": "12.31.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",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"archiver": "^7.0.1",
|
|
31
31
|
"color": "^5.0.0",
|
|
32
32
|
"json-diff-ts": "^4.0.1",
|
|
33
|
+
"milsymbol": "^3.0.2",
|
|
33
34
|
"node-stream-zip": "^1.15.0",
|
|
34
35
|
"protobufjs": "^7.3.0",
|
|
35
36
|
"rimraf": "^6.0.0",
|