@factset/frontgate-js-sdk 7.1.0 → 7.1.2

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 (44) hide show
  1. package/CHANGELOG.md +65 -1
  2. package/dist/lib/esnext/connection/util/Compressor.js +2 -0
  3. package/dist/lib/esnext/logger/AbstractLogger.js +1 -0
  4. package/dist/lib/esnext/logger/WinstonLogger.js +3 -1
  5. package/dist/lib/esnext/mixins/auth/SessionAuthMixin.js +19 -21
  6. package/dist/lib/esnext/mixins/auth/UserPasswordAuthMixin.js +2 -4
  7. package/dist/lib/esnext/mixins/connection/FrontgateWSMixin.js +1 -1
  8. package/dist/lib/esnext/mixins/subscription/EndpointSubscriptionMixin.js +14 -7
  9. package/dist/lib/esnext/version.js +1 -1
  10. package/dist/lib/node/connection/util/Compressor.js +2 -0
  11. package/dist/lib/node/logger/AbstractLogger.js +1 -0
  12. package/dist/lib/node/logger/WinstonLogger.js +3 -1
  13. package/dist/lib/node/mixins/auth/SessionAuthMixin.js +19 -21
  14. package/dist/lib/node/mixins/auth/UserPasswordAuthMixin.js +2 -4
  15. package/dist/lib/node/mixins/connection/FrontgateWSMixin.js +1 -1
  16. package/dist/lib/node/mixins/subscription/EndpointSubscriptionMixin.js +14 -7
  17. package/dist/lib/node/version.js +1 -1
  18. package/dist/lib/types/authentication/util/SecretGenerator.d.ts +4 -2
  19. package/dist/lib/types/mixins/AuthTokenRequestMixin.d.ts +1 -14
  20. package/dist/lib/types/mixins/EndpointRequestMixin.d.ts +2 -12
  21. package/dist/lib/types/mixins/HTTPProxyRequestMixin.d.ts +2 -11
  22. package/dist/lib/types/mixins/LoggerMixin.d.ts +1 -9
  23. package/dist/lib/types/mixins/MessageCompressorMixin.d.ts +1 -11
  24. package/dist/lib/types/mixins/OpenTelemetryMixin.d.ts +1 -16
  25. package/dist/lib/types/mixins/PingMixin.d.ts +1 -10
  26. package/dist/lib/types/mixins/ReconnectMixin.d.ts +1 -13
  27. package/dist/lib/types/mixins/RemoteLoggerMixin.d.ts +1 -10
  28. package/dist/lib/types/mixins/RequestMixin.d.ts +1 -10
  29. package/dist/lib/types/mixins/auth/AppAuthMixin.d.ts +2 -20
  30. package/dist/lib/types/mixins/auth/CookieTokenAuthMixin.d.ts +1 -10
  31. package/dist/lib/types/mixins/auth/FetchAuthenticationMixin.d.ts +2 -49
  32. package/dist/lib/types/mixins/auth/FetchAuthenticationWithOptionalCompressionMixin.d.ts +2 -52
  33. package/dist/lib/types/mixins/auth/SessionAuthMixin.d.ts +2 -57
  34. package/dist/lib/types/mixins/auth/TokenAuthMixin.d.ts +1 -12
  35. package/dist/lib/types/mixins/auth/UserCredentialAuthMixin.d.ts +2 -20
  36. package/dist/lib/types/mixins/auth/UserPasswordAuthMixin.d.ts +2 -20
  37. package/dist/lib/types/mixins/connection/FrontgateWSMixin.d.ts +2 -42
  38. package/dist/lib/types/mixins/connection/index.d.ts +1 -1
  39. package/dist/lib/types/mixins/subscription/DataObserver.d.ts +1 -1
  40. package/dist/lib/types/mixins/subscription/EndpointSubscriptionMixin.d.ts +2 -15
  41. package/dist/lib/types/mixins/subscription/RawSubscriptionMixin.d.ts +1 -18
  42. package/dist/lib/umd/mdg2.client.min.umd.js +1 -1
  43. package/dist/lib/umd/mdg2.client.umd.js +4524 -4987
  44. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -1,6 +1,68 @@
1
+ ## <small>7.1.2 (2026-05-26)</small>
2
+
3
+ * fix(endpoint-subscription): prevent late response from clobbering active subscription [75b39a8]
4
+ * chore(deps): lock file maintenance [862e3b9]
5
+ * chore(deps): update yarn to v4.15.0 [e0356c8]
6
+ * docs(client-usage): fix usage instructions [7f70434]
7
+
8
+ ## <small>7.1.1 (2026-05-22)</small>
9
+
10
+ * chore(deps): lock file maintenance [3df42bb]
11
+ * chore(deps): lock file maintenance [3719301]
12
+ * chore(deps): lock file maintenance [fbc6d86]
13
+ * chore(deps): lock file maintenance [17f1a93]
14
+ * chore(deps): update actions/deploy-pages action to v5 [f721a0b]
15
+ * chore(deps): update actions/setup-node action to v6.4.0 [f772230]
16
+ * chore(deps): update actions/upload-pages-artifact action to v5 [3df9da3]
17
+ * chore(deps): update dependency axios to ^1.15.2 [security] [5838528]
18
+ * chore(deps): update dependency happy-dom to ^20.8.8 [security] [9995d98]
19
+ * chore(deps): update dependency happy-dom to ^20.8.9 [security] [261bacc]
20
+ * chore(deps): update dependency typescript to v6 [287cb5f]
21
+ * chore(deps): update dependency vite to v8 [62e69e7]
22
+ * chore(deps): update dependency vite-plugin-node-polyfills to ^0.26.0 [869bd24]
23
+ * chore(deps): update dependency vite-plugin-node-polyfills to ^0.27.0 [656c8ac]
24
+ * chore(deps): update dependency vite-plugin-node-polyfills to ^0.28.0 [24884b1]
25
+ * chore(deps): update factset/backstage-entity-validator action to v0.6.0 [2c8fd5e]
26
+ * chore(deps): update factset/waffle-actions action to v2.7.0 [77ea193]
27
+ * chore(deps): update factset/waffle-actions action to v2.7.2 [00db486]
28
+ * chore(deps): update factset/waffle-actions action to v2.7.3 [791475b]
29
+ * chore(deps): update factset/waffle-actions action to v2.8.0 [42b68da]
30
+ * chore(deps): update lockfile [6862184]
31
+ * chore(deps): update lockfile [31ab993]
32
+ * chore(deps): update lockfile [18ff49b]
33
+ * chore(deps): update lockfile [018f63e]
34
+ * chore(deps): update lockfile [88635d5]
35
+ * chore(deps): update shared-actions-public/sonarsource_sonarqube-scan-action action to v7.1.0 [09e2402]
36
+ * chore(deps): update shared-actions-public/sonarsource_sonarqube-scan-action action to v7.2.0 [dcad76d]
37
+ * chore(deps): update shared-actions-public/sonarsource_sonarqube-scan-action action to v8 [1571e4e]
38
+ * chore(deps): update shared-actions-public/sonarsource_sonarqube-scan-action action to v8.1.0 [14ed672]
39
+ * chore(deps): update yarn to v4.13.0 [e510119]
40
+ * chore(deps): update yarn to v4.14.0 [aed4c63]
41
+ * chore(deps): update yarn to v4.14.1 [9a00c87]
42
+ * chore(docs): use @factset/ instead of @fds/ prefix [9f6835f]
43
+ * chore(ga): downgrade actions for GHES support [d09c2a8]
44
+ * chore(release): update changelog for v7.1.1 [fadb013]
45
+ * fix(abstract-logger): make sure a loglevel is always defined [d039198]
46
+ * fix(compressor): initialize members with null as typed [a056cf1]
47
+ * fix(connectable): mark config as potentially undefined [b8f7dca]
48
+ * fix(data-observer): unsubscribe can be undefined [e6947ab]
49
+ * fix(frontgate-ws): init message_buffer to avoid null comparison [f6aa80f]
50
+ * fix(ga): add environment to docs job [1d62d6f]
51
+ * fix(hooks): hook needs to accept generic PtlMessage [6554b6a]
52
+ * fix(session-auth): resolve incompatibility with Connectable interface [95104a8]
53
+ * fix(winston-logger): check for existing trace method [b533a24]
54
+ * feat(ga): add workflow dispatch for docs job [fb6c9eb]
55
+ * feat(ga): permit token for docs upload [ec22600]
56
+ * feat(tsconfig): migrate to TS 6 [731dcd7]
57
+ * docs(client-download): prefer factset.com domain [27a963f]
58
+ * refactor(error-handling): type errors [331915c]
59
+ * refactor(frontgate-ws-mixin): deduplicate import [6d36bbf]
60
+ * refactor(mixins): make previously implicit type signature explicit [e7c067a]
61
+ * refactor(secret-generator): improve type signature to avoid null check [230dea6]
62
+ * tests(data-observer): type test inputs [e88596c]
63
+
1
64
  ## 7.1.0 (2026-03-10)
2
65
 
3
- * feat(auth): add fetch auth with compression [13af8dc]
4
66
  * chore(deps): lock file maintenance [a9f36a7]
5
67
  * chore(deps): lock file maintenance [62ab9e8]
6
68
  * chore(deps): lock file maintenance [2453f92]
@@ -12,6 +74,8 @@
12
74
  * chore(deps): update factset/waffle-actions action to v2.6.3 [e1c8a5a]
13
75
  * chore(deps): update lockfile [093f343]
14
76
  * chore(deps): update lockfile [6c9ea37]
77
+ * chore(release): update changelog for v7.1.0 [e473077]
78
+ * feat(auth): add fetch auth with compression [13af8dc]
15
79
  * fix(dependencies): upgrade axios due to a security issue [5c72eaf]
16
80
 
17
81
  ## <small>7.0.11 (2026-02-10)</small>
@@ -11,6 +11,8 @@ const concat = (buffers) => {
11
11
  };
12
12
  export class Compressor {
13
13
  constructor() {
14
+ this.compressor = null;
15
+ this.decompressor = null;
14
16
  this.reset();
15
17
  }
16
18
  reset() {
@@ -13,6 +13,7 @@ export class AbstractLogger {
13
13
  this.defaultLevel = LogLevel.WARN;
14
14
  this.noop = () => null;
15
15
  this.name = name;
16
+ this.level = this.defaultLevel;
16
17
  this.setDefaultLevelFromLocalStorage();
17
18
  Object.assign(AbstractLogger.loggers, { [name]: this });
18
19
  }
@@ -13,7 +13,9 @@ export class WinstonLogger extends AbstractLogger {
13
13
  super(name);
14
14
  this.name = name;
15
15
  this.logger = logger;
16
- this.trace = Function.prototype.bind.call(logger.trace, logger);
16
+ if (logger.trace) {
17
+ this.trace = Function.prototype.bind.call(logger.trace, logger);
18
+ }
17
19
  this.debug = Function.prototype.bind.call(logger.debug, logger);
18
20
  this.info = Function.prototype.bind.call(logger.info, logger);
19
21
  this.warn = Function.prototype.bind.call(logger.warn, logger);
@@ -30,12 +30,27 @@ export const sessionAuth = (config, idApplication, username, password, deploymen
30
30
  _mdg2wstoken.set(this, void 0);
31
31
  _sharedSecret.set(this, void 0);
32
32
  _clientSecret.set(this, void 0);
33
+ this.connect = async () => {
34
+ __classPrivateFieldSet(this, _logOut, false, "f");
35
+ try {
36
+ __classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
37
+ await super.connect();
38
+ }
39
+ catch (e) {
40
+ __classPrivateFieldSet(this, _tokenConnectionAttempt, false, "f");
41
+ await super.connect();
42
+ const token = await __classPrivateFieldGet(this, _instances, "m", _requestOtpAuthenticationTokenForSessionHandling).call(this);
43
+ __classPrivateFieldSet(this, _mdg2wstoken, token.token, "f");
44
+ await super.disconnect();
45
+ __classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
46
+ await super.connect();
47
+ __classPrivateFieldSet(this, _mdg2wstoken, undefined, "f");
48
+ }
49
+ };
33
50
  const plainSharedSecret = SecretGenerator.generateSharedSecret(username, password);
34
51
  const plainClientSecret = SecretGenerator.generateClientSecret(username, password);
35
- if (plainSharedSecret && plainClientSecret) {
36
- __classPrivateFieldSet(this, _sharedSecret, Buffer.from(plainSharedSecret), "f");
37
- __classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
38
- }
52
+ __classPrivateFieldSet(this, _sharedSecret, Buffer.from(plainSharedSecret), "f");
53
+ __classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
39
54
  this.hooks.hook('frontgateConnection:beforeConnect', (settings) => {
40
55
  void this.hooks.callHook('frontgateConnection:setIdApp', ID_APP_AUTHENTICATED);
41
56
  void this.hooks.callHook('frontgateConnection:setIdUser', ID_USER_AUTHENTICATED);
@@ -83,23 +98,6 @@ export const sessionAuth = (config, idApplication, username, password, deploymen
83
98
  await this.hooks.callHook('frontgateConnection:authenticated');
84
99
  });
85
100
  }
86
- async connect() {
87
- __classPrivateFieldSet(this, _logOut, false, "f");
88
- try {
89
- __classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
90
- await super.connect();
91
- }
92
- catch (e) {
93
- __classPrivateFieldSet(this, _tokenConnectionAttempt, false, "f");
94
- await super.connect();
95
- const token = await __classPrivateFieldGet(this, _instances, "m", _requestOtpAuthenticationTokenForSessionHandling).call(this);
96
- __classPrivateFieldSet(this, _mdg2wstoken, token.token, "f");
97
- await super.disconnect();
98
- __classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
99
- await super.connect();
100
- __classPrivateFieldSet(this, _mdg2wstoken, undefined, "f");
101
- }
102
- }
103
101
  async connectSession() {
104
102
  __classPrivateFieldSet(this, _logOut, false, "f");
105
103
  __classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
@@ -26,10 +26,8 @@ export const userPasswordAuth = (idApplication, username, password, deploymentSt
26
26
  _clientSecret.set(this, void 0);
27
27
  const plainSharedSecret = SecretGenerator.generateSharedSecret(username, password);
28
28
  const plainClientSecret = SecretGenerator.generateClientSecret(username, password);
29
- if (plainSharedSecret && plainClientSecret) {
30
- __classPrivateFieldSet(this, _sharedSecret, Buffer.from(plainSharedSecret), "f");
31
- __classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
32
- }
29
+ __classPrivateFieldSet(this, _sharedSecret, Buffer.from(plainSharedSecret), "f");
30
+ __classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
33
31
  this.hooks.hook('frontgateConnection:connected', async (conf) => {
34
32
  void this.hooks.callHook('frontgateConnection:setIdApp', idApplication);
35
33
  void this.hooks.callHook('frontgateConnection:setIdUser', ID_USER_AUTHENTICATED);
@@ -34,7 +34,7 @@ export const wsConnection = (conf) => {
34
34
  _jobId.set(this, 0);
35
35
  _idApplication.set(this, void 0);
36
36
  _idUser.set(this, void 0);
37
- _message_buffer_size.set(this, void 0);
37
+ _message_buffer_size.set(this, 0);
38
38
  _msgBuffer.set(this, []);
39
39
  __classPrivateFieldSet(this, _idApplication, ID_APP_AUTHENTICATED, "f");
40
40
  __classPrivateFieldSet(this, _idUser, ID_USER_NONE, "f");
@@ -68,6 +68,16 @@ export const endpointSubscriptions = (originalConfig) => {
68
68
  return;
69
69
  }
70
70
  const observer = new FrontgateClientEndpointDataObserver(response.header.id_job, hlResponseData);
71
+ if (subscriptionZombie) {
72
+ this.log(LogLevel.WARN, `Zombie subscription detected for ${key}. Cancelling stale subscription on server.`);
73
+ const cancelationRequest = new CancelSubscriptionRequest(observer.idJob);
74
+ void this.hooks.callHook('frontgateConnection:sendMessage', {
75
+ message: cancelationRequest.getPtlMessage(),
76
+ callbackType: 'job',
77
+ callbackId: '',
78
+ });
79
+ return;
80
+ }
71
81
  let removeMessageUpdateHook = this.hooks.hook(`frontgateConnection:response:${subscriptionMsg.callbackId}`, (update) => {
72
82
  if (!update.Message.includes('HighLevelUpdate')) {
73
83
  if (update.Message.includes('SubscriptionLoss')) {
@@ -98,8 +108,9 @@ export const endpointSubscriptions = (originalConfig) => {
98
108
  removeMessageUpdateHook();
99
109
  this.log(LogLevel.INFO, `Resubscribing to ${key} due to reconnect`);
100
110
  await this.hooks.callHook('frontgateConnection:sendMessage', subscriptionMsg);
111
+ let removeResubscribeHookOnce;
101
112
  const resubscribePromise = new Promise((res, rej) => {
102
- this.hooks.hookOnce(`frontgateConnection:response:${subscriptionMsg.callbackId}`, (resp) => {
113
+ removeResubscribeHookOnce = this.hooks.hookOnce(`frontgateConnection:response:${subscriptionMsg.callbackId}`, (resp) => {
103
114
  if (!resp.Message.includes('HighLevelResponse')) {
104
115
  const err = new ErrorResponse(resp);
105
116
  this.log(LogLevel.ERROR, `Unexpected response: ${resp.Message}`);
@@ -111,7 +122,7 @@ export const endpointSubscriptions = (originalConfig) => {
111
122
  observer.idJob = resp.header.id_job;
112
123
  if (subscriptionZombie) {
113
124
  this.log(LogLevel.WARN, `Zombie subscription detected for ${key}. Initiating unsubscribe.`);
114
- observer.unsubscribe();
125
+ observer.unsubscribe?.();
115
126
  res();
116
127
  return;
117
128
  }
@@ -156,6 +167,7 @@ export const endpointSubscriptions = (originalConfig) => {
156
167
  await useTimeout(timeOutInMs, 'Request timeout reached', resubscribePromise);
157
168
  }
158
169
  catch (e) {
170
+ removeResubscribeHookOnce?.();
159
171
  subscriptionZombie = true;
160
172
  observer.pushError(new ErrorResponse({ Message: 'Resubscribe failed', Error: e }));
161
173
  }
@@ -188,11 +200,6 @@ export const endpointSubscriptions = (originalConfig) => {
188
200
  __classPrivateFieldGet(this, _subscriptions, "f").set(key, observer);
189
201
  const currentSubscounts = __classPrivateFieldGet(this, _subscriptionCounts, "f").get(key) ?? 0;
190
202
  __classPrivateFieldGet(this, _subscriptionCounts, "f").set(key, currentSubscounts + 1);
191
- if (subscriptionZombie) {
192
- this.log(LogLevel.WARN, `Zombie subscription detected for ${key}. Initiating unsubscribe.`);
193
- observer.unsubscribe();
194
- return;
195
- }
196
203
  resolve(observer);
197
204
  });
198
205
  })
@@ -1 +1 @@
1
- export const PACKAGE_JSON = { version: '7.1.0', package: '@factset/frontgate-js-sdk' };
1
+ export const PACKAGE_JSON = { version: '7.1.2', package: '@factset/frontgate-js-sdk' };
@@ -14,6 +14,8 @@ const concat = (buffers) => {
14
14
  };
15
15
  class Compressor {
16
16
  constructor() {
17
+ this.compressor = null;
18
+ this.decompressor = null;
17
19
  this.reset();
18
20
  }
19
21
  reset() {
@@ -16,6 +16,7 @@ class AbstractLogger {
16
16
  this.defaultLevel = LogLevel.WARN;
17
17
  this.noop = () => null;
18
18
  this.name = name;
19
+ this.level = this.defaultLevel;
19
20
  this.setDefaultLevelFromLocalStorage();
20
21
  Object.assign(AbstractLogger.loggers, { [name]: this });
21
22
  }
@@ -16,7 +16,9 @@ class WinstonLogger extends AbstractLogger_1.AbstractLogger {
16
16
  super(name);
17
17
  this.name = name;
18
18
  this.logger = logger;
19
- this.trace = Function.prototype.bind.call(logger.trace, logger);
19
+ if (logger.trace) {
20
+ this.trace = Function.prototype.bind.call(logger.trace, logger);
21
+ }
20
22
  this.debug = Function.prototype.bind.call(logger.debug, logger);
21
23
  this.info = Function.prototype.bind.call(logger.info, logger);
22
24
  this.warn = Function.prototype.bind.call(logger.warn, logger);
@@ -33,12 +33,27 @@ const sessionAuth = (config, idApplication, username, password, deploymentStage)
33
33
  _mdg2wstoken.set(this, void 0);
34
34
  _sharedSecret.set(this, void 0);
35
35
  _clientSecret.set(this, void 0);
36
+ this.connect = async () => {
37
+ __classPrivateFieldSet(this, _logOut, false, "f");
38
+ try {
39
+ __classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
40
+ await super.connect();
41
+ }
42
+ catch (e) {
43
+ __classPrivateFieldSet(this, _tokenConnectionAttempt, false, "f");
44
+ await super.connect();
45
+ const token = await __classPrivateFieldGet(this, _instances, "m", _requestOtpAuthenticationTokenForSessionHandling).call(this);
46
+ __classPrivateFieldSet(this, _mdg2wstoken, token.token, "f");
47
+ await super.disconnect();
48
+ __classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
49
+ await super.connect();
50
+ __classPrivateFieldSet(this, _mdg2wstoken, undefined, "f");
51
+ }
52
+ };
36
53
  const plainSharedSecret = compat_1.SecretGenerator.generateSharedSecret(username, password);
37
54
  const plainClientSecret = compat_1.SecretGenerator.generateClientSecret(username, password);
38
- if (plainSharedSecret && plainClientSecret) {
39
- __classPrivateFieldSet(this, _sharedSecret, Buffer.from(plainSharedSecret), "f");
40
- __classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
41
- }
55
+ __classPrivateFieldSet(this, _sharedSecret, Buffer.from(plainSharedSecret), "f");
56
+ __classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
42
57
  this.hooks.hook('frontgateConnection:beforeConnect', (settings) => {
43
58
  void this.hooks.callHook('frontgateConnection:setIdApp', authentication_1.ID_APP_AUTHENTICATED);
44
59
  void this.hooks.callHook('frontgateConnection:setIdUser', authentication_1.ID_USER_AUTHENTICATED);
@@ -86,23 +101,6 @@ const sessionAuth = (config, idApplication, username, password, deploymentStage)
86
101
  await this.hooks.callHook('frontgateConnection:authenticated');
87
102
  });
88
103
  }
89
- async connect() {
90
- __classPrivateFieldSet(this, _logOut, false, "f");
91
- try {
92
- __classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
93
- await super.connect();
94
- }
95
- catch (e) {
96
- __classPrivateFieldSet(this, _tokenConnectionAttempt, false, "f");
97
- await super.connect();
98
- const token = await __classPrivateFieldGet(this, _instances, "m", _requestOtpAuthenticationTokenForSessionHandling).call(this);
99
- __classPrivateFieldSet(this, _mdg2wstoken, token.token, "f");
100
- await super.disconnect();
101
- __classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
102
- await super.connect();
103
- __classPrivateFieldSet(this, _mdg2wstoken, undefined, "f");
104
- }
105
- }
106
104
  async connectSession() {
107
105
  __classPrivateFieldSet(this, _logOut, false, "f");
108
106
  __classPrivateFieldSet(this, _tokenConnectionAttempt, true, "f");
@@ -29,10 +29,8 @@ const userPasswordAuth = (idApplication, username, password, deploymentStage) =>
29
29
  _clientSecret.set(this, void 0);
30
30
  const plainSharedSecret = compat_1.SecretGenerator.generateSharedSecret(username, password);
31
31
  const plainClientSecret = compat_1.SecretGenerator.generateClientSecret(username, password);
32
- if (plainSharedSecret && plainClientSecret) {
33
- __classPrivateFieldSet(this, _sharedSecret, Buffer.from(plainSharedSecret), "f");
34
- __classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
35
- }
32
+ __classPrivateFieldSet(this, _sharedSecret, Buffer.from(plainSharedSecret), "f");
33
+ __classPrivateFieldSet(this, _clientSecret, Buffer.from(plainClientSecret), "f");
36
34
  this.hooks.hook('frontgateConnection:connected', async (conf) => {
37
35
  void this.hooks.callHook('frontgateConnection:setIdApp', idApplication);
38
36
  void this.hooks.callHook('frontgateConnection:setIdUser', authentication_1.ID_USER_AUTHENTICATED);
@@ -40,7 +40,7 @@ const wsConnection = (conf) => {
40
40
  _jobId.set(this, 0);
41
41
  _idApplication.set(this, void 0);
42
42
  _idUser.set(this, void 0);
43
- _message_buffer_size.set(this, void 0);
43
+ _message_buffer_size.set(this, 0);
44
44
  _msgBuffer.set(this, []);
45
45
  __classPrivateFieldSet(this, _idApplication, authentication_1.ID_APP_AUTHENTICATED, "f");
46
46
  __classPrivateFieldSet(this, _idUser, authentication_1.ID_USER_NONE, "f");
@@ -71,6 +71,16 @@ const endpointSubscriptions = (originalConfig) => {
71
71
  return;
72
72
  }
73
73
  const observer = new __1.FrontgateClientEndpointDataObserver(response.header.id_job, hlResponseData);
74
+ if (subscriptionZombie) {
75
+ this.log(logger_1.LogLevel.WARN, `Zombie subscription detected for ${key}. Cancelling stale subscription on server.`);
76
+ const cancelationRequest = new message_1.CancelSubscriptionRequest(observer.idJob);
77
+ void this.hooks.callHook('frontgateConnection:sendMessage', {
78
+ message: cancelationRequest.getPtlMessage(),
79
+ callbackType: 'job',
80
+ callbackId: '',
81
+ });
82
+ return;
83
+ }
74
84
  let removeMessageUpdateHook = this.hooks.hook(`frontgateConnection:response:${subscriptionMsg.callbackId}`, (update) => {
75
85
  if (!update.Message.includes('HighLevelUpdate')) {
76
86
  if (update.Message.includes('SubscriptionLoss')) {
@@ -101,8 +111,9 @@ const endpointSubscriptions = (originalConfig) => {
101
111
  removeMessageUpdateHook();
102
112
  this.log(logger_1.LogLevel.INFO, `Resubscribing to ${key} due to reconnect`);
103
113
  await this.hooks.callHook('frontgateConnection:sendMessage', subscriptionMsg);
114
+ let removeResubscribeHookOnce;
104
115
  const resubscribePromise = new Promise((res, rej) => {
105
- this.hooks.hookOnce(`frontgateConnection:response:${subscriptionMsg.callbackId}`, (resp) => {
116
+ removeResubscribeHookOnce = this.hooks.hookOnce(`frontgateConnection:response:${subscriptionMsg.callbackId}`, (resp) => {
106
117
  if (!resp.Message.includes('HighLevelResponse')) {
107
118
  const err = new message_1.ErrorResponse(resp);
108
119
  this.log(logger_1.LogLevel.ERROR, `Unexpected response: ${resp.Message}`);
@@ -114,7 +125,7 @@ const endpointSubscriptions = (originalConfig) => {
114
125
  observer.idJob = resp.header.id_job;
115
126
  if (subscriptionZombie) {
116
127
  this.log(logger_1.LogLevel.WARN, `Zombie subscription detected for ${key}. Initiating unsubscribe.`);
117
- observer.unsubscribe();
128
+ observer.unsubscribe?.();
118
129
  res();
119
130
  return;
120
131
  }
@@ -159,6 +170,7 @@ const endpointSubscriptions = (originalConfig) => {
159
170
  await (0, functions_1.useTimeout)(timeOutInMs, 'Request timeout reached', resubscribePromise);
160
171
  }
161
172
  catch (e) {
173
+ removeResubscribeHookOnce?.();
162
174
  subscriptionZombie = true;
163
175
  observer.pushError(new message_1.ErrorResponse({ Message: 'Resubscribe failed', Error: e }));
164
176
  }
@@ -191,11 +203,6 @@ const endpointSubscriptions = (originalConfig) => {
191
203
  __classPrivateFieldGet(this, _subscriptions, "f").set(key, observer);
192
204
  const currentSubscounts = __classPrivateFieldGet(this, _subscriptionCounts, "f").get(key) ?? 0;
193
205
  __classPrivateFieldGet(this, _subscriptionCounts, "f").set(key, currentSubscounts + 1);
194
- if (subscriptionZombie) {
195
- this.log(logger_1.LogLevel.WARN, `Zombie subscription detected for ${key}. Initiating unsubscribe.`);
196
- observer.unsubscribe();
197
- return;
198
- }
199
206
  resolve(observer);
200
207
  });
201
208
  })
@@ -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.1.0', package: '@factset/frontgate-js-sdk' };
4
+ exports.PACKAGE_JSON = { version: '7.1.2', package: '@factset/frontgate-js-sdk' };
@@ -5,8 +5,10 @@ export declare class SecretGenerator {
5
5
  private static readonly BCRYPT_KEY_B;
6
6
  private static readonly ALGORITHM;
7
7
  static createEncryptedSecret(salt: Buffer, sharedSecret: Buffer, clientSecret: Buffer): number[];
8
- static generateClientSecret(username: string, password: string, callback?: (err: Error, encrypted: string) => void): string | undefined;
9
- static generateSharedSecret(username: string, password: string, callback?: (err: Error, encrypted: string) => void): string | undefined;
8
+ static generateClientSecret(username: string, password: string): string;
9
+ static generateClientSecret(username: string, password: string, callback: (err: Error | null, encrypted: string | undefined) => void): undefined;
10
+ static generateSharedSecret(username: string, password: string): string;
11
+ static generateSharedSecret(username: string, password: string, callback: (err: Error | null, encrypted: string | undefined) => void): undefined;
10
12
  static getEncryptionKey(salt: Buffer, secret: Buffer): Buffer;
11
13
  private static generateSalt;
12
14
  private static create128bitSeed;
@@ -9,17 +9,4 @@ export interface AuthTokenRequestable {
9
9
  requestAuthenticationTokenForCookieTokenAuthentication: (lifetimeSeconds?: number, idUser?: number, idApplication?: number, timeOutInMs?: number) => Promise<CookieTokenAuthenticationFactors>;
10
10
  }
11
11
  export type usedHooksByAuthTokenRequest = CalledHooksByConnection;
12
- export declare const authTokenRequest: () => (<T extends AConstructorTypeOf<FrontgateClient<usedHooksByAuthTokenRequest & DefaultFrontgateClientHooks>>>(Base: T) => {
13
- new (...args: any[]): {
14
- requestAuthenticationToken(lifetimeSeconds?: number, idUser?: number, idApplication?: number, timeOutInMs?: number): Promise<{
15
- token: string;
16
- expiry: number;
17
- }>;
18
- requestAuthenticationTokenForCookieTokenAuthentication(lifetimeSeconds?: number, idUser?: number, idApplication?: number, timeOutInMs?: number): Promise<CookieTokenAuthenticationFactors>;
19
- logger: import("..").LoggerInterface | undefined;
20
- hooks: import("hookable").Hookable<CalledHooksByConnection & import("../FrontgateClient").CalledHooksByBase, import("hookable").HookKeys<CalledHooksByConnection & import("../FrontgateClient").CalledHooksByBase>>;
21
- readonly "__#private@#defaultTimeoutInMs": number;
22
- get defaultTimeoutInMs(): number;
23
- log(level: import("..").LogLevel, ...args: unknown[]): void;
24
- };
25
- } & T) & import(".").ExtendendMixinFactoryOptions;
12
+ export declare const authTokenRequest: () => (<T extends AConstructorTypeOf<FrontgateClient<usedHooksByAuthTokenRequest & DefaultFrontgateClientHooks>>>(Base: T) => typeof Base & AConstructorTypeOf<AuthTokenRequestable>) & import(".").ExtendendMixinFactoryOptions;
@@ -1,6 +1,6 @@
1
1
  import { type AConstructorTypeOf, type CalledHooksByConnection } from '.';
2
2
  import type { DefaultFrontgateClientHooks, FrontgateClient } from '../FrontgateClient';
3
- import type { HighLevelRequestResult, PtlMessage } from '../common/interfaces';
3
+ import type { HighLevelRequestResult } from '../common/interfaces';
4
4
  import { type HighLevelRequestMethod, type HighLevelRequestOptions } from '../message';
5
5
  export interface EndpointRequestable {
6
6
  requestEndpoint: <ResponseData = any>(method: HighLevelRequestMethod, path: string, data?: Record<string, unknown>, options?: HighLevelRequestOptions, timeOutInMs?: number) => Promise<HighLevelRequestResult<ResponseData>>;
@@ -10,14 +10,4 @@ export interface EndpointRequestMixinOptions {
10
10
  disableChunkedResponse?: boolean;
11
11
  allowPermissionDeniedResponse?: boolean;
12
12
  }
13
- export declare const endpointRequest: (config?: EndpointRequestMixinOptions) => (<T extends AConstructorTypeOf<FrontgateClient<usedHooksByEndpointRequest & DefaultFrontgateClientHooks>>>(Base: T) => {
14
- new (...args: any[]): {
15
- requestEndpoint<ResponseData = any>(method: HighLevelRequestMethod, path: string, data?: Record<string, unknown>, options?: HighLevelRequestOptions, timeOutInMs?: number): Promise<HighLevelRequestResult<ResponseData>>;
16
- "__#private@#hasNextChunk"(msg: PtlMessage): boolean;
17
- logger: import("..").LoggerInterface | undefined;
18
- hooks: import("hookable").Hookable<CalledHooksByConnection & import("../FrontgateClient").CalledHooksByBase, import("hookable").HookKeys<CalledHooksByConnection & import("../FrontgateClient").CalledHooksByBase>>;
19
- readonly "__#private@#defaultTimeoutInMs": number;
20
- get defaultTimeoutInMs(): number;
21
- log(level: import("..").LogLevel, ...args: unknown[]): void;
22
- };
23
- } & T) & import(".").ExtendendMixinFactoryOptions;
13
+ export declare const endpointRequest: (config?: EndpointRequestMixinOptions) => (<T extends AConstructorTypeOf<FrontgateClient<usedHooksByEndpointRequest & DefaultFrontgateClientHooks>>>(Base: T) => typeof Base & AConstructorTypeOf<EndpointRequestable>) & import(".").ExtendendMixinFactoryOptions;
@@ -1,18 +1,9 @@
1
1
  import { type AConstructorTypeOf, type CalledHooksByConnection } from '.';
2
2
  import type { DefaultFrontgateClientHooks, FrontgateClient } from '../FrontgateClient';
3
3
  import type { HTTPProxyRequestResult } from '../common/interfaces/result/HTTPProxyRequestResult';
4
- import type { HTTPProxyRequestBody, HTTPMethod, HTTPProxyRequestOptions } from '../message';
4
+ import type { HTTPMethod, HTTPProxyRequestOptions } from '../message';
5
5
  export interface HTTPProxyRequestable {
6
6
  requestProxyEndpoint: (method: HTTPMethod, path: string, body?: Record<string, unknown>, options?: HTTPProxyRequestOptions, timeOutInMs?: number) => Promise<HTTPProxyRequestResult>;
7
7
  }
8
8
  export type usedHooksByHTTPProxyRequest = CalledHooksByConnection;
9
- export declare const httpProxyRequest: () => (<T extends AConstructorTypeOf<FrontgateClient<usedHooksByHTTPProxyRequest & DefaultFrontgateClientHooks>>>(Base: T) => {
10
- new (...args: any[]): {
11
- requestProxyEndpoint(method: HTTPMethod, path: string, body?: HTTPProxyRequestBody, options?: HTTPProxyRequestOptions, timeOutInMs?: number): Promise<HTTPProxyRequestResult>;
12
- logger: import("..").LoggerInterface | undefined;
13
- hooks: import("hookable").Hookable<CalledHooksByConnection & import("../FrontgateClient").CalledHooksByBase, import("hookable").HookKeys<CalledHooksByConnection & import("../FrontgateClient").CalledHooksByBase>>;
14
- readonly "__#private@#defaultTimeoutInMs": number;
15
- get defaultTimeoutInMs(): number;
16
- log(level: import("..").LogLevel, ...args: unknown[]): void;
17
- };
18
- } & T) & import(".").ExtendendMixinFactoryOptions;
9
+ export declare const httpProxyRequest: () => (<T extends AConstructorTypeOf<FrontgateClient<usedHooksByHTTPProxyRequest & DefaultFrontgateClientHooks>>>(Base: T) => typeof Base & AConstructorTypeOf<HTTPProxyRequestable>) & import(".").ExtendendMixinFactoryOptions;
@@ -1,12 +1,4 @@
1
1
  import { type AConstructorTypeOf } from '.';
2
2
  import type { FrontgateClient } from '../FrontgateClient';
3
3
  import type { LogLevel, LoggerInterface } from '../logger';
4
- export declare const logger: (loggerInstance: LoggerInterface, logLevel?: LogLevel) => (<T extends AConstructorTypeOf<FrontgateClient>>(Base: T) => {
5
- new (...args: any[]): {
6
- logger: LoggerInterface | undefined;
7
- hooks: import("hookable").Hookable<import("../FrontgateClient").CalledHooksByBase, "base:log">;
8
- readonly "__#private@#defaultTimeoutInMs": number;
9
- get defaultTimeoutInMs(): number;
10
- log(level: LogLevel, ...args: unknown[]): void;
11
- };
12
- } & T) & import(".").ExtendendMixinFactoryOptions;
4
+ export declare const logger: (loggerInstance: LoggerInterface, logLevel?: LogLevel) => (<T extends AConstructorTypeOf<FrontgateClient>>(Base: T) => typeof Base) & import(".").ExtendendMixinFactoryOptions;
@@ -1,14 +1,4 @@
1
1
  import { type AConstructorTypeOf, type CalledHooksByConnection } from '.';
2
2
  import type { DefaultFrontgateClientHooks, FrontgateClient } from '../FrontgateClient';
3
- import { Compressor } from '../connection/util/Compressor';
4
3
  export type usedHooksByMessageCompressor = CalledHooksByConnection;
5
- export declare const messageCompressor: () => (<T extends AConstructorTypeOf<FrontgateClient<usedHooksByMessageCompressor & DefaultFrontgateClientHooks>>>(Base: T) => {
6
- new (...args: any[]): {
7
- readonly "__#private@#compressor": Compressor;
8
- logger: import("..").LoggerInterface | undefined;
9
- hooks: import("hookable").Hookable<CalledHooksByConnection & import("../FrontgateClient").CalledHooksByBase, import("hookable").HookKeys<CalledHooksByConnection & import("../FrontgateClient").CalledHooksByBase>>;
10
- readonly "__#private@#defaultTimeoutInMs": number;
11
- get defaultTimeoutInMs(): number;
12
- log(level: import("..").LogLevel, ...args: unknown[]): void;
13
- };
14
- } & T) & import(".").ExtendendMixinFactoryOptions;
4
+ export declare const messageCompressor: () => (<T extends AConstructorTypeOf<FrontgateClient<usedHooksByMessageCompressor & DefaultFrontgateClientHooks>>>(Base: T) => typeof Base) & import(".").ExtendendMixinFactoryOptions;
@@ -1,20 +1,5 @@
1
1
  import { type SpanContext } from '@opentelemetry/api';
2
2
  import { type AConstructorTypeOf, type CalledHooksByConnection } from '.';
3
3
  import type { DefaultFrontgateClientHooks, FrontgateClient } from '../FrontgateClient';
4
- export declare const openTelemetry: () => (<T extends AConstructorTypeOf<FrontgateClient<CalledHooksByConnection & DefaultFrontgateClientHooks>>>(Base: T) => {
5
- new (...args: any[]): {
6
- "__#private@#createSpanHeader"(tracing: SpanContext): {
7
- tracing: {
8
- value: {
9
- value: number[];
10
- };
11
- };
12
- } | undefined;
13
- logger: import("..").LoggerInterface | undefined;
14
- hooks: import("hookable").Hookable<CalledHooksByConnection & import("../FrontgateClient").CalledHooksByBase, import("hookable").HookKeys<CalledHooksByConnection & import("../FrontgateClient").CalledHooksByBase>>;
15
- readonly "__#private@#defaultTimeoutInMs": number;
16
- get defaultTimeoutInMs(): number;
17
- log(level: import("..").LogLevel, ...args: unknown[]): void;
18
- };
19
- } & T) & import(".").ExtendendMixinFactoryOptions;
4
+ export declare const openTelemetry: () => (<T extends AConstructorTypeOf<FrontgateClient<CalledHooksByConnection & DefaultFrontgateClientHooks>>>(Base: T) => typeof Base) & import(".").ExtendendMixinFactoryOptions;
20
5
  export declare const encodeSpanContext: (spanContext: SpanContext) => number[];
@@ -5,13 +5,4 @@ export interface Pingable {
5
5
  ping: (timeOutInMs?: number) => Promise<PingResponse>;
6
6
  }
7
7
  export type usedHooksByPingRequest = CalledHooksByConnection;
8
- export declare const pingRequests: () => (<T extends AConstructorTypeOf<FrontgateClient<usedHooksByPingRequest & DefaultFrontgateClientHooks>>>(Base: T) => {
9
- new (...args: any[]): {
10
- ping(timeOutInMs?: number): Promise<PingResponse>;
11
- logger: import("..").LoggerInterface | undefined;
12
- hooks: import("hookable").Hookable<CalledHooksByConnection & import("../FrontgateClient").CalledHooksByBase, import("hookable").HookKeys<CalledHooksByConnection & import("../FrontgateClient").CalledHooksByBase>>;
13
- readonly "__#private@#defaultTimeoutInMs": number;
14
- get defaultTimeoutInMs(): number;
15
- log(level: import("..").LogLevel, ...args: unknown[]): void;
16
- };
17
- } & T) & import(".").ExtendendMixinFactoryOptions;
8
+ export declare const pingRequests: () => (<T extends AConstructorTypeOf<FrontgateClient<usedHooksByPingRequest & DefaultFrontgateClientHooks>>>(Base: T) => typeof Base & AConstructorTypeOf<Pingable>) & import(".").ExtendendMixinFactoryOptions;
@@ -1,22 +1,10 @@
1
1
  import type { CloseEvent } from 'ws';
2
2
  import { type AConstructorTypeOf, type CalledHooksByConnection } from '.';
3
3
  import type { DefaultFrontgateClientHooks, FrontgateClient } from '../FrontgateClient';
4
- import { LogLevel } from '../logger';
5
4
  export type usedHooksByReconnect = CalledHooksByConnection;
6
5
  export interface CalledHooksByReconnect {
7
6
  'reconnect:attempt': (error: CloseEvent) => void;
8
7
  'reconnect:failed': (error: CloseEvent) => void;
9
8
  'reconnect:success': () => void;
10
9
  }
11
- export declare const reconnect: (reconnectDelaysInMs?: number[]) => (<T extends AConstructorTypeOf<FrontgateClient<usedHooksByReconnect & CalledHooksByReconnect & DefaultFrontgateClientHooks>>>(Base: T) => {
12
- new (...args: any[]): {
13
- "__#private@#reconnectAttempts": number;
14
- readonly "__#private@#reconnectDelays": number[];
15
- "__#private@#reconnectTimer": NodeJS.Timeout | undefined;
16
- logger: import("../logger").LoggerInterface | undefined;
17
- hooks: import("hookable").Hookable<CalledHooksByConnection & CalledHooksByReconnect & import("../FrontgateClient").CalledHooksByBase, import("hookable").HookKeys<CalledHooksByConnection & CalledHooksByReconnect & import("../FrontgateClient").CalledHooksByBase>>;
18
- readonly "__#private@#defaultTimeoutInMs": number;
19
- get defaultTimeoutInMs(): number;
20
- log(level: LogLevel, ...args: unknown[]): void;
21
- };
22
- } & T) & import(".").ExtendendMixinFactoryOptions;
10
+ export declare const reconnect: (reconnectDelaysInMs?: number[]) => (<T extends AConstructorTypeOf<FrontgateClient<usedHooksByReconnect & CalledHooksByReconnect & DefaultFrontgateClientHooks>>>(Base: T) => typeof Base) & import(".").ExtendendMixinFactoryOptions;