@tak-ps/node-tak 11.17.4 → 11.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/.github/workflows/release.yml +10 -16
  2. package/CHANGELOG.md +8 -0
  3. package/lib/api/mission.ts +41 -27
  4. package/package.json +3 -3
  5. package/dist/cli.d.ts +0 -2
  6. package/dist/cli.js +0 -183
  7. package/dist/cli.js.map +0 -1
  8. package/dist/index.d.ts +0 -59
  9. package/dist/index.js +0 -204
  10. package/dist/index.js.map +0 -1
  11. package/dist/lib/api/contacts.d.ts +0 -24
  12. package/dist/lib/api/contacts.js +0 -44
  13. package/dist/lib/api/contacts.js.map +0 -1
  14. package/dist/lib/api/credentials.d.ts +0 -21
  15. package/dist/lib/api/credentials.js +0 -83
  16. package/dist/lib/api/credentials.js.map +0 -1
  17. package/dist/lib/api/export.d.ts +0 -21
  18. package/dist/lib/api/export.js +0 -37
  19. package/dist/lib/api/export.js.map +0 -1
  20. package/dist/lib/api/files.d.ts +0 -77
  21. package/dist/lib/api/files.js +0 -170
  22. package/dist/lib/api/files.js.map +0 -1
  23. package/dist/lib/api/groups.d.ts +0 -43
  24. package/dist/lib/api/groups.js +0 -68
  25. package/dist/lib/api/groups.js.map +0 -1
  26. package/dist/lib/api/iconsets.d.ts +0 -27
  27. package/dist/lib/api/iconsets.js +0 -42
  28. package/dist/lib/api/iconsets.js.map +0 -1
  29. package/dist/lib/api/injectors.d.ts +0 -52
  30. package/dist/lib/api/injectors.js +0 -82
  31. package/dist/lib/api/injectors.js.map +0 -1
  32. package/dist/lib/api/locate.d.ts +0 -13
  33. package/dist/lib/api/locate.js +0 -27
  34. package/dist/lib/api/locate.js.map +0 -1
  35. package/dist/lib/api/mission-invite.d.ts +0 -36
  36. package/dist/lib/api/mission-invite.js +0 -55
  37. package/dist/lib/api/mission-invite.js.map +0 -1
  38. package/dist/lib/api/mission-layer.d.ts +0 -137
  39. package/dist/lib/api/mission-layer.js +0 -247
  40. package/dist/lib/api/mission-layer.js.map +0 -1
  41. package/dist/lib/api/mission-log.d.ts +0 -75
  42. package/dist/lib/api/mission-log.js +0 -117
  43. package/dist/lib/api/mission-log.js.map +0 -1
  44. package/dist/lib/api/mission.d.ts +0 -498
  45. package/dist/lib/api/mission.js +0 -696
  46. package/dist/lib/api/mission.js.map +0 -1
  47. package/dist/lib/api/oauth.d.ts +0 -22
  48. package/dist/lib/api/oauth.js +0 -55
  49. package/dist/lib/api/oauth.js.map +0 -1
  50. package/dist/lib/api/package.d.ts +0 -40
  51. package/dist/lib/api/package.js +0 -70
  52. package/dist/lib/api/package.js.map +0 -1
  53. package/dist/lib/api/profile.d.ts +0 -9
  54. package/dist/lib/api/profile.js +0 -16
  55. package/dist/lib/api/profile.js.map +0 -1
  56. package/dist/lib/api/query.d.ts +0 -16
  57. package/dist/lib/api/query.js +0 -60
  58. package/dist/lib/api/query.js.map +0 -1
  59. package/dist/lib/api/repeater.d.ts +0 -47
  60. package/dist/lib/api/repeater.js +0 -62
  61. package/dist/lib/api/repeater.js.map +0 -1
  62. package/dist/lib/api/security.d.ts +0 -110
  63. package/dist/lib/api/security.js +0 -123
  64. package/dist/lib/api/security.js.map +0 -1
  65. package/dist/lib/api/subscriptions.d.ts +0 -103
  66. package/dist/lib/api/subscriptions.js +0 -74
  67. package/dist/lib/api/subscriptions.js.map +0 -1
  68. package/dist/lib/api/types.d.ts +0 -41
  69. package/dist/lib/api/types.js +0 -42
  70. package/dist/lib/api/types.js.map +0 -1
  71. package/dist/lib/api/video.d.ts +0 -139
  72. package/dist/lib/api/video.js +0 -151
  73. package/dist/lib/api/video.js.map +0 -1
  74. package/dist/lib/api.d.ts +0 -60
  75. package/dist/lib/api.js +0 -166
  76. package/dist/lib/api.js.map +0 -1
  77. package/dist/lib/auth.d.ts +0 -34
  78. package/dist/lib/auth.js +0 -97
  79. package/dist/lib/auth.js.map +0 -1
  80. package/dist/lib/commands.d.ts +0 -38
  81. package/dist/lib/commands.js +0 -34
  82. package/dist/lib/commands.js.map +0 -1
  83. package/dist/lib/fetch.d.ts +0 -8
  84. package/dist/lib/fetch.js +0 -26
  85. package/dist/lib/fetch.js.map +0 -1
  86. package/dist/lib/stream.d.ts +0 -2
  87. package/dist/lib/stream.js +0 -9
  88. package/dist/lib/stream.js.map +0 -1
  89. package/dist/test/default.test.d.ts +0 -1
  90. package/dist/test/default.test.js +0 -8
  91. package/dist/test/default.test.js.map +0 -1
  92. package/dist/test/findCoT.test.d.ts +0 -1
  93. package/dist/test/findCoT.test.js +0 -85
  94. package/dist/test/findCoT.test.js.map +0 -1
  95. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -5,31 +5,25 @@ on:
5
5
  tags:
6
6
  - '*'
7
7
 
8
+ permissions:
9
+ id-token: write # Required for OIDC
10
+ contents: read
11
+
8
12
  jobs:
9
13
  build:
10
14
  runs-on: ubuntu-latest
11
15
  steps:
12
- - uses: actions/checkout@v4
13
-
14
- - name: Get tag
15
- id: tag
16
- uses: dawidd6/action-get-tag@v1
16
+ - uses: actions/checkout@v6
17
17
 
18
- - uses: actions/setup-node@v4
18
+ - uses: actions/setup-node@v6
19
19
  with:
20
20
  node-version: 22
21
- registry-url: https://registry.npmjs.org/
21
+
22
+ - name: Update npm
23
+ run: npm install -g npm@latest
22
24
 
23
25
  - name: npm install
24
26
  run: npm install
25
27
 
26
- - name: npm run build
27
- run: npm run build
28
-
29
28
  - name: npm publish
30
- run: npm publish
31
- env:
32
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
33
-
34
- - name: Github Release
35
- uses: softprops/action-gh-release@v2
29
+ run: npm publish --provenance --access public
package/CHANGELOG.md CHANGED
@@ -10,6 +10,14 @@
10
10
 
11
11
  ## Version History
12
12
 
13
+ ### v11.18.1 - 2025-12-15
14
+
15
+ - :rocket: Update Release Process
16
+
17
+ ### v11.18.0 - 2025-12-04
18
+
19
+ - :rocket: Update Mission type to require description
20
+
13
21
  ### v11.17.4 - 2025-12-03
14
22
 
15
23
  - :bug: Update Mission must occur via `guid`
@@ -28,9 +28,29 @@ export const MissionContent = Type.Object({
28
28
  expiration: Type.Integer()
29
29
  });
30
30
 
31
+ export const MissionChange = Type.Object({
32
+ isFederatedChange: Type.Boolean(),
33
+ type: Type.String(),
34
+ missionName: Type.String(),
35
+ timestamp: Type.String(),
36
+ serverTime: Type.String(),
37
+ creatorUid: Type.Optional(Type.String()),
38
+ contentUid: Type.Optional(Type.String()),
39
+ details: Type.Optional(Type.Object({
40
+ type: Type.String(),
41
+ callsign: Type.String(),
42
+ color: Type.Optional(Type.String()),
43
+ location: Type.Object({
44
+ lat: Type.Number(),
45
+ lon: Type.Number()
46
+ })
47
+ })),
48
+ contentResource: Type.Optional(MissionContent)
49
+ });
50
+
31
51
  export const Mission = Type.Object({
32
52
  name: Type.String(),
33
- description: Type.Optional(Type.String()),
53
+ description: Type.String(),
34
54
  chatRoom: Type.Optional(Type.String()),
35
55
  baseLayer: Type.Optional(Type.String()),
36
56
  bbox: Type.Optional(Type.String()),
@@ -60,27 +80,7 @@ export const Mission = Type.Object({
60
80
  passwordProtected: Type.Boolean(),
61
81
  token: Type.Optional(Type.String()), // Only present when mission created
62
82
  groups: Type.Optional(Type.Union([Type.String(), Type.Array(Type.String())])), // Only present on Mission.get()
63
- missionChanges: Type.Optional(Type.Array(Type.Unknown())) // Only present on Mission.get()
64
- });
65
-
66
- export const MissionChange = Type.Object({
67
- isFederatedChange: Type.Boolean(),
68
- type: Type.String(),
69
- missionName: Type.String(),
70
- timestamp: Type.String(),
71
- serverTime: Type.String(),
72
- creatorUid: Type.Optional(Type.String()),
73
- contentUid: Type.Optional(Type.String()),
74
- details: Type.Optional(Type.Object({
75
- type: Type.String(),
76
- callsign: Type.String(),
77
- color: Type.Optional(Type.String()),
78
- location: Type.Object({
79
- lat: Type.Number(),
80
- lon: Type.Number()
81
- })
82
- })),
83
- contentResource: Type.Optional(MissionContent)
83
+ missionChanges: Type.Optional(Type.Array(MissionChange)) // Only present on Mission.get()
84
84
  });
85
85
 
86
86
  export const MissionRole = Type.Object({
@@ -245,6 +245,17 @@ export default class MissionCommands extends Commands {
245
245
  return encodeURIComponent(name.trim())
246
246
  }
247
247
 
248
+ /*
249
+ * The Mission type is currently cast from an unknown to a Mission
250
+ * from the fetch call from the server. There are a few standardizations
251
+ * we make for better usability.
252
+ */
253
+ #stdMission(mission: Static<typeof Mission>): Static<typeof Mission> {
254
+ if (mission.description === undefined) mission.description = '';
255
+
256
+ return mission;
257
+ }
258
+
248
259
  #headers(opts?: Static<typeof MissionOptions>): object {
249
260
  if (opts && opts.token) {
250
261
  return {
@@ -645,7 +656,8 @@ export default class MissionCommands extends Commands {
645
656
  });
646
657
 
647
658
  if (!missions.data.length) throw new Err(404, null, `No Mission for GUID: ${guid}`);
648
- return missions.data[0];
659
+
660
+ return this.#stdMission(missions.data[0]);
649
661
  }
650
662
 
651
663
  /**
@@ -724,7 +736,7 @@ export default class MissionCommands extends Commands {
724
736
  });
725
737
  }
726
738
 
727
- return mission;
739
+ return this.#stdMission(mission);
728
740
  }
729
741
 
730
742
  /**
@@ -755,7 +767,7 @@ export default class MissionCommands extends Commands {
755
767
 
756
768
  if (!missions.data.length) throw new Err(404, null, `No Mission for Name: ${name}`);
757
769
 
758
- return missions.data[0];
770
+ return this.#stdMission(missions.data[0]);
759
771
  }
760
772
 
761
773
  /**
@@ -780,6 +792,8 @@ export default class MissionCommands extends Commands {
780
792
  throw new Err(400, null, 'Mission Name cannot contain forward slashes');
781
793
  }
782
794
 
795
+ if (body.description === undefined) body.description = '';
796
+
783
797
  if (body.group && Array.isArray(body.group)) body.group = body.group.join(',');
784
798
 
785
799
  let q: keyof Static<typeof MissionCreateInput>;
@@ -803,7 +817,7 @@ export default class MissionCommands extends Commands {
803
817
  });
804
818
  }
805
819
 
806
- return mission;
820
+ return this.#stdMission(mission);
807
821
  }
808
822
 
809
823
  /**
@@ -826,7 +840,7 @@ export default class MissionCommands extends Commands {
826
840
 
827
841
  const mission = missions.data[0];
828
842
 
829
- return mission;
843
+ return this.#stdMission(mission);
830
844
  }
831
845
 
832
846
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tak-ps/node-tak",
3
3
  "type": "module",
4
- "version": "11.17.4",
4
+ "version": "11.18.1",
5
5
  "description": "Lightweight JavaScript library for communicating with TAK Server",
6
6
  "author": "Nick Ingalls <nick@ingalls.ca>",
7
7
  "main": "dist/index.js",
@@ -44,7 +44,7 @@
44
44
  "devDependencies": {
45
45
  "@inquirer/prompts": "^8.0.1",
46
46
  "@types/minimist": "^1.2.5",
47
- "@types/node": "^24.0.0",
47
+ "@types/node": "^25.0.0",
48
48
  "@types/pem": "^1.14.4",
49
49
  "@types/tape": "^5.6.0",
50
50
  "c8": "^10.1.3",
@@ -58,7 +58,7 @@
58
58
  },
59
59
  "repository": {
60
60
  "type": "git",
61
- "url": "git+https://github.com/dfpc-coe/node-tak.git"
61
+ "url": "https://github.com/dfpc-coe/node-tak"
62
62
  },
63
63
  "keywords": [
64
64
  "tak",
package/dist/cli.d.ts DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env tsx
2
- export {};
package/dist/cli.js DELETED
@@ -1,183 +0,0 @@
1
- #!/usr/bin/env tsx
2
- import fs from 'node:fs/promises';
3
- import os from 'node:os';
4
- import path from 'node:path';
5
- import minimist from 'minimist';
6
- import { CoTParser } from '@tak-ps/node-cot';
7
- import TAK from './index.js';
8
- import { getPemFromP12 } from 'p12-pem';
9
- import TAKAPI, { CommandList } from './lib/api.js';
10
- import { APIAuthPassword, APIAuthCertificate } from './lib/auth.js';
11
- import Commands from './lib/commands.js';
12
- import { select, confirm, number, input, password, Separator } from '@inquirer/prompts';
13
- const args = minimist(process.argv, {
14
- string: ['profile', 'format', 'auth'],
15
- });
16
- const configPath = path.resolve(os.homedir(), './.tak.json');
17
- let config;
18
- try {
19
- config = JSON.parse(String(await fs.readFile(configPath)));
20
- }
21
- catch (err) {
22
- if (err instanceof Error && err.message.includes('no such file or directory')) {
23
- const answer = await confirm({
24
- message: 'No TAK Config file Detected, create one?'
25
- });
26
- if (!answer) {
27
- throw new Error('No config file and not creating one');
28
- }
29
- config = {
30
- version: 1,
31
- profiles: {}
32
- };
33
- await fs.writeFile(configPath, JSON.stringify(config, null, 4));
34
- }
35
- else {
36
- throw err;
37
- }
38
- }
39
- if (!args.profile && config.profiles && Object.keys(config.profiles).length) {
40
- args.profile = await select({
41
- message: 'Choose a profile',
42
- choices: [
43
- { name: 'New Profile', value: '' },
44
- new Separator(),
45
- ].concat(Object.keys(config.profiles).map((profile) => {
46
- return {
47
- name: profile,
48
- value: profile
49
- };
50
- }))
51
- });
52
- }
53
- if (!args.profile) {
54
- console.error('Create new TAK Server Profile:');
55
- args.profile = await input({ message: 'Enter a name for this profile' });
56
- const host = await input({ message: 'Server hostname', default: 'ops.example.com' });
57
- let marti = 8443;
58
- let webtak = 443;
59
- let stream = 8089;
60
- do {
61
- marti = await number({ message: 'Marti API Port', default: marti });
62
- } while (!marti || isNaN(marti));
63
- do {
64
- webtak = await number({ message: 'WebTAK API Port', default: webtak });
65
- } while (!webtak || isNaN(webtak));
66
- do {
67
- stream = await number({ message: 'Streaming Port', default: stream });
68
- } while (!stream || isNaN(stream));
69
- if (!config.profiles)
70
- config.profiles = {};
71
- config.profiles[args.profile] = {
72
- host,
73
- ports: { webtak, marti, stream }
74
- };
75
- }
76
- if (args.profile && !config.profiles[args.profile]) {
77
- throw new Error(`Profile "${args.profile}" is not defined in config file`);
78
- }
79
- else if (!args.auth && !config.profiles[args.profile].auth) {
80
- const user = await input({ message: 'TAK Username' });
81
- const pass = await password({ message: 'TAK Password' });
82
- const api = await TAKAPI.init(new URL('https://' + config.profiles[args.profile].host + ':' + config.profiles[args.profile].ports.webtak), new APIAuthPassword(user, pass));
83
- const auth = await api.Credentials.generate();
84
- config.profiles[args.profile].auth = {
85
- cert: auth.cert,
86
- key: auth.key,
87
- ca: auth.ca[0]
88
- };
89
- }
90
- let command = args._[2];
91
- if (!command) {
92
- command = await select({
93
- message: 'Choose a Command Group',
94
- choices: [{
95
- name: 'stream',
96
- value: 'stream'
97
- }].concat(Object.keys(CommandList).map((profile) => {
98
- return {
99
- name: profile,
100
- value: profile
101
- };
102
- }))
103
- });
104
- }
105
- await fs.writeFile(configPath, JSON.stringify(config, null, 4));
106
- let auth = config.profiles[args.profile].auth;
107
- if (args.auth) {
108
- const password = process.env.TAK_P12_PASSWORD || await input({ message: 'P12 Container Password' });
109
- const certs = getPemFromP12(args.auth, password);
110
- const cert = certs.pemCertificate
111
- .split('-----BEGIN CERTIFICATE-----')
112
- .join('-----BEGIN CERTIFICATE-----\n')
113
- .split('-----END CERTIFICATE-----')
114
- .join('\n-----END CERTIFICATE-----');
115
- const key = certs.pemKey
116
- .split('-----BEGIN RSA PRIVATE KEY-----')
117
- .join('-----BEGIN RSA PRIVATE KEY-----\n')
118
- .split('-----END RSA PRIVATE KEY-----')
119
- .join('\n-----END RSA PRIVATE KEY-----');
120
- auth = { cert, key };
121
- }
122
- if (!auth)
123
- throw new Error(`No Auth in ${args.profile} profile`);
124
- if (command === 'stream') {
125
- const tak = await TAK.connect(new URL('ssl://' + config.profiles[args.profile].host + ':' + config.profiles[args.profile].ports.stream), auth);
126
- tak.on('cot', (cot) => {
127
- console.log(JSON.stringify(CoTParser.to_geojson(cot)));
128
- });
129
- }
130
- else {
131
- if (!config.profiles[args.profile].auth) {
132
- throw new Error(`No Auth in ${args.profile} profile`);
133
- }
134
- const tak = new TAKAPI(new URL('https://' + config.profiles[args.profile].host + ':' + config.profiles[args.profile].ports.marti), new APIAuthCertificate(auth.cert, auth.key));
135
- const invokeTest = tak[CommandList[command]];
136
- if (!invokeTest || !(invokeTest instanceof Commands)) {
137
- throw new Error(`${command} not found`);
138
- }
139
- const invoke = invokeTest;
140
- let subcommand = args._[3];
141
- const subcommands = (obj) => Object.keys(obj);
142
- if (subcommand === 'help') {
143
- console.log(([
144
- 'Command:',
145
- ` tak ${command} <subcommand>`,
146
- 'SubCommands:',
147
- ].concat(subcommands(invoke.schema).map((subcommand) => {
148
- return ` ${String(subcommand)} - ${invoke.schema[subcommand].description}`;
149
- }))).join('\n'));
150
- process.exit(0);
151
- }
152
- else if (!subcommand) {
153
- subcommand = await select({
154
- message: 'Choose an action',
155
- choices: subcommands(invoke.schema).map((subcommand) => {
156
- return {
157
- name: subcommand,
158
- value: subcommand
159
- };
160
- })
161
- });
162
- }
163
- if (!invoke.schema[subcommand]) {
164
- throw new Error(`Unsupported Subcommand: ${subcommand}`);
165
- }
166
- else if (args.format && !invoke.schema[subcommand].formats.includes(args.format)) {
167
- throw new Error(`tak ${command} ${subcommand} does not support --format ${args.format}. Supported formats are: ${invoke.schema[subcommand].formats.join(",")}`);
168
- }
169
- try {
170
- args._[3] = subcommand;
171
- const res = await invoke.cli(args);
172
- if (typeof res === 'string') {
173
- console.log(res);
174
- }
175
- else {
176
- console.log(JSON.stringify(res, null, 4));
177
- }
178
- }
179
- catch (err) {
180
- console.error(err);
181
- }
182
- }
183
- //# sourceMappingURL=cli.js.map
package/dist/cli.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts DELETED
@@ -1,59 +0,0 @@
1
- import EventEmitter from 'node:events';
2
- import type { Static } from '@sinclair/typebox';
3
- import CoT from '@tak-ps/node-cot';
4
- import type { CoTOptions } from '@tak-ps/node-cot';
5
- import type { TLSSocket } from 'node:tls';
6
- import TAKAPI from './lib/api.js';
7
- import { TAKAuth } from './lib/auth.js';
8
- export * from './lib/auth.js';
9
- export declare const REGEX_CONTROL: RegExp;
10
- export declare const REGEX_EVENT: RegExp;
11
- export interface PartialCoT {
12
- event: string;
13
- remainder: string;
14
- }
15
- export type TAKOptions = {
16
- id?: number | string;
17
- type?: string;
18
- cot?: CoTOptions;
19
- };
20
- export default class TAK extends EventEmitter {
21
- id: number | string;
22
- type: string;
23
- url: URL;
24
- auth: Static<typeof TAKAuth>;
25
- open: boolean;
26
- destroyed: boolean;
27
- queue: string[];
28
- writing: boolean;
29
- cotOptions: CoTOptions;
30
- pingInterval?: ReturnType<typeof setTimeout>;
31
- client?: TLSSocket;
32
- version?: string;
33
- /**
34
- * @constructor
35
- *
36
- * @param url - Full URL of Streaming COT Endpoint IE: "https://ops.cotak.gov:8089"
37
- * @param auth - TAK Certificate Pair
38
- * @param opts - Options Object
39
- * @param opts.id - When using multiple connections in a script, allows a unique ID per connection
40
- * @param opts.type - When using multiple connections in a script, allows specifying a script provided connection type
41
- */
42
- constructor(url: URL, auth: Static<typeof TAKAuth>, opts?: TAKOptions);
43
- static connect(url: URL, auth: Static<typeof TAKAuth>, opts?: TAKOptions): Promise<TAK>;
44
- connect_ssl(): Promise<TAK>;
45
- reconnect(): Promise<void>;
46
- destroy(): void;
47
- ping(): Promise<void>;
48
- writer(body: string): Promise<boolean>;
49
- process(): Promise<void>;
50
- /**
51
- * Write a CoT to the TAK Connection
52
- *
53
- * @param {CoT} cot CoT Object
54
- */
55
- write(cots: CoT[]): Promise<void>;
56
- write_xml(body: string): void;
57
- static findCoT(str: string): null | PartialCoT;
58
- }
59
- export { TAKAPI, CoT, };
package/dist/index.js DELETED
@@ -1,204 +0,0 @@
1
- import EventEmitter from 'node:events';
2
- import tls from 'node:tls';
3
- import CoT, { CoTParser } from '@tak-ps/node-cot';
4
- import TAKAPI from './lib/api.js';
5
- export * from './lib/auth.js';
6
- /* eslint-disable no-control-regex */
7
- export const REGEX_CONTROL = /[\u000B-\u001F\u007F-\u009F]/g;
8
- // Match <event .../> or <event> but not <events>
9
- export const REGEX_EVENT = /(<event[ >][\s\S]*?<\/event>)([\s\S]*)/;
10
- export default class TAK extends EventEmitter {
11
- id;
12
- type;
13
- url;
14
- auth;
15
- open;
16
- destroyed;
17
- queue;
18
- writing;
19
- cotOptions;
20
- pingInterval;
21
- client;
22
- version;
23
- /**
24
- * @constructor
25
- *
26
- * @param url - Full URL of Streaming COT Endpoint IE: "https://ops.cotak.gov:8089"
27
- * @param auth - TAK Certificate Pair
28
- * @param opts - Options Object
29
- * @param opts.id - When using multiple connections in a script, allows a unique ID per connection
30
- * @param opts.type - When using multiple connections in a script, allows specifying a script provided connection type
31
- */
32
- constructor(url, auth, opts = {}) {
33
- super();
34
- if (!opts)
35
- opts = {};
36
- this.id = opts.id || crypto.randomUUID();
37
- this.type = opts.type || 'unknown';
38
- this.url = url;
39
- this.auth = auth;
40
- this.writing = false;
41
- this.cotOptions = opts.cot || {};
42
- this.open = false;
43
- this.destroyed = false;
44
- this.queue = [];
45
- }
46
- static async connect(url, auth, opts = {}) {
47
- const tak = new TAK(url, auth, opts);
48
- if (url.protocol === 'ssl:') {
49
- if (!tak.auth.cert)
50
- throw new Error('auth.cert required');
51
- if (!tak.auth.key)
52
- throw new Error('auth.key required');
53
- return await tak.connect_ssl();
54
- }
55
- else {
56
- throw new Error('Unknown TAK Server Protocol');
57
- }
58
- }
59
- connect_ssl() {
60
- return new Promise((resolve) => {
61
- this.destroyed = false;
62
- this.client = tls.connect({
63
- host: this.url.hostname,
64
- port: parseInt(this.url.port),
65
- rejectUnauthorized: this.auth.rejectUnauthorized ?? false,
66
- cert: this.auth.cert,
67
- key: this.auth.key,
68
- passphrase: this.auth.passphrase,
69
- ca: this.auth.ca,
70
- });
71
- this.client.setNoDelay();
72
- this.client.on('connect', () => {
73
- console.error(`ok - ${this.id} @ connect:${this.client ? this.client.authorized : 'NO CLIENT'} - ${this.client ? this.client.authorizationError : 'NO CLIENT'}`);
74
- });
75
- this.client.on('secureConnect', () => {
76
- console.error(`ok - ${this.id} @ secure:${this.client ? this.client.authorized : 'NO CLIENT'} - ${this.client ? this.client.authorizationError : 'NO CLIENT'}`);
77
- this.emit('secureConnect');
78
- this.ping();
79
- });
80
- let buff = '';
81
- this.client.on('data', async (data) => {
82
- // Eventually Parse ProtoBuf
83
- buff = buff + data.toString();
84
- let result = TAK.findCoT(buff);
85
- while (result && result.event) {
86
- try {
87
- const cot = await CoTParser.from_xml(result.event, this.cotOptions);
88
- if (cot.raw.event._attributes.type === 't-x-c-t-r') {
89
- this.open = true;
90
- this.emit('ping');
91
- }
92
- else if (cot.raw.event._attributes.type === 't-x-takp-v'
93
- && cot.raw.event.detail
94
- && cot.raw.event.detail.TakControl
95
- && cot.raw.event.detail.TakControl.TakServerVersionInfo
96
- && cot.raw.event.detail.TakControl.TakServerVersionInfo._attributes) {
97
- this.version = cot.raw.event.detail.TakControl.TakServerVersionInfo._attributes.serverVersion;
98
- }
99
- else {
100
- this.emit('cot', cot);
101
- }
102
- }
103
- catch (e) {
104
- console.error('Error parsing', e, data.toString());
105
- }
106
- buff = result.remainder;
107
- result = TAK.findCoT(buff);
108
- }
109
- }).on('timeout', () => {
110
- this.emit('timeout');
111
- }).on('error', (err) => {
112
- this.emit('error', err);
113
- }).on('end', () => {
114
- this.open = false;
115
- this.emit('end');
116
- });
117
- this.pingInterval = setInterval(() => {
118
- this.ping();
119
- }, 5000);
120
- return resolve(this);
121
- });
122
- }
123
- async reconnect() {
124
- if (this.destroyed) {
125
- await this.connect_ssl();
126
- }
127
- else {
128
- this.destroy();
129
- await this.connect_ssl();
130
- }
131
- }
132
- destroy() {
133
- this.destroyed = true;
134
- if (this.client) {
135
- this.client.destroy();
136
- }
137
- if (this.pingInterval) {
138
- clearInterval(this.pingInterval);
139
- this.pingInterval = undefined;
140
- }
141
- }
142
- async ping() {
143
- this.write([CoT.ping()]);
144
- }
145
- writer(body) {
146
- return new Promise((resolve, reject) => {
147
- if (!this.client)
148
- return reject(new Error('A Connection Client must first be created before it can be written'));
149
- const res = this.client.write(body + '\n', () => {
150
- return resolve(res);
151
- });
152
- });
153
- }
154
- async process() {
155
- this.writing = true;
156
- while (this.queue.length) {
157
- const body = this.queue.shift();
158
- if (!body)
159
- continue;
160
- await this.writer(body);
161
- }
162
- await this.writer('');
163
- if (this.queue.length) {
164
- process.nextTick(() => {
165
- this.process();
166
- });
167
- }
168
- else {
169
- this.writing = false;
170
- }
171
- }
172
- /**
173
- * Write a CoT to the TAK Connection
174
- *
175
- * @param {CoT} cot CoT Object
176
- */
177
- async write(cots) {
178
- for (const cot of cots) {
179
- this.queue.push(await CoTParser.to_xml(cot));
180
- }
181
- if (this.queue.length && !this.writing) {
182
- this.process();
183
- }
184
- }
185
- write_xml(body) {
186
- this.queue.push(body);
187
- if (this.queue.length && !this.writing) {
188
- this.process();
189
- }
190
- }
191
- // https://github.com/vidterra/multitak/blob/main/app/lib/helper.js#L4
192
- static findCoT(str) {
193
- str = str.replace(REGEX_CONTROL, "");
194
- const match = str.match(REGEX_EVENT); // find first CoT
195
- if (!match)
196
- return null;
197
- return {
198
- event: match[1],
199
- remainder: match[2],
200
- };
201
- }
202
- }
203
- export { TAKAPI, CoT, };
204
- //# sourceMappingURL=index.js.map