@openfin/cloud-interop-core-api 0.0.1-alpha.1a0a938 → 0.0.1-alpha.1aa5f8a

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/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # @openfin/cloud-interop-core-api
2
2
 
3
- This package contains the core interop library that handles all interactions with the HERE Cloud Interop Service.
3
+ This package contains the core interop library that handles all interactions with the Here™ Cloud Interop Service.
4
4
 
5
5
  It is callable via browser or node applications.
6
6
 
7
7
 
8
8
  ## Authentication
9
9
 
10
- The library supports authentication with the HERE Cloud Interop Service using the following methods:
10
+ The library supports authentication with the Here™ Cloud Interop Service using the following methods:
11
11
  - Basic Authentication
12
12
  - JWT Token Authentication
13
13
  - Default Authentication i.e. Interactive session based authentication using cookies
package/bundle.d.ts CHANGED
@@ -245,36 +245,36 @@ export declare class CloudInteropAPI {
245
245
  /**
246
246
  * Connects and creates a session on the Cloud Interop service
247
247
  *
248
- * @param parameters - The parameters to use to connect
249
- * @returns Promise that resolves when connection is established
248
+ * @param {ConnectParameters} parameters - The parameters to use to connect
249
+ * @returns {*} {Promise<void>}
250
250
  * @memberof CloudInteropAPI
251
- * @throws CloudInteropAPIError - If an error occurs during connection
252
- * @throws AuthorizationError - If the connection is unauthorized
251
+ * @throws {CloudInteropAPIError} - If an error occurs during connection
252
+ * @throws {AuthorizationError} - If the connection is unauthorized
253
253
  */
254
254
  connect(parameters: ConnectParameters): Promise<void>;
255
255
  /**
256
256
  * Disconnects from the Cloud Interop service
257
257
  *
258
- * @returns Promise that resolves when disconnected
258
+ * @returns {*} {Promise<void>}
259
259
  * @memberof CloudInteropAPI
260
- * @throws CloudInteropAPIError - If an error occurs during disconnection
260
+ * @throws {CloudInteropAPIError} - If an error occurs during disconnection
261
261
  */
262
262
  disconnect(): Promise<void>;
263
263
  /**
264
264
  * Publishes a new context for the given context group to the other connected sessions
265
265
  *
266
- * @param contextGroup - The context group to publish to
267
- * @param context - The context to publish
268
- * @returns Promise that resolves when context is published
266
+ * @param {string} contextGroup - The context group to publish to
267
+ * @param {object} context - The context to publish
268
+ * @returns {*} {Promise<void>}
269
269
  * @memberof CloudInteropAPI
270
270
  */
271
271
  setContext(contextGroup: string, context: InferredContext): Promise<void>;
272
272
  /**
273
273
  * Starts an intent discovery operation
274
274
  *
275
- * @returns Promise that resolves when intent discovery is started
275
+ * @returns {*} {Promise<void>}
276
276
  * @memberof CloudInteropAPI
277
- * @throws CloudInteropAPIError - If an error occurs during intent discovery
277
+ * @throws {CloudInteropAPIError} - If an error occurs during intent discovery
278
278
  */
279
279
  startIntentDiscovery(options: StartIntentDiscoveryOptions): Promise<void>;
280
280
  raiseIntent(options: RaiseIntentAPIOptions): Promise<void>;
@@ -418,7 +418,6 @@ export declare type CreateSessionResponse = {
418
418
  sub: string;
419
419
  platformId: string;
420
420
  sourceId: string;
421
- localSessionExpiryHandling?: boolean;
422
421
  };
423
422
 
424
423
  declare const errorSchema: z.ZodObject<{
package/index.cjs CHANGED
@@ -1,12 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var buffer = require('buffer');
4
- require('fs');
5
- require('path');
6
4
  var mqtt = require('mqtt');
7
5
 
8
- var u=n=>{let e=n.replaceAll("-","+").replaceAll("_","/");return e.padEnd(e.length+(4-e.length%4)%4,"=")};
9
-
10
6
  class CloudInteropAPIError extends Error {
11
7
  code;
12
8
  constructor(message = 'An unexpected error has occurred', code = 'UNEXPECTED_ERROR', cause) {
@@ -357,7 +353,6 @@ class CloudInteropAPI {
357
353
  #attemptingToReconnect = false;
358
354
  #events = new EventController();
359
355
  #intents;
360
- #sessionTimer;
361
356
  constructor(cloudInteropSettings) {
362
357
  this.#cloudInteropSettings = cloudInteropSettings;
363
358
  }
@@ -370,11 +365,11 @@ class CloudInteropAPI {
370
365
  /**
371
366
  * Connects and creates a session on the Cloud Interop service
372
367
  *
373
- * @param parameters - The parameters to use to connect
374
- * @returns Promise that resolves when connection is established
368
+ * @param {ConnectParameters} parameters - The parameters to use to connect
369
+ * @returns {*} {Promise<void>}
375
370
  * @memberof CloudInteropAPI
376
- * @throws CloudInteropAPIError - If an error occurs during connection
377
- * @throws AuthorizationError - If the connection is unauthorized
371
+ * @throws {CloudInteropAPIError} - If an error occurs during connection
372
+ * @throws {AuthorizationError} - If the connection is unauthorized
378
373
  */
379
374
  async connect(parameters) {
380
375
  this.#validateConnectParams(parameters);
@@ -398,11 +393,6 @@ class CloudInteropAPI {
398
393
  throw new CloudInteropAPIError(`Failed to connect to the Cloud Interop service: ${this.#cloudInteropSettings.url}`, 'ERR_CONNECT', new Error(createSessionResponse.statusText));
399
394
  }
400
395
  this.#sessionDetails = (await createSessionResponse.json());
401
- // If local session expiry handling is enabled, start the session timer
402
- if (this.#sessionDetails.localSessionExpiryHandling) {
403
- this.#logger('debug', `Local session expiry handling is enabled`);
404
- this.#startSessionTimer();
405
- }
406
396
  const sessionRootTopic = this.#sessionDetails.sessionRootTopic;
407
397
  const clientOptions = {
408
398
  keepalive: this.#keepAliveIntervalSeconds,
@@ -432,7 +422,9 @@ class CloudInteropAPI {
432
422
  if (error instanceof mqtt.ErrorWithReasonCode) {
433
423
  switch (error.code) {
434
424
  case BadUserNamePasswordError: {
435
- this.#handleSessionExpiry();
425
+ await this.#disconnect(false);
426
+ this.#logger('warn', `Session expired`);
427
+ this.#events.emitEvent('session-expired');
436
428
  return;
437
429
  }
438
430
  default: {
@@ -486,9 +478,9 @@ class CloudInteropAPI {
486
478
  /**
487
479
  * Disconnects from the Cloud Interop service
488
480
  *
489
- * @returns Promise that resolves when disconnected
481
+ * @returns {*} {Promise<void>}
490
482
  * @memberof CloudInteropAPI
491
- * @throws CloudInteropAPIError - If an error occurs during disconnection
483
+ * @throws {CloudInteropAPIError} - If an error occurs during disconnection
492
484
  */
493
485
  async disconnect() {
494
486
  await this.#disconnect(true);
@@ -496,9 +488,9 @@ class CloudInteropAPI {
496
488
  /**
497
489
  * Publishes a new context for the given context group to the other connected sessions
498
490
  *
499
- * @param contextGroup - The context group to publish to
500
- * @param context - The context to publish
501
- * @returns Promise that resolves when context is published
491
+ * @param {string} contextGroup - The context group to publish to
492
+ * @param {object} context - The context to publish
493
+ * @returns {*} {Promise<void>}
502
494
  * @memberof CloudInteropAPI
503
495
  */
504
496
  async setContext(contextGroup, context) {
@@ -525,9 +517,9 @@ class CloudInteropAPI {
525
517
  /**
526
518
  * Starts an intent discovery operation
527
519
  *
528
- * @returns Promise that resolves when intent discovery is started
520
+ * @returns {*} {Promise<void>}
529
521
  * @memberof CloudInteropAPI
530
- * @throws CloudInteropAPIError - If an error occurs during intent discovery
522
+ * @throws {CloudInteropAPIError} - If an error occurs during intent discovery
531
523
  */
532
524
  async startIntentDiscovery(options) {
533
525
  this.#throwIfNotConnected();
@@ -568,11 +560,6 @@ class CloudInteropAPI {
568
560
  if (!this.#connectionParams) {
569
561
  throw new Error('Connect parameters must be provided');
570
562
  }
571
- // Cancel session timer if it's running
572
- if (this.#sessionTimer) {
573
- clearTimeout(this.#sessionTimer);
574
- this.#sessionTimer = undefined;
575
- }
576
563
  const disconnectResponse = await fetch(`${this.#cloudInteropSettings.url}/api/sessions/${this.#sessionDetails.sessionId}`, {
577
564
  method: 'DELETE',
578
565
  headers: getRequestHeaders(this.#connectionParams),
@@ -671,88 +658,6 @@ class CloudInteropAPI {
671
658
  throw new Error('MQTT client not connected');
672
659
  }
673
660
  }
674
- /**
675
- * Extracts the expiration timestamp from a JWT token.
676
- *
677
- * @param token - The JWT token string
678
- * @returns The expiration timestamp in seconds, or null if extraction fails
679
- */
680
- #extractExpirationFromJwt(token) {
681
- try {
682
- // JWT tokens have three parts separated by dots: header.payload.signature
683
- // The exp claim is in the payload
684
- const parts = token.split('.');
685
- if (parts.length < 2) {
686
- this.#logger('warn', 'Invalid JWT token format: expected at least 2 parts');
687
- return null;
688
- }
689
- const payload = parts[1];
690
- // Decode base64url encoded payload
691
- const decodedBytes = buffer.Buffer.from(u(payload), 'base64');
692
- const payloadJson = decodedBytes.toString('utf8');
693
- // Parse JSON to get the exp claim
694
- const claims = JSON.parse(payloadJson);
695
- const exp = claims.exp;
696
- if (exp === undefined || exp === null) {
697
- this.#logger('warn', "JWT token does not contain 'exp' claim");
698
- return null;
699
- }
700
- if (typeof exp !== 'number') {
701
- this.#logger('warn', `JWT token 'exp' claim is not a number: ${exp}`);
702
- return null;
703
- }
704
- return exp;
705
- }
706
- catch (error) {
707
- this.#logger('error', `Failed to extract expiration from JWT token: ${error instanceof Error ? error.message : error}`);
708
- return null;
709
- }
710
- }
711
- /**
712
- * Start a session timer that will expire at the time specified in the JWT token's exp claim.
713
- * When the timer fires, it executes the same actions as the BadUserNamePasswordError case.
714
- */
715
- #startSessionTimer() {
716
- if (!this.#sessionDetails?.localSessionExpiryHandling) {
717
- return;
718
- }
719
- const token = this.#sessionDetails.token;
720
- if (!token) {
721
- this.#logger('warn', 'Cannot start session timer: token not available');
722
- return;
723
- }
724
- // Extract expiration time from JWT token
725
- const expTimestamp = this.#extractExpirationFromJwt(token);
726
- if (expTimestamp === null) {
727
- this.#logger('warn', 'Cannot start session timer: could not extract expiration from JWT token');
728
- return;
729
- }
730
- const currentTimeSeconds = Math.floor(Date.now() / 1000);
731
- const delaySeconds = expTimestamp - currentTimeSeconds;
732
- if (delaySeconds <= 0) {
733
- this.#logger('warn', 'JWT token has already expired or expires immediately');
734
- // Execute the same actions as BadUserNamePasswordError case
735
- this.#handleSessionExpiry();
736
- return;
737
- }
738
- // Clear any existing timer
739
- if (this.#sessionTimer) {
740
- clearTimeout(this.#sessionTimer);
741
- }
742
- const expirationTimeString = new Date(expTimestamp * 1000).toISOString();
743
- this.#logger('debug', `Starting session timer to expire in ${delaySeconds} seconds (at ${expirationTimeString})`);
744
- this.#sessionTimer = setTimeout(async () => {
745
- this.#handleSessionExpiry();
746
- }, delaySeconds * 1000);
747
- }
748
- /**
749
- * Handles session expiry by executing the same actions as the BadUserNamePasswordError case.
750
- */
751
- async #handleSessionExpiry() {
752
- await this.#disconnect(false);
753
- this.#logger('warn', 'Session expired');
754
- this.#events.emitEvent('session-expired');
755
- }
756
661
  }
757
662
 
758
663
  exports.AuthorizationError = AuthorizationError;
package/index.mjs CHANGED
@@ -1,10 +1,6 @@
1
1
  import { Buffer } from 'buffer';
2
- import 'fs';
3
- import 'path';
4
2
  import mqtt from 'mqtt';
5
3
 
6
- var u=n=>{let e=n.replaceAll("-","+").replaceAll("_","/");return e.padEnd(e.length+(4-e.length%4)%4,"=")};
7
-
8
4
  class CloudInteropAPIError extends Error {
9
5
  code;
10
6
  constructor(message = 'An unexpected error has occurred', code = 'UNEXPECTED_ERROR', cause) {
@@ -355,7 +351,6 @@ class CloudInteropAPI {
355
351
  #attemptingToReconnect = false;
356
352
  #events = new EventController();
357
353
  #intents;
358
- #sessionTimer;
359
354
  constructor(cloudInteropSettings) {
360
355
  this.#cloudInteropSettings = cloudInteropSettings;
361
356
  }
@@ -368,11 +363,11 @@ class CloudInteropAPI {
368
363
  /**
369
364
  * Connects and creates a session on the Cloud Interop service
370
365
  *
371
- * @param parameters - The parameters to use to connect
372
- * @returns Promise that resolves when connection is established
366
+ * @param {ConnectParameters} parameters - The parameters to use to connect
367
+ * @returns {*} {Promise<void>}
373
368
  * @memberof CloudInteropAPI
374
- * @throws CloudInteropAPIError - If an error occurs during connection
375
- * @throws AuthorizationError - If the connection is unauthorized
369
+ * @throws {CloudInteropAPIError} - If an error occurs during connection
370
+ * @throws {AuthorizationError} - If the connection is unauthorized
376
371
  */
377
372
  async connect(parameters) {
378
373
  this.#validateConnectParams(parameters);
@@ -396,11 +391,6 @@ class CloudInteropAPI {
396
391
  throw new CloudInteropAPIError(`Failed to connect to the Cloud Interop service: ${this.#cloudInteropSettings.url}`, 'ERR_CONNECT', new Error(createSessionResponse.statusText));
397
392
  }
398
393
  this.#sessionDetails = (await createSessionResponse.json());
399
- // If local session expiry handling is enabled, start the session timer
400
- if (this.#sessionDetails.localSessionExpiryHandling) {
401
- this.#logger('debug', `Local session expiry handling is enabled`);
402
- this.#startSessionTimer();
403
- }
404
394
  const sessionRootTopic = this.#sessionDetails.sessionRootTopic;
405
395
  const clientOptions = {
406
396
  keepalive: this.#keepAliveIntervalSeconds,
@@ -430,7 +420,9 @@ class CloudInteropAPI {
430
420
  if (error instanceof mqtt.ErrorWithReasonCode) {
431
421
  switch (error.code) {
432
422
  case BadUserNamePasswordError: {
433
- this.#handleSessionExpiry();
423
+ await this.#disconnect(false);
424
+ this.#logger('warn', `Session expired`);
425
+ this.#events.emitEvent('session-expired');
434
426
  return;
435
427
  }
436
428
  default: {
@@ -484,9 +476,9 @@ class CloudInteropAPI {
484
476
  /**
485
477
  * Disconnects from the Cloud Interop service
486
478
  *
487
- * @returns Promise that resolves when disconnected
479
+ * @returns {*} {Promise<void>}
488
480
  * @memberof CloudInteropAPI
489
- * @throws CloudInteropAPIError - If an error occurs during disconnection
481
+ * @throws {CloudInteropAPIError} - If an error occurs during disconnection
490
482
  */
491
483
  async disconnect() {
492
484
  await this.#disconnect(true);
@@ -494,9 +486,9 @@ class CloudInteropAPI {
494
486
  /**
495
487
  * Publishes a new context for the given context group to the other connected sessions
496
488
  *
497
- * @param contextGroup - The context group to publish to
498
- * @param context - The context to publish
499
- * @returns Promise that resolves when context is published
489
+ * @param {string} contextGroup - The context group to publish to
490
+ * @param {object} context - The context to publish
491
+ * @returns {*} {Promise<void>}
500
492
  * @memberof CloudInteropAPI
501
493
  */
502
494
  async setContext(contextGroup, context) {
@@ -523,9 +515,9 @@ class CloudInteropAPI {
523
515
  /**
524
516
  * Starts an intent discovery operation
525
517
  *
526
- * @returns Promise that resolves when intent discovery is started
518
+ * @returns {*} {Promise<void>}
527
519
  * @memberof CloudInteropAPI
528
- * @throws CloudInteropAPIError - If an error occurs during intent discovery
520
+ * @throws {CloudInteropAPIError} - If an error occurs during intent discovery
529
521
  */
530
522
  async startIntentDiscovery(options) {
531
523
  this.#throwIfNotConnected();
@@ -566,11 +558,6 @@ class CloudInteropAPI {
566
558
  if (!this.#connectionParams) {
567
559
  throw new Error('Connect parameters must be provided');
568
560
  }
569
- // Cancel session timer if it's running
570
- if (this.#sessionTimer) {
571
- clearTimeout(this.#sessionTimer);
572
- this.#sessionTimer = undefined;
573
- }
574
561
  const disconnectResponse = await fetch(`${this.#cloudInteropSettings.url}/api/sessions/${this.#sessionDetails.sessionId}`, {
575
562
  method: 'DELETE',
576
563
  headers: getRequestHeaders(this.#connectionParams),
@@ -669,88 +656,6 @@ class CloudInteropAPI {
669
656
  throw new Error('MQTT client not connected');
670
657
  }
671
658
  }
672
- /**
673
- * Extracts the expiration timestamp from a JWT token.
674
- *
675
- * @param token - The JWT token string
676
- * @returns The expiration timestamp in seconds, or null if extraction fails
677
- */
678
- #extractExpirationFromJwt(token) {
679
- try {
680
- // JWT tokens have three parts separated by dots: header.payload.signature
681
- // The exp claim is in the payload
682
- const parts = token.split('.');
683
- if (parts.length < 2) {
684
- this.#logger('warn', 'Invalid JWT token format: expected at least 2 parts');
685
- return null;
686
- }
687
- const payload = parts[1];
688
- // Decode base64url encoded payload
689
- const decodedBytes = Buffer.from(u(payload), 'base64');
690
- const payloadJson = decodedBytes.toString('utf8');
691
- // Parse JSON to get the exp claim
692
- const claims = JSON.parse(payloadJson);
693
- const exp = claims.exp;
694
- if (exp === undefined || exp === null) {
695
- this.#logger('warn', "JWT token does not contain 'exp' claim");
696
- return null;
697
- }
698
- if (typeof exp !== 'number') {
699
- this.#logger('warn', `JWT token 'exp' claim is not a number: ${exp}`);
700
- return null;
701
- }
702
- return exp;
703
- }
704
- catch (error) {
705
- this.#logger('error', `Failed to extract expiration from JWT token: ${error instanceof Error ? error.message : error}`);
706
- return null;
707
- }
708
- }
709
- /**
710
- * Start a session timer that will expire at the time specified in the JWT token's exp claim.
711
- * When the timer fires, it executes the same actions as the BadUserNamePasswordError case.
712
- */
713
- #startSessionTimer() {
714
- if (!this.#sessionDetails?.localSessionExpiryHandling) {
715
- return;
716
- }
717
- const token = this.#sessionDetails.token;
718
- if (!token) {
719
- this.#logger('warn', 'Cannot start session timer: token not available');
720
- return;
721
- }
722
- // Extract expiration time from JWT token
723
- const expTimestamp = this.#extractExpirationFromJwt(token);
724
- if (expTimestamp === null) {
725
- this.#logger('warn', 'Cannot start session timer: could not extract expiration from JWT token');
726
- return;
727
- }
728
- const currentTimeSeconds = Math.floor(Date.now() / 1000);
729
- const delaySeconds = expTimestamp - currentTimeSeconds;
730
- if (delaySeconds <= 0) {
731
- this.#logger('warn', 'JWT token has already expired or expires immediately');
732
- // Execute the same actions as BadUserNamePasswordError case
733
- this.#handleSessionExpiry();
734
- return;
735
- }
736
- // Clear any existing timer
737
- if (this.#sessionTimer) {
738
- clearTimeout(this.#sessionTimer);
739
- }
740
- const expirationTimeString = new Date(expTimestamp * 1000).toISOString();
741
- this.#logger('debug', `Starting session timer to expire in ${delaySeconds} seconds (at ${expirationTimeString})`);
742
- this.#sessionTimer = setTimeout(async () => {
743
- this.#handleSessionExpiry();
744
- }, delaySeconds * 1000);
745
- }
746
- /**
747
- * Handles session expiry by executing the same actions as the BadUserNamePasswordError case.
748
- */
749
- async #handleSessionExpiry() {
750
- await this.#disconnect(false);
751
- this.#logger('warn', 'Session expired');
752
- this.#events.emitEvent('session-expired');
753
- }
754
659
  }
755
660
 
756
661
  export { AuthorizationError, CloudInteropAPI, CloudInteropAPIError };
package/package.json CHANGED
@@ -1,15 +1,18 @@
1
1
  {
2
2
  "name": "@openfin/cloud-interop-core-api",
3
- "version": "0.0.1-alpha.1a0a938",
4
- "description": "",
3
+ "version": "0.0.1-alpha.1aa5f8a",
5
4
  "type": "module",
5
+ "description": "",
6
6
  "main": "./index.cjs",
7
7
  "browser": "./index.mjs",
8
8
  "types": "./bundle.d.ts",
9
- "author": "support@here.io",
9
+ "author": "",
10
10
  "license": "SEE LICENSE IN LICENSE.md",
11
11
  "dependencies": {
12
- "mqtt": "catalog:",
13
- "zod": "catalog:"
12
+ "mqtt": "^5.13.0",
13
+ "zod": "^3.24.4"
14
+ },
15
+ "optionalDependencies": {
16
+ "@rollup/rollup-linux-x64-gnu": "*"
14
17
  }
15
18
  }