@factset/frontgate-js-sdk 7.0.10 → 7.1.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 +24 -240
- package/dist/lib/esnext/mixins/MessageCompressorMixin.js +1 -1
- package/dist/lib/esnext/mixins/auth/FetchAuthenticationWithOptionalCompressionMixin.js +165 -0
- package/dist/lib/esnext/mixins/auth/index.js +1 -0
- package/dist/lib/esnext/mixins/subscription/EndpointSubscriptionMixin.js +9 -0
- package/dist/lib/esnext/version.js +1 -1
- package/dist/lib/node/mixins/MessageCompressorMixin.js +1 -1
- package/dist/lib/node/mixins/auth/FetchAuthenticationWithOptionalCompressionMixin.js +169 -0
- package/dist/lib/node/mixins/auth/index.js +1 -0
- package/dist/lib/node/mixins/subscription/EndpointSubscriptionMixin.js +9 -0
- package/dist/lib/node/version.js +1 -1
- package/dist/lib/types/mixins/auth/FetchAuthenticationWithOptionalCompressionMixin.d.ts +54 -0
- package/dist/lib/types/mixins/auth/index.d.ts +1 -0
- package/dist/lib/types/mixins/index.d.ts +2 -2
- package/dist/lib/umd/mdg2.client.min.umd.js +1 -1
- package/dist/lib/umd/mdg2.client.umd.js +158 -2
- package/package.json +1 -1
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
import { ID_APP_AUTHENTICATED, ID_USER_AUTHENTICATED } from '../../authentication';
|
|
13
|
+
import { Compressor } from '../../connection/util/Compressor';
|
|
14
|
+
import { LogLevel } from '../../logger';
|
|
15
|
+
import { AuthenticationByTokenRequest } from '../../message/request/AuthenticationByTokenRequest';
|
|
16
|
+
import { createExtendedMixinFactory, wsConnection } from '../.';
|
|
17
|
+
var FetchConnectionConfigurationResponseHeaders;
|
|
18
|
+
(function (FetchConnectionConfigurationResponseHeaders) {
|
|
19
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_HOST"] = "frontgate-host";
|
|
20
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_PATH_PREFIX"] = "frontgate-path-prefix";
|
|
21
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_SPLIT_AUTHENTICATION_TOKEN_SECOND_FACTOR"] = "frontgate-split-authentication-token-second-factor";
|
|
22
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_AUTHENTICATION_TYPE"] = "frontgate-authentication-type";
|
|
23
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_AUTHENTICATION_TOKEN"] = "frontgate-authentication-token";
|
|
24
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_WEBSOCKET_PORT"] = "frontgate-websocket-port";
|
|
25
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_WEBSOCKET_PROTOCOL"] = "frontgate-websocket-protocol";
|
|
26
|
+
})(FetchConnectionConfigurationResponseHeaders || (FetchConnectionConfigurationResponseHeaders = {}));
|
|
27
|
+
export const fetchAuthWithOptionalCompressor = (config, input, init) => {
|
|
28
|
+
const mixinFetchAuth = (Base) => {
|
|
29
|
+
var _instances, _token, _secondFactor, _shouldCompress, _compressor, _requestInfo, _requestInit, _fetchConnectionConfiguration, _a;
|
|
30
|
+
return _a = class extends wsConnection({
|
|
31
|
+
host: '',
|
|
32
|
+
pathPrefix: '',
|
|
33
|
+
port: 0,
|
|
34
|
+
tls: true,
|
|
35
|
+
maximumIdleIntervalInS: config.maximumIdleIntervalInS,
|
|
36
|
+
})(Base) {
|
|
37
|
+
constructor(...args) {
|
|
38
|
+
super(...args);
|
|
39
|
+
_instances.add(this);
|
|
40
|
+
_token.set(this, '');
|
|
41
|
+
_secondFactor.set(this, '');
|
|
42
|
+
_shouldCompress.set(this, false);
|
|
43
|
+
_compressor.set(this, void 0);
|
|
44
|
+
_requestInfo.set(this, void 0);
|
|
45
|
+
_requestInit.set(this, void 0);
|
|
46
|
+
__classPrivateFieldSet(this, _requestInfo, input, "f");
|
|
47
|
+
__classPrivateFieldSet(this, _requestInit, init, "f");
|
|
48
|
+
__classPrivateFieldSet(this, _compressor, new Compressor(), "f");
|
|
49
|
+
this.hooks.hook('frontgateConnection:reset', () => {
|
|
50
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
51
|
+
__classPrivateFieldGet(this, _compressor, "f").reset();
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
this.hooks.hook('frontgateConnection:beforeSendMessage', (data) => {
|
|
55
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
56
|
+
const compressed = __classPrivateFieldGet(this, _compressor, "f").compress(data.msg);
|
|
57
|
+
data.msg = compressed;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
this.hooks.hook('frontgateConnection:afterReceiveMessage', (data) => {
|
|
61
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
62
|
+
const decompressed = __classPrivateFieldGet(this, _compressor, "f").decompress(new Uint8Array(data.msg));
|
|
63
|
+
data.msg = decompressed;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
this.hooks.hook('frontgateConnection:beforeConnect', async (settings) => {
|
|
67
|
+
void this.hooks.callHook('frontgateConnection:setIdApp', ID_APP_AUTHENTICATED);
|
|
68
|
+
void this.hooks.callHook('frontgateConnection:setIdUser', ID_USER_AUTHENTICATED);
|
|
69
|
+
this.log(LogLevel.DEBUG, 'Fetching connection configuration');
|
|
70
|
+
const fetchConfig = await __classPrivateFieldGet(this, _instances, "m", _fetchConnectionConfiguration).call(this);
|
|
71
|
+
this.log(LogLevel.DEBUG, 'Connection configuration received', fetchConfig);
|
|
72
|
+
settings.url = fetchConfig.url;
|
|
73
|
+
if (fetchConfig.authtenticationType === 'token' && fetchConfig.authenticationToken) {
|
|
74
|
+
__classPrivateFieldSet(this, _token, fetchConfig.authenticationToken, "f");
|
|
75
|
+
}
|
|
76
|
+
else if (fetchConfig.splitAuthenticationTokenSecondFactor) {
|
|
77
|
+
__classPrivateFieldSet(this, _secondFactor, fetchConfig.splitAuthenticationTokenSecondFactor, "f");
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
throw new Error('Invalid authentication configuration');
|
|
81
|
+
}
|
|
82
|
+
this.log(LogLevel.DEBUG, 'Adding mdg2auth subprotocol');
|
|
83
|
+
if (__classPrivateFieldGet(this, _secondFactor, "f") !== '') {
|
|
84
|
+
settings.subProtocols.push(`mdg2auth-${__classPrivateFieldGet(this, _secondFactor, "f")}`);
|
|
85
|
+
}
|
|
86
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
87
|
+
settings.subProtocols.forEach((protocol, index) => {
|
|
88
|
+
if (protocol.includes('jsjson') && !protocol.includes('jsjsonc')) {
|
|
89
|
+
settings.subProtocols[index] = protocol.replace('jsjson', 'jsjsonc');
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
const authFn = async (conf) => {
|
|
95
|
+
void this.hooks.callHook('frontgateConnection:setIdApp', ID_APP_AUTHENTICATED);
|
|
96
|
+
void this.hooks.callHook('frontgateConnection:setIdUser', ID_USER_AUTHENTICATED);
|
|
97
|
+
const options = {
|
|
98
|
+
maximum_idle_interval: conf.maximumIdleInterval,
|
|
99
|
+
};
|
|
100
|
+
const tokenData = { b64: __classPrivateFieldGet(this, _token, "f") };
|
|
101
|
+
const request = new AuthenticationByTokenRequest(tokenData, options.maximum_idle_interval);
|
|
102
|
+
const message = request.toJson();
|
|
103
|
+
this.log(LogLevel.INFO, 'Sending message', message);
|
|
104
|
+
const msg = {
|
|
105
|
+
message,
|
|
106
|
+
callbackType: 'response',
|
|
107
|
+
callbackId: message.Message.replace('Request', 'Response'),
|
|
108
|
+
};
|
|
109
|
+
await this.hooks.callHook('frontgateConnection:sendMessage', msg);
|
|
110
|
+
this.hooks.hookOnce(`frontgateConnection:response:${msg.callbackId}`, (response) => {
|
|
111
|
+
this.log(LogLevel.INFO, 'Received response', response);
|
|
112
|
+
void this.hooks.callHook('frontgateConnection:authenticated');
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
this.hooks.hook('frontgateConnection:connected', authFn);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
_token = new WeakMap(),
|
|
119
|
+
_secondFactor = new WeakMap(),
|
|
120
|
+
_shouldCompress = new WeakMap(),
|
|
121
|
+
_compressor = new WeakMap(),
|
|
122
|
+
_requestInfo = new WeakMap(),
|
|
123
|
+
_requestInit = new WeakMap(),
|
|
124
|
+
_instances = new WeakSet(),
|
|
125
|
+
_fetchConnectionConfiguration = async function _fetchConnectionConfiguration() {
|
|
126
|
+
const response = await fetch(__classPrivateFieldGet(this, _requestInfo, "f"), __classPrivateFieldGet(this, _requestInit, "f"));
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
throw new Error(`Failed to fetch connection configuration: ${response.status} ${response.statusText}`);
|
|
129
|
+
}
|
|
130
|
+
const { headers } = response;
|
|
131
|
+
const host = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_HOST);
|
|
132
|
+
const pathPrefix = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_PATH_PREFIX);
|
|
133
|
+
const splitAuthenticationTokenSecondFactor = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_SPLIT_AUTHENTICATION_TOKEN_SECOND_FACTOR);
|
|
134
|
+
const authenticationType = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_AUTHENTICATION_TYPE);
|
|
135
|
+
const authenticationToken = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_AUTHENTICATION_TOKEN);
|
|
136
|
+
const port = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_WEBSOCKET_PORT) ?? '443';
|
|
137
|
+
const url = `wss://${host}:${port}${pathPrefix ?? ''}/ws`;
|
|
138
|
+
if (authenticationType === 'token' && !authenticationToken) {
|
|
139
|
+
throw new Error('Authentication token is required for token authentication');
|
|
140
|
+
}
|
|
141
|
+
if (authenticationType !== 'token' && !splitAuthenticationTokenSecondFactor) {
|
|
142
|
+
throw new Error('Split authentication token second factor is required');
|
|
143
|
+
}
|
|
144
|
+
const protocol = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_WEBSOCKET_PROTOCOL);
|
|
145
|
+
if (protocol === 'jsjsonc-v2') {
|
|
146
|
+
__classPrivateFieldSet(this, _shouldCompress, true, "f");
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
__classPrivateFieldSet(this, _shouldCompress, false, "f");
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
url,
|
|
153
|
+
authtenticationType: authenticationType,
|
|
154
|
+
authenticationToken,
|
|
155
|
+
splitAuthenticationTokenSecondFactor,
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
_a;
|
|
159
|
+
};
|
|
160
|
+
return createExtendedMixinFactory(mixinFetchAuth, {
|
|
161
|
+
featureName: 'FetchAuthWithOptionalCompressor',
|
|
162
|
+
featureGroups: ['Auth', 'Connection'],
|
|
163
|
+
disabledFeatureGroups: ['Auth', 'Connection', 'Compression'],
|
|
164
|
+
});
|
|
165
|
+
};
|
|
@@ -115,6 +115,15 @@ export const endpointSubscriptions = (originalConfig) => {
|
|
|
115
115
|
res();
|
|
116
116
|
return;
|
|
117
117
|
}
|
|
118
|
+
try {
|
|
119
|
+
observer.pushData(JSON.parse(resp.body.value));
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
this.log(LogLevel.ERROR, `Failed to parse response: ${resp.body.value}`);
|
|
123
|
+
this.log(LogLevel.ERROR, e);
|
|
124
|
+
rej(e);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
118
127
|
removeMessageUpdateHook = this.hooks.hook(`frontgateConnection:response:${resp.header.id_job}`, (update) => {
|
|
119
128
|
if (!update.Message.includes('HighLevelUpdate')) {
|
|
120
129
|
if (update.Message.includes('SubscriptionLoss')) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const PACKAGE_JSON = { version: '7.0
|
|
1
|
+
export const PACKAGE_JSON = { version: '7.1.0', package: '@factset/frontgate-js-sdk' };
|
|
@@ -43,7 +43,7 @@ const messageCompressor = () => {
|
|
|
43
43
|
};
|
|
44
44
|
return (0, _1.createExtendedMixinFactory)(mixinCompressor, {
|
|
45
45
|
featureName: 'MessageCompressor',
|
|
46
|
-
featureGroups: ['
|
|
46
|
+
featureGroups: ['Compression'],
|
|
47
47
|
});
|
|
48
48
|
};
|
|
49
49
|
exports.messageCompressor = messageCompressor;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.fetchAuthWithOptionalCompressor = void 0;
|
|
15
|
+
const authentication_1 = require("../../authentication");
|
|
16
|
+
const Compressor_1 = require("../../connection/util/Compressor");
|
|
17
|
+
const logger_1 = require("../../logger");
|
|
18
|
+
const AuthenticationByTokenRequest_1 = require("../../message/request/AuthenticationByTokenRequest");
|
|
19
|
+
const _1 = require("../.");
|
|
20
|
+
var FetchConnectionConfigurationResponseHeaders;
|
|
21
|
+
(function (FetchConnectionConfigurationResponseHeaders) {
|
|
22
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_HOST"] = "frontgate-host";
|
|
23
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_PATH_PREFIX"] = "frontgate-path-prefix";
|
|
24
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_SPLIT_AUTHENTICATION_TOKEN_SECOND_FACTOR"] = "frontgate-split-authentication-token-second-factor";
|
|
25
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_AUTHENTICATION_TYPE"] = "frontgate-authentication-type";
|
|
26
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_AUTHENTICATION_TOKEN"] = "frontgate-authentication-token";
|
|
27
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_WEBSOCKET_PORT"] = "frontgate-websocket-port";
|
|
28
|
+
FetchConnectionConfigurationResponseHeaders["FRONTGATE_WEBSOCKET_PROTOCOL"] = "frontgate-websocket-protocol";
|
|
29
|
+
})(FetchConnectionConfigurationResponseHeaders || (FetchConnectionConfigurationResponseHeaders = {}));
|
|
30
|
+
const fetchAuthWithOptionalCompressor = (config, input, init) => {
|
|
31
|
+
const mixinFetchAuth = (Base) => {
|
|
32
|
+
var _instances, _token, _secondFactor, _shouldCompress, _compressor, _requestInfo, _requestInit, _fetchConnectionConfiguration, _a;
|
|
33
|
+
return _a = class extends (0, _1.wsConnection)({
|
|
34
|
+
host: '',
|
|
35
|
+
pathPrefix: '',
|
|
36
|
+
port: 0,
|
|
37
|
+
tls: true,
|
|
38
|
+
maximumIdleIntervalInS: config.maximumIdleIntervalInS,
|
|
39
|
+
})(Base) {
|
|
40
|
+
constructor(...args) {
|
|
41
|
+
super(...args);
|
|
42
|
+
_instances.add(this);
|
|
43
|
+
_token.set(this, '');
|
|
44
|
+
_secondFactor.set(this, '');
|
|
45
|
+
_shouldCompress.set(this, false);
|
|
46
|
+
_compressor.set(this, void 0);
|
|
47
|
+
_requestInfo.set(this, void 0);
|
|
48
|
+
_requestInit.set(this, void 0);
|
|
49
|
+
__classPrivateFieldSet(this, _requestInfo, input, "f");
|
|
50
|
+
__classPrivateFieldSet(this, _requestInit, init, "f");
|
|
51
|
+
__classPrivateFieldSet(this, _compressor, new Compressor_1.Compressor(), "f");
|
|
52
|
+
this.hooks.hook('frontgateConnection:reset', () => {
|
|
53
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
54
|
+
__classPrivateFieldGet(this, _compressor, "f").reset();
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
this.hooks.hook('frontgateConnection:beforeSendMessage', (data) => {
|
|
58
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
59
|
+
const compressed = __classPrivateFieldGet(this, _compressor, "f").compress(data.msg);
|
|
60
|
+
data.msg = compressed;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
this.hooks.hook('frontgateConnection:afterReceiveMessage', (data) => {
|
|
64
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
65
|
+
const decompressed = __classPrivateFieldGet(this, _compressor, "f").decompress(new Uint8Array(data.msg));
|
|
66
|
+
data.msg = decompressed;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
this.hooks.hook('frontgateConnection:beforeConnect', async (settings) => {
|
|
70
|
+
void this.hooks.callHook('frontgateConnection:setIdApp', authentication_1.ID_APP_AUTHENTICATED);
|
|
71
|
+
void this.hooks.callHook('frontgateConnection:setIdUser', authentication_1.ID_USER_AUTHENTICATED);
|
|
72
|
+
this.log(logger_1.LogLevel.DEBUG, 'Fetching connection configuration');
|
|
73
|
+
const fetchConfig = await __classPrivateFieldGet(this, _instances, "m", _fetchConnectionConfiguration).call(this);
|
|
74
|
+
this.log(logger_1.LogLevel.DEBUG, 'Connection configuration received', fetchConfig);
|
|
75
|
+
settings.url = fetchConfig.url;
|
|
76
|
+
if (fetchConfig.authtenticationType === 'token' && fetchConfig.authenticationToken) {
|
|
77
|
+
__classPrivateFieldSet(this, _token, fetchConfig.authenticationToken, "f");
|
|
78
|
+
}
|
|
79
|
+
else if (fetchConfig.splitAuthenticationTokenSecondFactor) {
|
|
80
|
+
__classPrivateFieldSet(this, _secondFactor, fetchConfig.splitAuthenticationTokenSecondFactor, "f");
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
throw new Error('Invalid authentication configuration');
|
|
84
|
+
}
|
|
85
|
+
this.log(logger_1.LogLevel.DEBUG, 'Adding mdg2auth subprotocol');
|
|
86
|
+
if (__classPrivateFieldGet(this, _secondFactor, "f") !== '') {
|
|
87
|
+
settings.subProtocols.push(`mdg2auth-${__classPrivateFieldGet(this, _secondFactor, "f")}`);
|
|
88
|
+
}
|
|
89
|
+
if (__classPrivateFieldGet(this, _shouldCompress, "f")) {
|
|
90
|
+
settings.subProtocols.forEach((protocol, index) => {
|
|
91
|
+
if (protocol.includes('jsjson') && !protocol.includes('jsjsonc')) {
|
|
92
|
+
settings.subProtocols[index] = protocol.replace('jsjson', 'jsjsonc');
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
const authFn = async (conf) => {
|
|
98
|
+
void this.hooks.callHook('frontgateConnection:setIdApp', authentication_1.ID_APP_AUTHENTICATED);
|
|
99
|
+
void this.hooks.callHook('frontgateConnection:setIdUser', authentication_1.ID_USER_AUTHENTICATED);
|
|
100
|
+
const options = {
|
|
101
|
+
maximum_idle_interval: conf.maximumIdleInterval,
|
|
102
|
+
};
|
|
103
|
+
const tokenData = { b64: __classPrivateFieldGet(this, _token, "f") };
|
|
104
|
+
const request = new AuthenticationByTokenRequest_1.AuthenticationByTokenRequest(tokenData, options.maximum_idle_interval);
|
|
105
|
+
const message = request.toJson();
|
|
106
|
+
this.log(logger_1.LogLevel.INFO, 'Sending message', message);
|
|
107
|
+
const msg = {
|
|
108
|
+
message,
|
|
109
|
+
callbackType: 'response',
|
|
110
|
+
callbackId: message.Message.replace('Request', 'Response'),
|
|
111
|
+
};
|
|
112
|
+
await this.hooks.callHook('frontgateConnection:sendMessage', msg);
|
|
113
|
+
this.hooks.hookOnce(`frontgateConnection:response:${msg.callbackId}`, (response) => {
|
|
114
|
+
this.log(logger_1.LogLevel.INFO, 'Received response', response);
|
|
115
|
+
void this.hooks.callHook('frontgateConnection:authenticated');
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
this.hooks.hook('frontgateConnection:connected', authFn);
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
_token = new WeakMap(),
|
|
122
|
+
_secondFactor = new WeakMap(),
|
|
123
|
+
_shouldCompress = new WeakMap(),
|
|
124
|
+
_compressor = new WeakMap(),
|
|
125
|
+
_requestInfo = new WeakMap(),
|
|
126
|
+
_requestInit = new WeakMap(),
|
|
127
|
+
_instances = new WeakSet(),
|
|
128
|
+
_fetchConnectionConfiguration = async function _fetchConnectionConfiguration() {
|
|
129
|
+
const response = await fetch(__classPrivateFieldGet(this, _requestInfo, "f"), __classPrivateFieldGet(this, _requestInit, "f"));
|
|
130
|
+
if (!response.ok) {
|
|
131
|
+
throw new Error(`Failed to fetch connection configuration: ${response.status} ${response.statusText}`);
|
|
132
|
+
}
|
|
133
|
+
const { headers } = response;
|
|
134
|
+
const host = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_HOST);
|
|
135
|
+
const pathPrefix = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_PATH_PREFIX);
|
|
136
|
+
const splitAuthenticationTokenSecondFactor = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_SPLIT_AUTHENTICATION_TOKEN_SECOND_FACTOR);
|
|
137
|
+
const authenticationType = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_AUTHENTICATION_TYPE);
|
|
138
|
+
const authenticationToken = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_AUTHENTICATION_TOKEN);
|
|
139
|
+
const port = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_WEBSOCKET_PORT) ?? '443';
|
|
140
|
+
const url = `wss://${host}:${port}${pathPrefix ?? ''}/ws`;
|
|
141
|
+
if (authenticationType === 'token' && !authenticationToken) {
|
|
142
|
+
throw new Error('Authentication token is required for token authentication');
|
|
143
|
+
}
|
|
144
|
+
if (authenticationType !== 'token' && !splitAuthenticationTokenSecondFactor) {
|
|
145
|
+
throw new Error('Split authentication token second factor is required');
|
|
146
|
+
}
|
|
147
|
+
const protocol = headers.get(FetchConnectionConfigurationResponseHeaders.FRONTGATE_WEBSOCKET_PROTOCOL);
|
|
148
|
+
if (protocol === 'jsjsonc-v2') {
|
|
149
|
+
__classPrivateFieldSet(this, _shouldCompress, true, "f");
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
__classPrivateFieldSet(this, _shouldCompress, false, "f");
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
url,
|
|
156
|
+
authtenticationType: authenticationType,
|
|
157
|
+
authenticationToken,
|
|
158
|
+
splitAuthenticationTokenSecondFactor,
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
_a;
|
|
162
|
+
};
|
|
163
|
+
return (0, _1.createExtendedMixinFactory)(mixinFetchAuth, {
|
|
164
|
+
featureName: 'FetchAuthWithOptionalCompressor',
|
|
165
|
+
featureGroups: ['Auth', 'Connection'],
|
|
166
|
+
disabledFeatureGroups: ['Auth', 'Connection', 'Compression'],
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
exports.fetchAuthWithOptionalCompressor = fetchAuthWithOptionalCompressor;
|
|
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./CookieTokenAuthMixin"), exports);
|
|
18
18
|
__exportStar(require("./TokenAuthMixin"), exports);
|
|
19
19
|
__exportStar(require("./FetchAuthenticationMixin"), exports);
|
|
20
|
+
__exportStar(require("./FetchAuthenticationWithOptionalCompressionMixin"), exports);
|
|
@@ -118,6 +118,15 @@ const endpointSubscriptions = (originalConfig) => {
|
|
|
118
118
|
res();
|
|
119
119
|
return;
|
|
120
120
|
}
|
|
121
|
+
try {
|
|
122
|
+
observer.pushData(JSON.parse(resp.body.value));
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
this.log(logger_1.LogLevel.ERROR, `Failed to parse response: ${resp.body.value}`);
|
|
126
|
+
this.log(logger_1.LogLevel.ERROR, e);
|
|
127
|
+
rej(e);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
121
130
|
removeMessageUpdateHook = this.hooks.hook(`frontgateConnection:response:${resp.header.id_job}`, (update) => {
|
|
122
131
|
if (!update.Message.includes('HighLevelUpdate')) {
|
|
123
132
|
if (update.Message.includes('SubscriptionLoss')) {
|
package/dist/lib/node/version.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PACKAGE_JSON = void 0;
|
|
4
|
-
exports.PACKAGE_JSON = { version: '7.0
|
|
4
|
+
exports.PACKAGE_JSON = { version: '7.1.0', package: '@factset/frontgate-js-sdk' };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { AConstructorTypeOf, FrontgateClientWSConnectionConfig, FrontgateMessage, CalledHooksByAuth, CalledHooksByConnection, FrontgateClientFetchWSConnectionConfig } from '../.';
|
|
2
|
+
import type { DefaultFrontgateClientHooks, FrontgateClient } from '../../FrontgateClient';
|
|
3
|
+
import type { PtlMessage } from '../../common/interfaces/PtlMessage';
|
|
4
|
+
import { Compressor } from '../../connection/util/Compressor';
|
|
5
|
+
import { LogLevel } from '../../logger';
|
|
6
|
+
export type usedHooksByFetchAuthWithOptionalCompressor = CalledHooksByConnection;
|
|
7
|
+
export declare const fetchAuthWithOptionalCompressor: (config: FrontgateClientFetchWSConnectionConfig, input: RequestInfo, init?: RequestInit) => (<T extends AConstructorTypeOf<FrontgateClient<usedHooksByFetchAuthWithOptionalCompressor & CalledHooksByAuth & DefaultFrontgateClientHooks>>>(Base: T) => {
|
|
8
|
+
new (...args: any[]): {
|
|
9
|
+
"__#private@#token": string;
|
|
10
|
+
"__#private@#secondFactor": string;
|
|
11
|
+
"__#private@#shouldCompress": boolean;
|
|
12
|
+
readonly "__#private@#compressor": Compressor;
|
|
13
|
+
readonly "__#private@#requestInfo": RequestInfo;
|
|
14
|
+
readonly "__#private@#requestInit": RequestInit | undefined;
|
|
15
|
+
"__#private@#fetchConnectionConfiguration"(): Promise<{
|
|
16
|
+
url: string;
|
|
17
|
+
authtenticationType: string | null;
|
|
18
|
+
authenticationToken: string | null;
|
|
19
|
+
splitAuthenticationTokenSecondFactor: string | null;
|
|
20
|
+
}>;
|
|
21
|
+
"__#private@#ws": import("ws") | undefined;
|
|
22
|
+
"__#private@#wsConf": import("../.").InternalFrontgateClientWSConnectionConfig | undefined;
|
|
23
|
+
"__#private@#wsStateInternal": "connecting" | "connected" | "authenticated" | "disconnected";
|
|
24
|
+
"__#private@#keepAliveTimer": NodeJS.Timeout | undefined;
|
|
25
|
+
"__#private@#jobId": number;
|
|
26
|
+
"__#private@#idApplication": number;
|
|
27
|
+
"__#private@#idUser": number;
|
|
28
|
+
get "__#private@#wsState"(): "connecting" | "connected" | "authenticated" | "disconnected";
|
|
29
|
+
"__#private@#message_buffer_size": number;
|
|
30
|
+
readonly "__#private@#msgBuffer": FrontgateMessage[];
|
|
31
|
+
set conf(newConf: FrontgateClientWSConnectionConfig);
|
|
32
|
+
connect(): Promise<void>;
|
|
33
|
+
disconnect(): Promise<void>;
|
|
34
|
+
"__#private@#getDisconnectMessage"(): import("../..").DisconnectionMessage;
|
|
35
|
+
"__#private@#getKeepAliveMessage"(): {
|
|
36
|
+
Message: string;
|
|
37
|
+
Version: number;
|
|
38
|
+
};
|
|
39
|
+
"__#private@#sendMessage"(msg: PtlMessage): Promise<void>;
|
|
40
|
+
"__#private@#respondToMessage"(msgObj: PtlMessage): void;
|
|
41
|
+
"__#private@#addJobIdToMessage"(msg: PtlMessage): number;
|
|
42
|
+
"__#private@#prepareMessage"(msg: PtlMessage): void;
|
|
43
|
+
"__#private@#createErrorMessage"(error: string, msg: PtlMessage): import("../..").ErrorResponse;
|
|
44
|
+
"__#private@#applyDefaultsToConfig"(oldConf: FrontgateClientWSConnectionConfig): import("../.").InternalFrontgateClientWSConnectionConfig;
|
|
45
|
+
isConnected(): boolean;
|
|
46
|
+
isDisconnected(): boolean;
|
|
47
|
+
isReadyToConnect(): boolean;
|
|
48
|
+
logger: import("../../logger").LoggerInterface | undefined;
|
|
49
|
+
hooks: import("hookable").Hookable<import("../ReconnectMixin").CalledHooksByReconnect & CalledHooksByAuth & CalledHooksByConnection & import("../../FrontgateClient").CalledHooksByBase, import("hookable").HookKeys<import("../ReconnectMixin").CalledHooksByReconnect & CalledHooksByAuth & CalledHooksByConnection & import("../../FrontgateClient").CalledHooksByBase>> & import("hookable").Hookable<CalledHooksByConnection & CalledHooksByAuth & import("../../FrontgateClient").CalledHooksByBase, import("hookable").HookKeys<CalledHooksByConnection & CalledHooksByAuth & import("../../FrontgateClient").CalledHooksByBase>>;
|
|
50
|
+
readonly "__#private@#defaultTimeoutInMs": number;
|
|
51
|
+
get defaultTimeoutInMs(): number;
|
|
52
|
+
log: ((level: LogLevel, ...args: unknown[]) => void) & ((level: LogLevel, ...args: unknown[]) => void);
|
|
53
|
+
};
|
|
54
|
+
} & T) & import("../.").ExtendendMixinFactoryOptions;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './CookieTokenAuthMixin';
|
|
2
2
|
export * from './TokenAuthMixin';
|
|
3
3
|
export * from './FetchAuthenticationMixin';
|
|
4
|
+
export * from './FetchAuthenticationWithOptionalCompressionMixin';
|
|
4
5
|
export interface CalledHooksByAuth {
|
|
5
6
|
'frontgateConnection:setIdApp': (idApp: number) => void;
|
|
6
7
|
'frontgateConnection:setIdUser': (idUser: number) => void;
|
|
@@ -11,8 +11,8 @@ export * from './OpenTelemetryMixin';
|
|
|
11
11
|
export * from './HTTPProxyRequestMixin';
|
|
12
12
|
export * from './PingMixin';
|
|
13
13
|
export * from './RemoteLoggerMixin';
|
|
14
|
-
export type FeatureName = 'AppAuth' | 'CookieTokenAuth' | 'FetchAuth' | 'SessionAuth' | 'TokenAuth' | 'UserCredentialAuth' | 'UserPasswordAuth' | 'WSConnection' | 'TCPConnection' | 'AuthTokenRequest' | 'EndpointRequest' | 'HTTPProxyRequest' | 'Logger' | 'MessageCompressor' | 'OpenTelemetry' | 'Reconnect' | 'Request' | 'EndpointSubscriptions' | 'Pingable' | 'RawSubscriptions' | 'RemoteLogger' | 'Custom';
|
|
15
|
-
export type FeatureGroup = 'Auth' | 'Connection' | 'Misc';
|
|
14
|
+
export type FeatureName = 'AppAuth' | 'CookieTokenAuth' | 'FetchAuth' | 'SessionAuth' | 'TokenAuth' | 'UserCredentialAuth' | 'UserPasswordAuth' | 'WSConnection' | 'TCPConnection' | 'AuthTokenRequest' | 'EndpointRequest' | 'HTTPProxyRequest' | 'Logger' | 'MessageCompressor' | 'OpenTelemetry' | 'Reconnect' | 'Request' | 'EndpointSubscriptions' | 'Pingable' | 'RawSubscriptions' | 'RemoteLogger' | 'FetchAuthWithOptionalCompressor' | 'Custom';
|
|
15
|
+
export type FeatureGroup = 'Auth' | 'Connection' | 'Compression' | 'Misc';
|
|
16
16
|
export type AConstructorTypeOf<T> = new (...args: any[]) => T;
|
|
17
17
|
export type MixinFactory<TBase, TMixin> = (Base: AConstructorTypeOf<TBase>) => AConstructorTypeOf<TBase & TMixin>;
|
|
18
18
|
export type ExtendedMixinFactory<TBase, TMixin> = ((Base: AConstructorTypeOf<TBase>) => AConstructorTypeOf<TBase & TMixin>) & {
|