@sprucelabs/mercury-client 41.0.385 → 42.0.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/build/.spruce/errors/errors.types.d.ts +50 -50
- package/build/.spruce/errors/errors.types.js +0 -2
- package/build/.spruce/errors/mercuryClient/connectionFailed.schema.js +5 -5
- package/build/.spruce/errors/mercuryClient/invalidEventSignature.schema.js +5 -5
- package/build/.spruce/errors/mercuryClient/invalidPayload.schema.js +3 -3
- package/build/.spruce/errors/mercuryClient/invalidProtocol.schema.js +3 -3
- package/build/.spruce/errors/mercuryClient/missingTestCacheDir.schema.js +1 -1
- package/build/.spruce/errors/mercuryClient/mustCreateEvent.schema.js +3 -3
- package/build/.spruce/errors/mercuryClient/mustHandleLocally.schema.js +3 -3
- package/build/.spruce/errors/mercuryClient/notConnected.schema.js +5 -5
- package/build/.spruce/errors/mercuryClient/timeout.schema.js +9 -9
- package/build/.spruce/errors/mercuryClient/unauthorizedAccess.schema.js +9 -9
- package/build/.spruce/errors/mercuryClient/unauthorizedTarget.schema.js +11 -11
- package/build/.spruce/errors/mercuryClient/unexpectedPayload.schema.js +3 -3
- package/build/.spruce/errors/mercuryClient/unknownError.schema.js +1 -1
- package/build/.spruce/errors/options.types.d.ts +2 -2
- package/build/.spruce/schemas/fields/fields.types.d.ts +1 -1
- package/build/.spruce/schemas/schemas.types.js +0 -2
- package/build/clients/MercuryClientFactory.js +11 -10
- package/build/clients/MercurySocketIoClient.d.ts +3 -1
- package/build/clients/MercurySocketIoClient.js +79 -81
- package/build/clients/MercuryTestClient.d.ts +1 -1
- package/build/clients/MercuryTestClient.js +50 -41
- package/build/clients/MutableContractClient.js +7 -6
- package/build/errors/SpruceError.d.ts +1 -1
- package/build/errors/SpruceError.js +7 -5
- package/build/esm/.spruce/errors/errors.types.d.ts +50 -50
- package/build/esm/.spruce/errors/errors.types.js +0 -2
- package/build/esm/.spruce/errors/options.types.d.ts +2 -2
- package/build/esm/clients/MercurySocketIoClient.d.ts +3 -1
- package/build/esm/clients/MercurySocketIoClient.js +11 -2
- package/build/esm/clients/MercuryTestClient.d.ts +1 -1
- package/build/esm/clients/MercuryTestClient.js +18 -9
- package/build/esm/clients/MutableContractClient.js +3 -1
- package/build/esm/errors/SpruceError.d.ts +1 -1
- package/build/esm/errors/SpruceError.js +5 -2
- package/build/tests/AbstractClientTest.js +12 -18
- package/build/tests/constants.js +9 -10
- package/package.json +115 -129
|
@@ -9,10 +9,15 @@ const constants_1 = require("../constants");
|
|
|
9
9
|
const SpruceError_1 = __importDefault(require("../errors/SpruceError"));
|
|
10
10
|
const MutableContractClient_1 = __importDefault(require("./MutableContractClient"));
|
|
11
11
|
class MercuryClientFactory {
|
|
12
|
+
static isTestMode = false;
|
|
13
|
+
static defaultContract;
|
|
14
|
+
static timeoutMs = 30000;
|
|
15
|
+
static totalClients = 0;
|
|
16
|
+
static clients = [];
|
|
17
|
+
static ClientClass;
|
|
12
18
|
static async Client(connectionOptions) {
|
|
13
|
-
var _a;
|
|
14
19
|
const { host: hostOption, contracts, reconnectDelayMs, allowSelfSignedCrt, emitTimeoutMs = this.timeoutMs, shouldReconnect, maxEmitRetries, connectionRetries, } = connectionOptions || {};
|
|
15
|
-
const host = hostOption
|
|
20
|
+
const host = hostOption ?? constants_1.DEFAULT_HOST;
|
|
16
21
|
if (host.substr(0, 4) !== 'http') {
|
|
17
22
|
throw new SpruceError_1.default({ code: 'INVALID_PROTOCOL', uri: host });
|
|
18
23
|
}
|
|
@@ -25,15 +30,15 @@ class MercuryClientFactory {
|
|
|
25
30
|
const eventContract = !contracts && this.defaultContract
|
|
26
31
|
? this.defaultContract
|
|
27
32
|
: //@ts-ignore
|
|
28
|
-
spruce_event_utils_1.eventContractUtil.unifyContracts(contracts
|
|
33
|
+
spruce_event_utils_1.eventContractUtil.unifyContracts(contracts ?? []);
|
|
29
34
|
let Client = MutableContractClient_1.default;
|
|
30
35
|
if (this.isTestMode) {
|
|
31
36
|
//TODO, make this something fitxures sets to make the test client available
|
|
32
37
|
Client = require('../clients/MercuryTestClient').default;
|
|
33
38
|
}
|
|
34
|
-
const client = new (
|
|
35
|
-
|
|
36
|
-
|
|
39
|
+
const client = new (MercuryClientFactory.ClientClass ??
|
|
40
|
+
//@ts-ignore
|
|
41
|
+
Client)({
|
|
37
42
|
host,
|
|
38
43
|
reconnection: false,
|
|
39
44
|
reconnectDelayMs,
|
|
@@ -83,8 +88,4 @@ class MercuryClientFactory {
|
|
|
83
88
|
return this.clients;
|
|
84
89
|
}
|
|
85
90
|
}
|
|
86
|
-
MercuryClientFactory.isTestMode = false;
|
|
87
|
-
MercuryClientFactory.timeoutMs = 30000;
|
|
88
|
-
MercuryClientFactory.totalClients = 0;
|
|
89
|
-
MercuryClientFactory.clients = [];
|
|
90
91
|
exports.default = MercuryClientFactory;
|
|
@@ -3,7 +3,9 @@ import { Schema, SchemaValues } from '@sprucelabs/schema';
|
|
|
3
3
|
import { io, SocketOptions, ManagerOptions } from 'socket.io-client';
|
|
4
4
|
import { ConnectionOptions, MercuryClient } from '../types/client.types';
|
|
5
5
|
export default class MercurySocketIoClient<Contract extends EventContract> implements MercuryClient<Contract> {
|
|
6
|
-
protected
|
|
6
|
+
protected _eventContract?: Contract;
|
|
7
|
+
protected get eventContract(): Contract;
|
|
8
|
+
protected set eventContract(contract: Contract);
|
|
7
9
|
static io: typeof io;
|
|
8
10
|
private host;
|
|
9
11
|
private ioOptions;
|
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
-
var t = {};
|
|
4
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
-
t[p] = s[p];
|
|
6
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
-
t[p[i]] = s[p[i]];
|
|
10
|
-
}
|
|
11
|
-
return t;
|
|
12
|
-
};
|
|
13
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
4
|
};
|
|
@@ -22,46 +11,66 @@ const socket_io_client_1 = require("socket.io-client");
|
|
|
22
11
|
const SpruceError_1 = __importDefault(require("../errors/SpruceError"));
|
|
23
12
|
const socketIoEventUtil_utility_1 = __importDefault(require("../utilities/socketIoEventUtil.utility"));
|
|
24
13
|
class MercurySocketIoClient {
|
|
14
|
+
_eventContract;
|
|
15
|
+
get eventContract() {
|
|
16
|
+
return this._eventContract;
|
|
17
|
+
}
|
|
18
|
+
set eventContract(contract) {
|
|
19
|
+
this._eventContract = contract;
|
|
20
|
+
}
|
|
21
|
+
static io = socket_io_client_1.io;
|
|
22
|
+
host;
|
|
23
|
+
ioOptions;
|
|
24
|
+
socket;
|
|
25
|
+
proxyToken = null;
|
|
26
|
+
emitTimeoutMs;
|
|
27
|
+
reconnectDelayMs;
|
|
28
|
+
isReAuthing = false;
|
|
29
|
+
reconnectPromise = null;
|
|
30
|
+
lastAuthOptions;
|
|
31
|
+
shouldReconnect;
|
|
32
|
+
connectionRetriesRemaining = 5;
|
|
33
|
+
connectionRetries;
|
|
34
|
+
registeredListeners = [];
|
|
35
|
+
allowNextEventToBeAuthenticate = false;
|
|
36
|
+
auth;
|
|
37
|
+
shouldAutoRegisterListeners = true;
|
|
38
|
+
isManuallyDisconnected = false;
|
|
39
|
+
isReconnecting = false;
|
|
40
|
+
id;
|
|
41
|
+
skipWaitIfReconnecting = false;
|
|
42
|
+
maxEmitRetries;
|
|
43
|
+
authRawResults;
|
|
44
|
+
authPromise;
|
|
45
|
+
shouldRegisterProxyOnReconnect = false;
|
|
46
|
+
reconnectKey;
|
|
25
47
|
constructor(options) {
|
|
26
|
-
|
|
27
|
-
this.isReAuthing = false;
|
|
28
|
-
this.reconnectPromise = null;
|
|
29
|
-
this.connectionRetriesRemaining = 5;
|
|
30
|
-
this.registeredListeners = [];
|
|
31
|
-
this.allowNextEventToBeAuthenticate = false;
|
|
32
|
-
this.shouldAutoRegisterListeners = true;
|
|
33
|
-
this.isManuallyDisconnected = false;
|
|
34
|
-
this.isReconnecting = false;
|
|
35
|
-
this.skipWaitIfReconnecting = false;
|
|
36
|
-
this.shouldRegisterProxyOnReconnect = false;
|
|
37
|
-
const { host, eventContract, emitTimeoutMs, reconnectDelayMs, shouldReconnect, maxEmitRetries = 5, connectionRetries } = options, ioOptions = __rest(options, ["host", "eventContract", "emitTimeoutMs", "reconnectDelayMs", "shouldReconnect", "maxEmitRetries", "connectionRetries"]);
|
|
48
|
+
const { host, eventContract, emitTimeoutMs, reconnectDelayMs, shouldReconnect, maxEmitRetries = 5, connectionRetries, ...ioOptions } = options;
|
|
38
49
|
this.host = host;
|
|
39
|
-
this.ioOptions =
|
|
50
|
+
this.ioOptions = { ...ioOptions, withCredentials: false };
|
|
40
51
|
this.eventContract = eventContract;
|
|
41
|
-
this.emitTimeoutMs = emitTimeoutMs
|
|
42
|
-
this.reconnectDelayMs = reconnectDelayMs
|
|
43
|
-
this.shouldReconnect = shouldReconnect
|
|
52
|
+
this.emitTimeoutMs = emitTimeoutMs ?? 30000;
|
|
53
|
+
this.reconnectDelayMs = reconnectDelayMs ?? 5000;
|
|
54
|
+
this.shouldReconnect = shouldReconnect ?? true;
|
|
44
55
|
this.id = new Date().getTime().toString();
|
|
45
56
|
this.maxEmitRetries = maxEmitRetries;
|
|
46
|
-
this.connectionRetriesRemaining = connectionRetries
|
|
47
|
-
this.connectionRetries = connectionRetries
|
|
57
|
+
this.connectionRetriesRemaining = connectionRetries ?? 5;
|
|
58
|
+
this.connectionRetries = connectionRetries ?? 5;
|
|
48
59
|
}
|
|
49
60
|
async connect() {
|
|
50
61
|
this.socket = MercurySocketIoClient.io(this.host, this.ioOptions);
|
|
51
62
|
this.emitStatusChange('connecting');
|
|
52
63
|
await new Promise((resolve, reject) => {
|
|
53
|
-
|
|
54
|
-
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.on('connect', () => {
|
|
55
|
-
var _a, _b;
|
|
64
|
+
this.socket?.on('connect', () => {
|
|
56
65
|
this.connectionRetriesRemaining = this.connectionRetries;
|
|
57
66
|
//@ts-ignore
|
|
58
|
-
|
|
67
|
+
this.socket?.removeAllListeners();
|
|
59
68
|
this.log(`Connection established!`);
|
|
60
69
|
if (!this.isReconnecting) {
|
|
61
70
|
this.emitStatusChange('connected');
|
|
62
71
|
}
|
|
63
72
|
if (this.shouldReconnect) {
|
|
64
|
-
|
|
73
|
+
this.socket?.once('disconnect', async (opts) => {
|
|
65
74
|
this.log('Mercury disconnected, reason:', opts);
|
|
66
75
|
await this.attemptReconnectAfterDelay();
|
|
67
76
|
});
|
|
@@ -69,7 +78,7 @@ class MercurySocketIoClient {
|
|
|
69
78
|
this.attachConnectError();
|
|
70
79
|
resolve(undefined);
|
|
71
80
|
});
|
|
72
|
-
|
|
81
|
+
this.socket?.on('timeout', () => {
|
|
73
82
|
reject(new SpruceError_1.default({
|
|
74
83
|
code: 'TIMEOUT',
|
|
75
84
|
eventName: 'connect',
|
|
@@ -89,26 +98,24 @@ class MercurySocketIoClient {
|
|
|
89
98
|
});
|
|
90
99
|
}
|
|
91
100
|
attachConnectError(reject, resolve) {
|
|
92
|
-
|
|
93
|
-
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.on('connect_error', async (err) => {
|
|
94
|
-
var _a;
|
|
101
|
+
this.socket?.on('connect_error', async (err) => {
|
|
95
102
|
const error = this.mapSocketErrorToSpruceError(err);
|
|
96
103
|
//@ts-ignore
|
|
97
|
-
|
|
104
|
+
this.socket?.removeAllListeners();
|
|
98
105
|
this.log('Failed to connect to Mercury', error.message);
|
|
99
106
|
this.log('Connection retries left', `${this.connectionRetriesRemaining}`);
|
|
100
107
|
if (this.connectionRetriesRemaining === 0) {
|
|
101
|
-
reject
|
|
108
|
+
reject?.(error);
|
|
102
109
|
return;
|
|
103
110
|
}
|
|
104
111
|
try {
|
|
105
112
|
this.isReconnecting = false;
|
|
106
113
|
await this.attemptReconnectAfterDelay();
|
|
107
|
-
resolve
|
|
114
|
+
resolve?.();
|
|
108
115
|
}
|
|
109
116
|
catch (err) {
|
|
110
117
|
//@ts-ignore
|
|
111
|
-
reject
|
|
118
|
+
reject?.(err);
|
|
112
119
|
}
|
|
113
120
|
});
|
|
114
121
|
}
|
|
@@ -136,7 +143,6 @@ class MercurySocketIoClient {
|
|
|
136
143
|
return this.reconnectPromise;
|
|
137
144
|
}
|
|
138
145
|
async reconnect(resolve, reject, retriesLeft) {
|
|
139
|
-
var _a;
|
|
140
146
|
try {
|
|
141
147
|
this.connectionRetriesRemaining--;
|
|
142
148
|
const key = new Date().getTime();
|
|
@@ -174,7 +180,7 @@ class MercurySocketIoClient {
|
|
|
174
180
|
}
|
|
175
181
|
catch (err) {
|
|
176
182
|
;
|
|
177
|
-
(
|
|
183
|
+
(console.error ?? console.log)(err.message);
|
|
178
184
|
this.isReconnecting = false;
|
|
179
185
|
this.skipWaitIfReconnecting = false;
|
|
180
186
|
retriesLeft = retriesLeft - 1;
|
|
@@ -204,8 +210,7 @@ class MercurySocketIoClient {
|
|
|
204
210
|
await all;
|
|
205
211
|
}
|
|
206
212
|
mapSocketErrorToSpruceError(err) {
|
|
207
|
-
|
|
208
|
-
const originalError = new Error((_a = err.message) !== null && _a !== void 0 ? _a : err);
|
|
213
|
+
const originalError = new Error(err.message ?? err);
|
|
209
214
|
if (err.stack) {
|
|
210
215
|
originalError.stack = err.stack;
|
|
211
216
|
}
|
|
@@ -238,10 +243,10 @@ class MercurySocketIoClient {
|
|
|
238
243
|
if (isLocalEvent) {
|
|
239
244
|
const listeners = this.registeredListeners.filter((r) => r[0] === eventName);
|
|
240
245
|
for (const listener of listeners) {
|
|
241
|
-
const cb = listener
|
|
242
|
-
cb
|
|
246
|
+
const cb = listener?.[1];
|
|
247
|
+
cb?.({
|
|
243
248
|
//@ts-ignore
|
|
244
|
-
payload: targetAndPayload
|
|
249
|
+
payload: targetAndPayload?.payload,
|
|
245
250
|
});
|
|
246
251
|
}
|
|
247
252
|
return {
|
|
@@ -256,13 +261,12 @@ class MercurySocketIoClient {
|
|
|
256
261
|
async emitAndFlattenResponses(eventName, payload, cb) {
|
|
257
262
|
const results = await this.emit(eventName, payload, cb);
|
|
258
263
|
const { payloads, errors } = spruce_event_utils_1.eventResponseUtil.getAllResponsePayloadsAndErrors(results, SpruceError_1.default);
|
|
259
|
-
if (errors
|
|
264
|
+
if (errors?.[0]) {
|
|
260
265
|
throw errors[0];
|
|
261
266
|
}
|
|
262
267
|
return payloads;
|
|
263
268
|
}
|
|
264
269
|
async _emit(retriesRemaining, eventName, payload, cb) {
|
|
265
|
-
var _a;
|
|
266
270
|
if (!this.skipWaitIfReconnecting) {
|
|
267
271
|
await this.waitIfReconnecting();
|
|
268
272
|
}
|
|
@@ -299,12 +303,16 @@ class MercurySocketIoClient {
|
|
|
299
303
|
}
|
|
300
304
|
};
|
|
301
305
|
if (cb) {
|
|
302
|
-
|
|
306
|
+
this.socket?.on(responseEventName, singleResponseHandler);
|
|
303
307
|
}
|
|
304
308
|
const args = [];
|
|
305
309
|
if (payload || this.proxyToken) {
|
|
306
|
-
const p =
|
|
307
|
-
|
|
310
|
+
const p = {
|
|
311
|
+
...payload,
|
|
312
|
+
};
|
|
313
|
+
if (eventName !== exports.authenticateFqen &&
|
|
314
|
+
this.proxyToken &&
|
|
315
|
+
!p.source) {
|
|
308
316
|
p.source = {
|
|
309
317
|
proxyToken: this.proxyToken,
|
|
310
318
|
};
|
|
@@ -312,11 +320,9 @@ class MercurySocketIoClient {
|
|
|
312
320
|
args.push(p);
|
|
313
321
|
}
|
|
314
322
|
const results = await new Promise((resolve, reject) => {
|
|
315
|
-
var _a;
|
|
316
323
|
try {
|
|
317
324
|
const emitTimeout = setTimeout(async () => {
|
|
318
|
-
|
|
319
|
-
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.off(responseEventName, singleResponseHandler);
|
|
325
|
+
this.socket?.off(responseEventName, singleResponseHandler);
|
|
320
326
|
if (retriesRemaining == 0) {
|
|
321
327
|
const err = new SpruceError_1.default({
|
|
322
328
|
code: 'TIMEOUT',
|
|
@@ -330,7 +336,8 @@ class MercurySocketIoClient {
|
|
|
330
336
|
}
|
|
331
337
|
retriesRemaining--;
|
|
332
338
|
try {
|
|
333
|
-
if (eventName === exports.authenticateFqen &&
|
|
339
|
+
if (eventName === exports.authenticateFqen &&
|
|
340
|
+
this.authRawResults) {
|
|
334
341
|
resolve(this.authRawResults);
|
|
335
342
|
return;
|
|
336
343
|
}
|
|
@@ -345,14 +352,13 @@ class MercurySocketIoClient {
|
|
|
345
352
|
}
|
|
346
353
|
}, this.emitTimeoutMs);
|
|
347
354
|
args.push((results) => {
|
|
348
|
-
var _a;
|
|
349
355
|
clearTimeout(emitTimeout);
|
|
350
356
|
this.handleConfirmPinResponse(eventName, results);
|
|
351
|
-
|
|
357
|
+
this.socket?.off(responseEventName, singleResponseHandler);
|
|
352
358
|
resolve(results);
|
|
353
359
|
});
|
|
354
360
|
const ioName = socketIoEventUtil_utility_1.default.toSocketName(eventName);
|
|
355
|
-
|
|
361
|
+
this.socket?.emit(ioName, ...args);
|
|
356
362
|
}
|
|
357
363
|
catch (err) {
|
|
358
364
|
reject(err);
|
|
@@ -365,7 +371,7 @@ class MercurySocketIoClient {
|
|
|
365
371
|
const signature = this.getEventSignatureByName(eventName);
|
|
366
372
|
if (signature.emitPayloadSchema) {
|
|
367
373
|
try {
|
|
368
|
-
(0, schema_1.validateSchemaValues)(signature.emitPayloadSchema, payload
|
|
374
|
+
(0, schema_1.validateSchemaValues)(signature.emitPayloadSchema, payload ?? {});
|
|
369
375
|
}
|
|
370
376
|
catch (err) {
|
|
371
377
|
throw new SpruceError_1.default({
|
|
@@ -383,9 +389,8 @@ class MercurySocketIoClient {
|
|
|
383
389
|
}
|
|
384
390
|
}
|
|
385
391
|
handleConfirmPinResponse(eventName, results) {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
if (eventName.search('confirm-pin') === 0 && (payload === null || payload === void 0 ? void 0 : payload.person)) {
|
|
392
|
+
const payload = results?.responses?.[0]?.payload;
|
|
393
|
+
if (eventName.search('confirm-pin') === 0 && payload?.person) {
|
|
389
394
|
this.lastAuthOptions = { token: payload.token };
|
|
390
395
|
this.auth = {
|
|
391
396
|
person: payload.person,
|
|
@@ -402,7 +407,6 @@ class MercurySocketIoClient {
|
|
|
402
407
|
this.shouldAutoRegisterListeners = should;
|
|
403
408
|
}
|
|
404
409
|
async on(eventName, cb) {
|
|
405
|
-
var _a, _b, _c;
|
|
406
410
|
this.registeredListeners.push([eventName, cb]);
|
|
407
411
|
const isLocalEvent = this.isEventLocal(eventName);
|
|
408
412
|
if (isLocalEvent) {
|
|
@@ -414,11 +418,11 @@ class MercurySocketIoClient {
|
|
|
414
418
|
payload: { events: [{ eventName }] },
|
|
415
419
|
});
|
|
416
420
|
if (results.totalErrors > 0) {
|
|
417
|
-
const options =
|
|
421
|
+
const options = results.responses[0].errors?.[0] ?? 'UNKNOWN_ERROR';
|
|
418
422
|
throw error_1.default.parse(options, SpruceError_1.default);
|
|
419
423
|
}
|
|
420
424
|
}
|
|
421
|
-
|
|
425
|
+
this.socket?.on(eventName,
|
|
422
426
|
//@ts-ignore
|
|
423
427
|
async (targetAndPayload, ioCallback) => {
|
|
424
428
|
if (cb) {
|
|
@@ -451,12 +455,11 @@ class MercurySocketIoClient {
|
|
|
451
455
|
}
|
|
452
456
|
async off(eventName) {
|
|
453
457
|
return new Promise((resolve, reject) => {
|
|
454
|
-
var _a;
|
|
455
458
|
if (!this.socket || !this.auth || this.isEventLocal(eventName)) {
|
|
456
459
|
resolve(0);
|
|
457
460
|
return;
|
|
458
461
|
}
|
|
459
|
-
|
|
462
|
+
this.socket?.emit('unregister-listeners::v2020_12_25', {
|
|
460
463
|
payload: {
|
|
461
464
|
fullyQualifiedEventNames: [eventName],
|
|
462
465
|
},
|
|
@@ -475,30 +478,27 @@ class MercurySocketIoClient {
|
|
|
475
478
|
return this.id;
|
|
476
479
|
}
|
|
477
480
|
async disconnect() {
|
|
478
|
-
var _a;
|
|
479
481
|
this.isManuallyDisconnected = true;
|
|
480
482
|
if (this.isSocketConnected()) {
|
|
481
483
|
//@ts-ignore
|
|
482
|
-
|
|
484
|
+
this.socket?.removeAllListeners();
|
|
483
485
|
await new Promise((resolve) => {
|
|
484
|
-
|
|
485
|
-
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.once('disconnect', () => {
|
|
486
|
+
this.socket?.once('disconnect', () => {
|
|
486
487
|
this.socket = undefined;
|
|
487
488
|
resolve(undefined);
|
|
488
489
|
});
|
|
489
|
-
|
|
490
|
+
this.socket?.disconnect();
|
|
490
491
|
});
|
|
491
492
|
}
|
|
492
493
|
return;
|
|
493
494
|
}
|
|
494
495
|
async authenticate(options) {
|
|
495
|
-
var _a, _b;
|
|
496
496
|
const { skillId, apiKey, token } = options;
|
|
497
497
|
if (this.authPromise) {
|
|
498
498
|
await this.authPromise;
|
|
499
499
|
return {
|
|
500
|
-
skill:
|
|
501
|
-
person:
|
|
500
|
+
skill: this.auth?.skill,
|
|
501
|
+
person: this.auth?.person,
|
|
502
502
|
};
|
|
503
503
|
}
|
|
504
504
|
this.lastAuthOptions = options;
|
|
@@ -528,8 +528,7 @@ class MercurySocketIoClient {
|
|
|
528
528
|
return !this.isReAuthing && this.isSocketConnected();
|
|
529
529
|
}
|
|
530
530
|
isSocketConnected() {
|
|
531
|
-
|
|
532
|
-
return (_b = (_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected) !== null && _b !== void 0 ? _b : false;
|
|
531
|
+
return this.socket?.connected ?? false;
|
|
533
532
|
}
|
|
534
533
|
getProxyToken() {
|
|
535
534
|
return this.proxyToken;
|
|
@@ -549,6 +548,5 @@ class MercurySocketIoClient {
|
|
|
549
548
|
return false;
|
|
550
549
|
}
|
|
551
550
|
}
|
|
552
|
-
MercurySocketIoClient.io = socket_io_client_1.io;
|
|
553
551
|
exports.default = MercurySocketIoClient;
|
|
554
552
|
exports.authenticateFqen = 'authenticate::v2020_12_25';
|
|
@@ -8,6 +8,7 @@ declare class InternalEmitter<Contract extends EventContract> extends AbstractEv
|
|
|
8
8
|
mixinOnlyUniqueSignatures(contract: EventContract): void;
|
|
9
9
|
overrideSignatures(contract: EventContract): void;
|
|
10
10
|
getContract(): SpruceSchemas.Mercury.v2020_12_25.EventContract;
|
|
11
|
+
setContract(contract: Contract): void;
|
|
11
12
|
}
|
|
12
13
|
export default class MercuryTestClient<
|
|
13
14
|
/** @ts-ignore */
|
|
@@ -21,7 +22,6 @@ Contract extends EventContract = SkillEventContract> extends MutableContractClie
|
|
|
21
22
|
private static namespacesThatHaveToBeHandledLocally;
|
|
22
23
|
private shouldWaitForDelayedConnectIfAuthing;
|
|
23
24
|
private static shouldRequireLocalListeners;
|
|
24
|
-
/** @ts-ignore */
|
|
25
25
|
protected get eventContract(): Contract;
|
|
26
26
|
protected set eventContract(contract: Contract);
|
|
27
27
|
static setShouldCheckPermissionsOnLocalEvents(should: boolean): void;
|
|
@@ -16,12 +16,12 @@ class InternalEmitter extends mercury_event_emitter_1.AbstractEventEmitter {
|
|
|
16
16
|
spruce_event_utils_1.eventContractUtil.getSignatureByName(this.eventContract, eventName);
|
|
17
17
|
return true;
|
|
18
18
|
}
|
|
19
|
-
catch
|
|
19
|
+
catch {
|
|
20
20
|
return false;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
validateEmitPayload(schema, actualPayload, eventName) {
|
|
24
|
-
const payload =
|
|
24
|
+
const payload = { ...actualPayload };
|
|
25
25
|
delete payload.source;
|
|
26
26
|
return super.validateEmitPayload(schema, payload, eventName);
|
|
27
27
|
}
|
|
@@ -37,21 +37,31 @@ class InternalEmitter extends mercury_event_emitter_1.AbstractEventEmitter {
|
|
|
37
37
|
overrideSignatures(contract) {
|
|
38
38
|
const fqens = Object.keys(contract.eventSignatures);
|
|
39
39
|
for (const fqen of fqens) {
|
|
40
|
-
this.eventContract.eventSignatures[fqen] =
|
|
40
|
+
this.eventContract.eventSignatures[fqen] =
|
|
41
|
+
contract.eventSignatures[fqen];
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
getContract() {
|
|
44
45
|
return this.eventContract;
|
|
45
46
|
}
|
|
47
|
+
setContract(contract) {
|
|
48
|
+
this.eventContract = contract;
|
|
49
|
+
}
|
|
46
50
|
}
|
|
47
51
|
class MercuryTestClient extends MutableContractClient_1.default {
|
|
48
|
-
|
|
52
|
+
static emitter;
|
|
53
|
+
_isConnected = false;
|
|
54
|
+
isConnectedToApi = false;
|
|
55
|
+
connectPromise;
|
|
56
|
+
static shouldCheckPermissionsOnLocalEvents = false;
|
|
57
|
+
shouldHandleAuthenticateLocallyIfListenerSet = true;
|
|
58
|
+
static namespacesThatHaveToBeHandledLocally = [];
|
|
59
|
+
shouldWaitForDelayedConnectIfAuthing = true;
|
|
60
|
+
static shouldRequireLocalListeners = true;
|
|
49
61
|
get eventContract() {
|
|
50
62
|
return MercuryTestClient.emitter.getContract();
|
|
51
63
|
}
|
|
52
|
-
set eventContract(contract) {
|
|
53
|
-
MercuryTestClient.getInternalEmitter().overrideSignatures(contract);
|
|
54
|
-
}
|
|
64
|
+
set eventContract(contract) { }
|
|
55
65
|
static setShouldCheckPermissionsOnLocalEvents(should) {
|
|
56
66
|
this.shouldCheckPermissionsOnLocalEvents = should;
|
|
57
67
|
}
|
|
@@ -63,27 +73,29 @@ class MercuryTestClient extends MutableContractClient_1.default {
|
|
|
63
73
|
}
|
|
64
74
|
constructor(options) {
|
|
65
75
|
const contract = options.eventContract;
|
|
66
|
-
super(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
76
|
+
super({ ...options, eventContract: contract });
|
|
77
|
+
if (!MercuryTestClient.emitter) {
|
|
78
|
+
MercuryTestClient.getInternalEmitter(contract);
|
|
79
|
+
}
|
|
80
|
+
else if (contract) {
|
|
81
|
+
MercuryTestClient.emitter.overrideSignatures(contract);
|
|
82
|
+
}
|
|
72
83
|
}
|
|
73
84
|
/** @ts-ignore */
|
|
74
85
|
static getInternalEmitter(contract) {
|
|
75
|
-
const mixed = mixinConnectionEvents(contract);
|
|
76
86
|
if (!MercuryTestClient.emitter) {
|
|
77
|
-
MercuryTestClient.emitter = new InternalEmitter({
|
|
87
|
+
MercuryTestClient.emitter = new InternalEmitter({
|
|
88
|
+
eventSignatures: {},
|
|
89
|
+
});
|
|
78
90
|
}
|
|
91
|
+
const mixed = mixinConnectionEvents(contract);
|
|
79
92
|
MercuryTestClient.emitter.mixinOnlyUniqueSignatures(mixed);
|
|
80
93
|
/** @ts-ignore */
|
|
81
94
|
return MercuryTestClient.emitter;
|
|
82
95
|
}
|
|
83
96
|
async off(eventName, cb) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (((_b = MercuryTestClient.emitter) === null || _b === void 0 ? void 0 : _b.listenCount(eventName)) === 0) {
|
|
97
|
+
await MercuryTestClient.emitter?.off(eventName, cb);
|
|
98
|
+
if (MercuryTestClient.emitter?.listenCount(eventName) === 0) {
|
|
87
99
|
return super.off(eventName);
|
|
88
100
|
}
|
|
89
101
|
else {
|
|
@@ -99,16 +111,14 @@ class MercuryTestClient extends MutableContractClient_1.default {
|
|
|
99
111
|
MercuryTestClient.emitter.mixinContract(contract);
|
|
100
112
|
}
|
|
101
113
|
doesHandleEvent(eventName) {
|
|
102
|
-
var _a;
|
|
103
114
|
return (super.doesHandleEvent(eventName) ||
|
|
104
|
-
|
|
115
|
+
MercuryTestClient.emitter?.doesHandleEvent(eventName));
|
|
105
116
|
}
|
|
106
117
|
async on(...args) {
|
|
107
118
|
//@ts-ignore
|
|
108
119
|
return MercuryTestClient.emitter.on(...args);
|
|
109
120
|
}
|
|
110
121
|
async emit(...args) {
|
|
111
|
-
var _a, _b, _c, _d, _e;
|
|
112
122
|
const fqen = args[0];
|
|
113
123
|
try {
|
|
114
124
|
if (this.shouldHandleEventLocally(fqen)) {
|
|
@@ -126,15 +136,16 @@ class MercuryTestClient extends MutableContractClient_1.default {
|
|
|
126
136
|
await this.connectIfNotConnected(fqen);
|
|
127
137
|
//@ts-ignore
|
|
128
138
|
const results = await super.emit(...args);
|
|
129
|
-
const firstError =
|
|
130
|
-
if (firstError &&
|
|
139
|
+
const firstError = results.responses?.[0]?.errors?.[0];
|
|
140
|
+
if (firstError &&
|
|
141
|
+
firstError.options?.code === 'INVALID_EVENT_NAME') {
|
|
131
142
|
firstError.message = `Event not found! Make sure you are booting your skill in your test with \`await this.bootSkill()\`. If you haven't, you'll need to create a listener with \`spruce create.listener\`.\n\nOriginal Error:\n\n${firstError.options.friendlyMessage}`;
|
|
132
143
|
}
|
|
133
144
|
return results;
|
|
134
145
|
}
|
|
135
146
|
}
|
|
136
147
|
catch (err) {
|
|
137
|
-
if (
|
|
148
|
+
if (err.options?.code === 'INVALID_EVENT_NAME') {
|
|
138
149
|
err.message = `${err.message} Double check it's spelled correctly (types are passing) and that you've run \`spruce create.event\` to create the event.`;
|
|
139
150
|
}
|
|
140
151
|
throw err;
|
|
@@ -157,7 +168,6 @@ class MercuryTestClient extends MutableContractClient_1.default {
|
|
|
157
168
|
return emitter.listenCount(fqen) > 0;
|
|
158
169
|
}
|
|
159
170
|
async handleEventLocally(args) {
|
|
160
|
-
var _a;
|
|
161
171
|
const emitter = MercuryTestClient.emitter;
|
|
162
172
|
const fqen = args[0];
|
|
163
173
|
const payload = args[1];
|
|
@@ -207,7 +217,7 @@ class MercuryTestClient extends MutableContractClient_1.default {
|
|
|
207
217
|
code: 'UNAUTHORIZED_ACCESS',
|
|
208
218
|
fqen,
|
|
209
219
|
action: 'emit',
|
|
210
|
-
target:
|
|
220
|
+
target: args[1] ?? {},
|
|
211
221
|
permissionContractId: sig.emitPermissionContract.id,
|
|
212
222
|
}),
|
|
213
223
|
],
|
|
@@ -221,8 +231,7 @@ class MercuryTestClient extends MutableContractClient_1.default {
|
|
|
221
231
|
return (0, just_clone_1.default)(results);
|
|
222
232
|
}
|
|
223
233
|
assertValidEventSignature(sig, fqen) {
|
|
224
|
-
|
|
225
|
-
if (!sig.isGlobal && !((_b = (_a = sig.emitPayloadSchema) === null || _a === void 0 ? void 0 : _a.fields) === null || _b === void 0 ? void 0 : _b.target)) {
|
|
234
|
+
if (!sig.isGlobal && !sig.emitPayloadSchema?.fields?.target) {
|
|
226
235
|
throw new SpruceError_1.default({
|
|
227
236
|
code: 'INVALID_EVENT_SIGNATURE',
|
|
228
237
|
fqen,
|
|
@@ -231,16 +240,15 @@ class MercuryTestClient extends MutableContractClient_1.default {
|
|
|
231
240
|
}
|
|
232
241
|
}
|
|
233
242
|
async optionallyCheckPermissions(args, permissionContractId, fqen) {
|
|
234
|
-
var _a;
|
|
235
243
|
if (!MercuryTestClient.shouldCheckPermissionsOnLocalEvents) {
|
|
236
244
|
return true;
|
|
237
245
|
}
|
|
238
|
-
let { target } =
|
|
246
|
+
let { target } = args[1] ?? {};
|
|
239
247
|
const permTarget = {};
|
|
240
|
-
if (target
|
|
248
|
+
if (target?.organizationId) {
|
|
241
249
|
permTarget.organizationId = target.organizationId;
|
|
242
250
|
}
|
|
243
|
-
if (target
|
|
251
|
+
if (target?.locationId) {
|
|
244
252
|
throw new Error('checking permissions against a location is not supported. Add to mercury-workspace -> mercury-client');
|
|
245
253
|
}
|
|
246
254
|
const results = await this.emit('does-honor-permission-contract::v2020_12_25', {
|
|
@@ -257,12 +265,13 @@ class MercuryTestClient extends MutableContractClient_1.default {
|
|
|
257
265
|
return doesHonor;
|
|
258
266
|
}
|
|
259
267
|
buildSource(args) {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
268
|
+
let source = {
|
|
269
|
+
...args[1]?.source,
|
|
270
|
+
};
|
|
271
|
+
if (this.auth?.person) {
|
|
263
272
|
source.personId = this.auth.person.id;
|
|
264
273
|
}
|
|
265
|
-
if (
|
|
274
|
+
if (this.auth?.skill) {
|
|
266
275
|
source.skillId = this.auth.skill.id;
|
|
267
276
|
}
|
|
268
277
|
if (args[0] !== 'authenticate::v2020_12_25' &&
|
|
@@ -273,7 +282,10 @@ class MercuryTestClient extends MutableContractClient_1.default {
|
|
|
273
282
|
const argsWithSource = [...args];
|
|
274
283
|
if (typeof argsWithSource[1] !== 'function' &&
|
|
275
284
|
Object.keys(source).length > 0) {
|
|
276
|
-
argsWithSource[1] =
|
|
285
|
+
argsWithSource[1] = {
|
|
286
|
+
...argsWithSource[1],
|
|
287
|
+
source,
|
|
288
|
+
};
|
|
277
289
|
}
|
|
278
290
|
return { source, argsWithSource: (0, just_clone_1.default)(argsWithSource) };
|
|
279
291
|
}
|
|
@@ -331,13 +343,10 @@ class MercuryTestClient extends MutableContractClient_1.default {
|
|
|
331
343
|
return this.shouldRequireLocalListeners;
|
|
332
344
|
}
|
|
333
345
|
}
|
|
334
|
-
MercuryTestClient.shouldCheckPermissionsOnLocalEvents = false;
|
|
335
|
-
MercuryTestClient.namespacesThatHaveToBeHandledLocally = [];
|
|
336
|
-
MercuryTestClient.shouldRequireLocalListeners = true;
|
|
337
346
|
exports.default = MercuryTestClient;
|
|
338
347
|
function mixinConnectionEvents(contract) {
|
|
339
348
|
return spruce_event_utils_1.eventContractUtil.unifyContracts([
|
|
340
|
-
contract
|
|
349
|
+
contract ?? { eventSignatures: {} },
|
|
341
350
|
statusChangePayloadSchema_1.connectionStatusContract,
|
|
342
351
|
]);
|
|
343
352
|
}
|