@openfin/cloud-interop-core-api 0.0.1-alpha.384d88e → 0.0.1-alpha.3cbe14e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{src/api.d.ts → api.d.ts} +1 -26
- package/dist/index.cjs +101 -275
- package/dist/index.mjs +3856 -275
- package/dist/{src/interfaces.d.ts → interfaces.d.ts} +17 -0
- package/package.json +5 -5
- package/dist/tests/connect.test.d.ts +0 -1
- package/dist/tests/context.test.d.ts +0 -1
- package/dist/tests/mocks/fetch.mock.d.ts +0 -128
- /package/dist/{src/errors → errors}/api.error.d.ts +0 -0
- /package/dist/{src/index.d.ts → index.d.ts} +0 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { EndReportIntentsEvent, Intent, IntentDetailsEvent, IntentResultEvent, InvokeIntentEvent, ReportIntentsEvent } from '@openfin-direct/shared-utils';
|
|
2
1
|
import mqtt from 'mqtt';
|
|
3
|
-
import { CloudInteropSettings, ConnectParameters, ContextEvent } from './interfaces';
|
|
2
|
+
import { CloudInteropSettings, ConnectParameters as ConnectParameters, ContextEvent } from './interfaces';
|
|
4
3
|
type CreateSessionResponse = {
|
|
5
4
|
sessionId: string;
|
|
6
5
|
sessionRootTopic: string;
|
|
@@ -18,11 +17,6 @@ type EventMap = {
|
|
|
18
17
|
reconnecting: (attemptNo: number) => void;
|
|
19
18
|
error: (error: Error) => void;
|
|
20
19
|
'session-expired': () => void;
|
|
21
|
-
'report-intents': (event: ReportIntentsEvent) => void;
|
|
22
|
-
'end-report-intents': (event: EndReportIntentsEvent) => void;
|
|
23
|
-
'intent-details': (event: IntentDetailsEvent) => void;
|
|
24
|
-
'invoke-intent': (event: InvokeIntentEvent) => void;
|
|
25
|
-
'intent-result': (event: IntentResultEvent) => void;
|
|
26
20
|
};
|
|
27
21
|
/**
|
|
28
22
|
* Represents a single connection to a Cloud Interop service
|
|
@@ -63,25 +57,6 @@ export declare class CloudInteropAPI {
|
|
|
63
57
|
* @memberof CloudInteropAPI
|
|
64
58
|
*/
|
|
65
59
|
setContext(contextGroup: string, context: object): Promise<void>;
|
|
66
|
-
/**
|
|
67
|
-
* Starts an intent discovery operation
|
|
68
|
-
*
|
|
69
|
-
* @return {*} {Promise<void>}
|
|
70
|
-
* @memberof CloudInteropAPI
|
|
71
|
-
* @throws {CloudInteropAPIError} - If an error occurs during intent discovery
|
|
72
|
-
*/
|
|
73
|
-
startIntentDiscovery(): Promise<void>;
|
|
74
|
-
/**
|
|
75
|
-
* Ends an intent discovery operation
|
|
76
|
-
*
|
|
77
|
-
* @return {*} {Promise<void>}
|
|
78
|
-
* @memberof CloudInteropAPI
|
|
79
|
-
* @throws {CloudInteropAPIError} - If an error occurs during stopping intent discovery
|
|
80
|
-
*/
|
|
81
|
-
endIntentDiscovery(): Promise<void>;
|
|
82
|
-
raiseIntent(intent: Intent, targetSessionId: string): Promise<void>;
|
|
83
|
-
reportSupportedIntents(discoveryId: string, intents: Intent[]): Promise<void>;
|
|
84
|
-
sendIntentResult(resultEvent: IntentResultEvent): Promise<void>;
|
|
85
60
|
addEventListener<K extends keyof EventMap>(type: K, callback: EventMap[K]): void;
|
|
86
61
|
removeEventListener<K extends keyof EventMap>(type: K, callback: EventMap[K]): void;
|
|
87
62
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var axios = require('axios');
|
|
3
4
|
var mqtt = require('mqtt');
|
|
4
5
|
|
|
5
6
|
class CloudInteropAPIError extends Error {
|
|
@@ -38,7 +39,6 @@ class CloudInteropAPI {
|
|
|
38
39
|
#connectionParams;
|
|
39
40
|
#eventListeners = new Map();
|
|
40
41
|
#attemptingToReconnect = false;
|
|
41
|
-
#currentIntentDiscoveryId;
|
|
42
42
|
constructor(cloudInteropSettings) {
|
|
43
43
|
this.#cloudInteropSettings = cloudInteropSettings;
|
|
44
44
|
}
|
|
@@ -64,99 +64,105 @@ class CloudInteropAPI {
|
|
|
64
64
|
this.#keepAliveIntervalSeconds = parameters.keepAliveIntervalSeconds || this.#keepAliveIntervalSeconds;
|
|
65
65
|
this.#logger = parameters.logger || this.#logger;
|
|
66
66
|
const { sourceId, platformId } = this.#connectionParams;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
throw new CloudInteropAPIError();
|
|
77
|
-
}
|
|
78
|
-
if (createSessionResponse.status !== 201) {
|
|
79
|
-
throw new CloudInteropAPIError(`Failed to connect to the Cloud Interop service: ${this.#cloudInteropSettings.url}`, 'ERR_CONNECT', new Error(createSessionResponse.statusText));
|
|
80
|
-
}
|
|
81
|
-
this.#sessionDetails = (await createSessionResponse.json());
|
|
82
|
-
const sessionRootTopic = this.#sessionDetails.sessionRootTopic;
|
|
83
|
-
const clientOptions = {
|
|
84
|
-
keepalive: this.#keepAliveIntervalSeconds,
|
|
85
|
-
clientId: this.#sessionDetails.sessionId,
|
|
86
|
-
clean: true,
|
|
87
|
-
protocolVersion: 5,
|
|
88
|
-
// The "will" message will be published on an unexpected disconnection
|
|
89
|
-
// The server can then tidy up. So it needs every for this client to do that, the session details is perfect
|
|
90
|
-
will: {
|
|
91
|
-
topic: 'interop/lastwill',
|
|
92
|
-
payload: Buffer.from(JSON.stringify(this.#sessionDetails)),
|
|
93
|
-
qos: 0,
|
|
94
|
-
retain: false,
|
|
95
|
-
},
|
|
96
|
-
username: this.#sessionDetails.token,
|
|
97
|
-
};
|
|
98
|
-
this.#mqttClient = await mqtt.connectAsync(this.#sessionDetails.url, clientOptions);
|
|
99
|
-
this.#logger('log', `Cloud Interop successfully connected to ${this.#cloudInteropSettings.url}`);
|
|
100
|
-
this.#mqttClient.on('error', async (error) => {
|
|
101
|
-
// We will receive errors for each failed reconnection attempt
|
|
102
|
-
// We don't won't to disconnect on these else we will never reconnect
|
|
103
|
-
if (!this.#attemptingToReconnect) {
|
|
104
|
-
await this.#disconnect(false);
|
|
67
|
+
try {
|
|
68
|
+
const createSessionResponse = await axios.post(`${this.#cloudInteropSettings.url}/api/sessions`, {
|
|
69
|
+
sourceId,
|
|
70
|
+
platformId,
|
|
71
|
+
}, {
|
|
72
|
+
headers: this.#getRequestHeaders(),
|
|
73
|
+
});
|
|
74
|
+
if (createSessionResponse.status !== 201) {
|
|
75
|
+
throw new CloudInteropAPIError(`Failed to connect to the Cloud Interop service: ${this.#cloudInteropSettings.url}`, 'ERR_CONNECT', createSessionResponse.status);
|
|
105
76
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
77
|
+
this.#sessionDetails = createSessionResponse.data;
|
|
78
|
+
const sessionRootTopic = this.#sessionDetails.sessionRootTopic;
|
|
79
|
+
const clientOptions = {
|
|
80
|
+
keepalive: this.#keepAliveIntervalSeconds,
|
|
81
|
+
clientId: this.#sessionDetails.sessionId,
|
|
82
|
+
clean: true,
|
|
83
|
+
protocolVersion: 5,
|
|
84
|
+
// The "will" message will be published on an unexpected disconnection
|
|
85
|
+
// The server can then tidy up. So it needs every for this client to do that, the session details is perfect
|
|
86
|
+
will: {
|
|
87
|
+
topic: 'interop/lastwill',
|
|
88
|
+
payload: Buffer.from(JSON.stringify(this.#sessionDetails)),
|
|
89
|
+
qos: 0,
|
|
90
|
+
retain: false,
|
|
91
|
+
},
|
|
92
|
+
username: this.#sessionDetails.token,
|
|
93
|
+
};
|
|
94
|
+
this.#mqttClient = await mqtt.connectAsync(this.#sessionDetails.url, clientOptions);
|
|
95
|
+
this.#logger('log', `Cloud Interop successfully connected to ${this.#cloudInteropSettings.url}`);
|
|
96
|
+
this.#mqttClient.on('error', async (error) => {
|
|
97
|
+
// We will receive errors for each failed reconnection attempt
|
|
98
|
+
// We don't won't to disconnect on these else we will never reconnect
|
|
99
|
+
if (!this.#attemptingToReconnect) {
|
|
100
|
+
await this.#disconnect(false);
|
|
101
|
+
}
|
|
102
|
+
if (error instanceof mqtt.ErrorWithReasonCode) {
|
|
103
|
+
switch (error.code) {
|
|
104
|
+
case BadUserNamePasswordError: {
|
|
105
|
+
await this.#disconnect(false);
|
|
106
|
+
this.#logger('warn', `Session expired`);
|
|
107
|
+
this.#emitEvent('session-expired');
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
default: {
|
|
111
|
+
this.#logger('error', `Unknown Infrastructure Error Code ${error.code} : ${error.message}${this.#attemptingToReconnect ? ' during reconnection attempt' : ''}`);
|
|
112
|
+
// As we are in the middle of a reconnect, lets not emit an error to cut down on the event noise
|
|
113
|
+
if (!this.#attemptingToReconnect) {
|
|
114
|
+
this.#emitEvent('error', new CloudInteropAPIError(`Unknown Infrastructure Error Code ${error.code} : ${error.message}`, 'ERR_INFRASTRUCTURE', error));
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
120
117
|
}
|
|
121
118
|
}
|
|
122
119
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
120
|
+
else {
|
|
121
|
+
this.#logger('error', `Unknown Error${this.#attemptingToReconnect ? ' during reconnection attempt' : ''}: ${error}`);
|
|
122
|
+
// As we are in the middle of a reconnect, lets not emit an error to cut down on the event noise
|
|
123
|
+
if (!this.#attemptingToReconnect) {
|
|
124
|
+
this.#emitEvent('error', new CloudInteropAPIError(`Unknown Error`, 'ERR_UNKNOWN', error));
|
|
125
|
+
}
|
|
129
126
|
}
|
|
127
|
+
});
|
|
128
|
+
this.#mqttClient.on('reconnect', () => {
|
|
129
|
+
this.#attemptingToReconnect = true;
|
|
130
|
+
this.#reconnectRetries += 1;
|
|
131
|
+
this.#logger('debug', `Cloud Interop attempting reconnection - ${this.#reconnectRetries}...`);
|
|
132
|
+
if (this.#reconnectRetries === this.#reconnectRetryLimit) {
|
|
133
|
+
this.#logger('warn', `Cloud Interop reached max reconnection attempts - ${this.#reconnectRetryLimit}...`);
|
|
134
|
+
this.#disconnect(true);
|
|
135
|
+
}
|
|
136
|
+
this.#emitEvent('reconnecting', this.#reconnectRetries);
|
|
137
|
+
});
|
|
138
|
+
// Does not fire on initial connection, only successful reconnection attempts
|
|
139
|
+
this.#mqttClient.on('connect', () => {
|
|
140
|
+
this.#logger('debug', `Cloud Interop successfully reconnected after ${this.#reconnectRetries} attempts`);
|
|
141
|
+
this.#reconnectRetries = 0;
|
|
142
|
+
this.#attemptingToReconnect = false;
|
|
143
|
+
this.#emitEvent('reconnected');
|
|
144
|
+
});
|
|
145
|
+
this.#mqttClient.on('message', (topic, message) => {
|
|
146
|
+
if (!this.#sessionDetails) {
|
|
147
|
+
this.#logger('warn', 'Received message when session not connected');
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
this.#handleCommand(topic, message, this.#sessionDetails);
|
|
151
|
+
});
|
|
152
|
+
// Subscribe to all context groups
|
|
153
|
+
this.#mqttClient.subscribe(`${sessionRootTopic}/context-groups/#`);
|
|
154
|
+
// Listen out for global commands
|
|
155
|
+
this.#mqttClient.subscribe(`${sessionRootTopic}/commands`);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
if (axios.isAxiosError(error)) {
|
|
159
|
+
if (error.response?.status === 401 || error.response?.status === 403) {
|
|
160
|
+
throw new AuthorizationError();
|
|
161
|
+
}
|
|
162
|
+
throw new CloudInteropAPIError();
|
|
130
163
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
this.#attemptingToReconnect = true;
|
|
134
|
-
this.#reconnectRetries += 1;
|
|
135
|
-
this.#logger('debug', `Cloud Interop attempting reconnection - ${this.#reconnectRetries}...`);
|
|
136
|
-
if (this.#reconnectRetries === this.#reconnectRetryLimit) {
|
|
137
|
-
this.#logger('warn', `Cloud Interop reached max reconnection attempts - ${this.#reconnectRetryLimit}...`);
|
|
138
|
-
this.#disconnect(true);
|
|
139
|
-
}
|
|
140
|
-
this.#emitEvent('reconnecting', this.#reconnectRetries);
|
|
141
|
-
});
|
|
142
|
-
// Does not fire on initial connection, only successful reconnection attempts
|
|
143
|
-
this.#mqttClient.on('connect', () => {
|
|
144
|
-
this.#logger('debug', `Cloud Interop successfully reconnected after ${this.#reconnectRetries} attempts`);
|
|
145
|
-
this.#reconnectRetries = 0;
|
|
146
|
-
this.#attemptingToReconnect = false;
|
|
147
|
-
this.#emitEvent('reconnected');
|
|
148
|
-
});
|
|
149
|
-
this.#mqttClient.on('message', (topic, message) => {
|
|
150
|
-
if (!this.#sessionDetails) {
|
|
151
|
-
this.#logger('warn', 'Received message when session not connected');
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
this.#handleMessage(topic, message, this.#sessionDetails);
|
|
155
|
-
});
|
|
156
|
-
// Subscribe to all context groups
|
|
157
|
-
this.#mqttClient.subscribe(`${sessionRootTopic}/context-groups/#`);
|
|
158
|
-
// Listen out for global commands
|
|
159
|
-
this.#mqttClient.subscribe(`${sessionRootTopic}/commands`);
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
160
166
|
}
|
|
161
167
|
/**
|
|
162
168
|
* Disconnects from the Cloud Interop service
|
|
@@ -184,120 +190,9 @@ class CloudInteropAPI {
|
|
|
184
190
|
context,
|
|
185
191
|
timestamp: Date.now(),
|
|
186
192
|
};
|
|
187
|
-
|
|
188
|
-
method: 'POST',
|
|
189
|
-
headers: this.#getRequestHeaders(),
|
|
190
|
-
body: JSON.stringify(payload),
|
|
191
|
-
});
|
|
192
|
-
if (!postResponse.ok) {
|
|
193
|
-
throw new CloudInteropAPIError(`Error setting context for ${contextGroup}`, 'ERR_SETTING_CONTEXT', new Error(postResponse.statusText));
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Starts an intent discovery operation
|
|
198
|
-
*
|
|
199
|
-
* @return {*} {Promise<void>}
|
|
200
|
-
* @memberof CloudInteropAPI
|
|
201
|
-
* @throws {CloudInteropAPIError} - If an error occurs during intent discovery
|
|
202
|
-
*/
|
|
203
|
-
async startIntentDiscovery() {
|
|
204
|
-
if (!this.#sessionDetails || !this.#connectionParams) {
|
|
205
|
-
throw new Error('Session not connected');
|
|
206
|
-
}
|
|
207
|
-
if (!this.#mqttClient) {
|
|
208
|
-
throw new Error('MQTT client not connected');
|
|
209
|
-
}
|
|
210
|
-
if (this.#currentIntentDiscoveryId) {
|
|
211
|
-
throw new Error('Intent discovery already in progress');
|
|
212
|
-
}
|
|
213
|
-
try {
|
|
214
|
-
const startResponse = await fetch(`${this.#cloudInteropSettings.url}/api/intents/${this.#sessionDetails.sessionId}`, {
|
|
215
|
-
method: 'POST',
|
|
216
|
-
headers: this.#getRequestHeaders(),
|
|
217
|
-
});
|
|
218
|
-
if (!startResponse.ok) {
|
|
219
|
-
throw new Error(startResponse.statusText);
|
|
220
|
-
}
|
|
221
|
-
const json = await startResponse.json();
|
|
222
|
-
this.#currentIntentDiscoveryId = json.discoveryId;
|
|
223
|
-
// Listen out for discovery results directly send to us
|
|
224
|
-
await this.#mqttClient.subscribeAsync(`${this.#sessionDetails.sessionRootTopic}/commands/${this.#currentIntentDiscoveryId}`);
|
|
225
|
-
}
|
|
226
|
-
catch (error) {
|
|
227
|
-
throw new CloudInteropAPIError('Error starting intent discovery', 'ERR_STARTING_INTENT_DISCOVERY', error);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Ends an intent discovery operation
|
|
232
|
-
*
|
|
233
|
-
* @return {*} {Promise<void>}
|
|
234
|
-
* @memberof CloudInteropAPI
|
|
235
|
-
* @throws {CloudInteropAPIError} - If an error occurs during stopping intent discovery
|
|
236
|
-
*/
|
|
237
|
-
async endIntentDiscovery() {
|
|
238
|
-
if (!this.#sessionDetails || !this.#connectionParams) {
|
|
239
|
-
throw new Error('Session not connected');
|
|
240
|
-
}
|
|
241
|
-
if (!this.#currentIntentDiscoveryId) {
|
|
242
|
-
throw new Error('Intent discovery not already in progress');
|
|
243
|
-
}
|
|
244
|
-
if (!this.#mqttClient) {
|
|
245
|
-
throw new Error('MQTT client not connected');
|
|
246
|
-
}
|
|
247
|
-
try {
|
|
248
|
-
await this.#mqttClient.unsubscribeAsync(`${this.#sessionDetails.sessionRootTopic}/commands/${this.#currentIntentDiscoveryId}`);
|
|
249
|
-
const deleteResponse = await fetch(`${this.#cloudInteropSettings.url}/api/intents/${this.#sessionDetails.sessionId}/${this.#currentIntentDiscoveryId}`, {
|
|
250
|
-
method: 'DELETE',
|
|
251
|
-
headers: this.#getRequestHeaders(),
|
|
252
|
-
});
|
|
253
|
-
if (!deleteResponse.ok) {
|
|
254
|
-
throw new Error(deleteResponse.statusText);
|
|
255
|
-
}
|
|
256
|
-
this.#currentIntentDiscoveryId = undefined;
|
|
257
|
-
}
|
|
258
|
-
catch (error) {
|
|
259
|
-
throw new CloudInteropAPIError('Error ending intent discovery', 'ERR_ENDING_INTENT_DISCOVERY', error);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
async raiseIntent(intent, targetSessionId) {
|
|
263
|
-
if (!this.#sessionDetails || !this.#connectionParams) {
|
|
264
|
-
throw new Error('Session not connected');
|
|
265
|
-
}
|
|
266
|
-
const postResponse = await fetch(`${this.#cloudInteropSettings.url}/api/intents/${this.#sessionDetails.sessionId}/sessions/${targetSessionId}`, {
|
|
267
|
-
method: 'POST',
|
|
268
|
-
headers: this.#getRequestHeaders(),
|
|
269
|
-
body: JSON.stringify({ intent }),
|
|
270
|
-
});
|
|
271
|
-
if (!postResponse.ok) {
|
|
272
|
-
throw new CloudInteropAPIError(`Error raising intent: ${intent.intentMetadata.name}`, 'ERR_RAISING_INTENT', new Error(postResponse.statusText));
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
async reportSupportedIntents(discoveryId, intents) {
|
|
276
|
-
if (!this.#sessionDetails || !this.#connectionParams) {
|
|
277
|
-
throw new Error('Session not connected');
|
|
278
|
-
}
|
|
279
|
-
const reportResponse = await fetch(`${this.#cloudInteropSettings.url}/api/intents/${this.#sessionDetails.sessionId}/${discoveryId}`, {
|
|
280
|
-
method: 'POST',
|
|
281
|
-
headers: this.#getRequestHeaders(),
|
|
282
|
-
body: JSON.stringify({ intents }),
|
|
283
|
-
});
|
|
284
|
-
if (!reportResponse.ok) {
|
|
285
|
-
throw new CloudInteropAPIError('Error starting intent discovery', 'ERR_REPORTING_INTENTS', new Error(reportResponse.statusText));
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
async sendIntentResult(resultEvent) {
|
|
289
|
-
if (!this.#sessionDetails || !this.#connectionParams) {
|
|
290
|
-
throw new Error('Session not connected');
|
|
291
|
-
}
|
|
292
|
-
const { initiatingSessionId, result, sessionId } = resultEvent;
|
|
293
|
-
const resultResponse = await fetch(`${this.#cloudInteropSettings.url}/api/intents/${initiatingSessionId}/result/${sessionId}`, {
|
|
294
|
-
method: 'POST',
|
|
193
|
+
await axios.post(`${this.#cloudInteropSettings.url}/api/context-groups/${this.#sessionDetails.sessionId}/${contextGroup}`, payload, {
|
|
295
194
|
headers: this.#getRequestHeaders(),
|
|
296
|
-
body: JSON.stringify({ result }),
|
|
297
195
|
});
|
|
298
|
-
if (!resultResponse.ok) {
|
|
299
|
-
throw new CloudInteropAPIError('Error sending intent result', 'ERR_SENDING_INTENT_RESULT', new Error(resultResponse.statusText));
|
|
300
|
-
}
|
|
301
196
|
}
|
|
302
197
|
addEventListener(type, callback) {
|
|
303
198
|
const listeners = this.#eventListeners.get(type) || [];
|
|
@@ -317,16 +212,15 @@ class CloudInteropAPI {
|
|
|
317
212
|
return;
|
|
318
213
|
}
|
|
319
214
|
try {
|
|
320
|
-
const disconnectResponse = await
|
|
321
|
-
method: 'DELETE',
|
|
215
|
+
const disconnectResponse = await axios.delete(`${this.#cloudInteropSettings.url}/api/sessions/${this.#sessionDetails.sessionId}`, {
|
|
322
216
|
headers: this.#getRequestHeaders(),
|
|
323
217
|
});
|
|
324
218
|
if (disconnectResponse.status !== 200) {
|
|
325
|
-
throw new CloudInteropAPIError('Error during session tear down - unexpected status', 'ERR_DISCONNECT',
|
|
219
|
+
throw new CloudInteropAPIError('Error during session tear down - unexpected status', 'ERR_DISCONNECT', disconnectResponse.status);
|
|
326
220
|
}
|
|
327
221
|
}
|
|
328
|
-
catch
|
|
329
|
-
throw new CloudInteropAPIError('Error during disconnection', 'ERR_DISCONNECT'
|
|
222
|
+
catch {
|
|
223
|
+
throw new CloudInteropAPIError('Error during disconnection', 'ERR_DISCONNECT');
|
|
330
224
|
}
|
|
331
225
|
finally {
|
|
332
226
|
this.#mqttClient?.removeAllListeners();
|
|
@@ -335,13 +229,12 @@ class CloudInteropAPI {
|
|
|
335
229
|
this.#mqttClient = undefined;
|
|
336
230
|
this.#reconnectRetries = 0;
|
|
337
231
|
this.#attemptingToReconnect = false;
|
|
338
|
-
this.#currentIntentDiscoveryId = undefined;
|
|
339
232
|
if (fireDisconnectedEvent) {
|
|
340
233
|
this.#emitEvent('disconnected');
|
|
341
234
|
}
|
|
342
235
|
}
|
|
343
236
|
}
|
|
344
|
-
#
|
|
237
|
+
#handleCommand(topic, message, sessionDetails) {
|
|
345
238
|
if (message.length === 0 || !sessionDetails) {
|
|
346
239
|
// Ignore clean up messages
|
|
347
240
|
return;
|
|
@@ -354,73 +247,6 @@ class CloudInteropAPI {
|
|
|
354
247
|
const { channelName: contextGroup, payload: context, source, history } = messageEnvelope;
|
|
355
248
|
this.#emitEvent('context', { contextGroup, context, source, history: { ...history, clientReceived: Date.now() } });
|
|
356
249
|
}
|
|
357
|
-
else if (topic.startsWith(`${sessionDetails.sessionRootTopic}/commands`)) {
|
|
358
|
-
this.#handleCommandMessage(messageEnvelope);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
#handleCommandMessage(message) {
|
|
362
|
-
switch (message.command) {
|
|
363
|
-
case 'report-intents': {
|
|
364
|
-
if (message.initiatingSessionId === this.#sessionDetails?.sessionId) {
|
|
365
|
-
// Ignore if this originated from us
|
|
366
|
-
return;
|
|
367
|
-
}
|
|
368
|
-
this.#emitEvent('report-intents', {
|
|
369
|
-
discoveryId: message.discoveryId,
|
|
370
|
-
initiatingSessionId: message.initiatingSessionId,
|
|
371
|
-
sessionId: message.sessionId,
|
|
372
|
-
});
|
|
373
|
-
break;
|
|
374
|
-
}
|
|
375
|
-
case 'intent-details': {
|
|
376
|
-
if (message.discoveryId !== this.#currentIntentDiscoveryId) {
|
|
377
|
-
// Ignore if its any other discovery id for some reason
|
|
378
|
-
return;
|
|
379
|
-
}
|
|
380
|
-
this.#emitEvent('intent-details', {
|
|
381
|
-
discoveryId: message.discoveryId,
|
|
382
|
-
initiatingSessionId: message.initiatingSessionId,
|
|
383
|
-
sessionId: message.sessionId,
|
|
384
|
-
intents: message.intents,
|
|
385
|
-
});
|
|
386
|
-
break;
|
|
387
|
-
}
|
|
388
|
-
case 'end-report-intents': {
|
|
389
|
-
if (message.initiatingSessionId === this.#sessionDetails?.sessionId) {
|
|
390
|
-
// Ignore if this originated from us
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
this.#emitEvent('end-report-intents', {
|
|
394
|
-
discoveryId: message.discoveryId,
|
|
395
|
-
initiatingSessionId: message.initiatingSessionId,
|
|
396
|
-
sessionId: message.sessionId,
|
|
397
|
-
});
|
|
398
|
-
break;
|
|
399
|
-
}
|
|
400
|
-
case 'invoke-intent': {
|
|
401
|
-
if (message.sessionId === this.#sessionDetails?.sessionId) {
|
|
402
|
-
this.#emitEvent('invoke-intent', {
|
|
403
|
-
initiatingSessionId: message.initiatingSessionId,
|
|
404
|
-
intent: message.intent,
|
|
405
|
-
sessionId: message.sessionId,
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
break;
|
|
409
|
-
}
|
|
410
|
-
case 'intent-result': {
|
|
411
|
-
if (message.initiatingSessionId === this.#sessionDetails?.sessionId) {
|
|
412
|
-
// Return result to originator and end discovery
|
|
413
|
-
const { command: _, ...resultEvent } = message;
|
|
414
|
-
this.#emitEvent('intent-result', resultEvent);
|
|
415
|
-
this.endIntentDiscovery().catch(() => undefined);
|
|
416
|
-
}
|
|
417
|
-
break;
|
|
418
|
-
}
|
|
419
|
-
default: {
|
|
420
|
-
this.#logger('warn', `Unknown command message received: ${message}`);
|
|
421
|
-
break;
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
250
|
}
|
|
425
251
|
#emitEvent(type, ...args) {
|
|
426
252
|
const listeners = this.#eventListeners.get(type) || [];
|
|
@@ -449,7 +275,7 @@ class CloudInteropAPI {
|
|
|
449
275
|
if (!this.#connectionParams) {
|
|
450
276
|
throw new Error('Connect parameters must be provided');
|
|
451
277
|
}
|
|
452
|
-
const headers =
|
|
278
|
+
const headers = new axios.AxiosHeaders();
|
|
453
279
|
headers['Content-Type'] = 'application/json';
|
|
454
280
|
if (this.#connectionParams.authenticationType === 'jwt' && this.#connectionParams.jwtAuthenticationParameters) {
|
|
455
281
|
const tokenResult = this.#connectionParams.jwtAuthenticationParameters.jwtRequestCallback();
|