@openfin/cloud-interop-core-api 0.0.1-alpha.6d7b62b → 0.0.1-alpha.6d9e190

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.
@@ -1,6 +1,10 @@
1
1
  import { Buffer } from 'buffer';
2
+ import 'fs';
3
+ import 'path';
2
4
  import mqtt from 'mqtt';
3
5
 
6
+ var u=n=>{let e=n.replaceAll("-","+").replaceAll("_","/");return e.padEnd(e.length+(4-e.length%4)%4,"=")};
7
+
4
8
  class CloudInteropAPIError extends Error {
5
9
  code;
6
10
  constructor(message = 'An unexpected error has occurred', code = 'UNEXPECTED_ERROR', cause) {
@@ -44,6 +48,8 @@ class EventController {
44
48
  }
45
49
  }
46
50
 
51
+ const isErrorIntentResult = (result) => 'error' in result;
52
+
47
53
  const APP_ID_DELIM = '::';
48
54
  const getRequestHeaders = (connectionParameters) => {
49
55
  const headers = {};
@@ -70,13 +76,9 @@ const getRequestHeaders = (connectionParameters) => {
70
76
  * @param source
71
77
  * @returns
72
78
  */
73
- const encodeAppIntents = (appIntents, { sessionId, sourceId }) => appIntents.map((intent) => ({
79
+ const encodeAppIntents = (appIntents, source) => appIntents.map((intent) => ({
74
80
  ...intent,
75
- apps: intent.apps.map((app) => {
76
- const id = encodeURIComponent(app.appId);
77
- const sId = encodeURIComponent(sourceId);
78
- return { ...app, appId: `${id}${APP_ID_DELIM}${sId}${APP_ID_DELIM}${sessionId}` };
79
- }),
81
+ apps: intent.apps.map((app) => ({ ...app, appId: encodeAppId(app.appId, source) })),
80
82
  }));
81
83
  /**
82
84
  * Decodes all app intents by URI decoding the parts previously encoded by `encodeAppIntents`
@@ -85,19 +87,35 @@ const encodeAppIntents = (appIntents, { sessionId, sourceId }) => appIntents.map
85
87
  */
86
88
  const decodeAppIntents = (appIntents) => appIntents.map((intent) => ({
87
89
  ...intent,
88
- apps: intent.apps.map((app) => {
89
- const [encodedAppId, encodedSourceId, sessionId] = app.appId.split(APP_ID_DELIM);
90
- const id = decodeURIComponent(encodedAppId);
91
- const sourceId = decodeURIComponent(encodedSourceId);
92
- return { ...app, appId: `${id}${APP_ID_DELIM}${sourceId}${APP_ID_DELIM}${sessionId}` };
93
- }),
90
+ apps: intent.apps.map((app) => ({ ...app, appId: decodeAppId(app.appId) })),
94
91
  }));
92
+ const encodeAppId = (appIdString, { sessionId, sourceId }) => {
93
+ const id = encodeURIComponent(appIdString);
94
+ const sId = encodeURIComponent(sourceId);
95
+ return `${id}${APP_ID_DELIM}${sId}${APP_ID_DELIM}${sessionId}`;
96
+ };
97
+ const decodeAppId = (appId) => {
98
+ const [encodedAppId, encodedSourceId, sessionId] = appId.split(APP_ID_DELIM);
99
+ const id = decodeURIComponent(encodedAppId);
100
+ const sourceId = decodeURIComponent(encodedSourceId);
101
+ return `${id}${APP_ID_DELIM}${sourceId}${APP_ID_DELIM}${sessionId}`;
102
+ };
95
103
  /**
96
- * Decodes the app id to extract the sessionId, returns '' if not able to parse
97
- * @param app
98
- * @returns
104
+ * Decodes the AppIdentifier to extract the appId, sourceId, and sessionId.
105
+ * @returns an object with:
106
+ * - appId: The appId, or the original appId if unable to parse.
107
+ * - sourceId: The sourceId, or an '' if unable to parse.
108
+ * - sessionId: The sessionId, or an '' if unable to parse.
99
109
  */
100
- const parseSessionId = (appId) => (typeof appId === 'string' ? appId : appId.appId).split(APP_ID_DELIM)?.[2]?.trim() ?? '';
110
+ const parseCloudAppId = (appId = '') => {
111
+ const originalAppString = typeof appId === 'string' ? appId : (appId.appId ?? '');
112
+ const parts = originalAppString.split(APP_ID_DELIM);
113
+ return {
114
+ appId: parts[0]?.trim() ?? originalAppString,
115
+ sourceId: parts[1]?.trim() ?? '',
116
+ sessionId: parts[2]?.trim() ?? '',
117
+ };
118
+ };
101
119
  const getSourceFromSession = (sessionDetails) => ({
102
120
  sessionId: sessionDetails.sessionId,
103
121
  sourceId: sessionDetails.sourceId,
@@ -146,13 +164,18 @@ class IntentController {
146
164
  body: JSON.stringify({ findOptions }),
147
165
  });
148
166
  if (!startResponse.ok) {
149
- throw new Error(startResponse.statusText);
167
+ throw new Error(`Error creating intent discovery record: ${startResponse.statusText}`);
150
168
  }
151
169
  // TODO: type this response?
152
170
  const json = await startResponse.json();
153
171
  this.#discovery.id = json.discoveryId;
154
172
  this.#discovery.sessionCount = json.sessionCount;
155
173
  this.#discovery.state = 'in-progress';
174
+ if (this.#discovery.sessionCount === 1) {
175
+ // since we have no other connected sessions, we can end discovery immediately
176
+ await this.#endIntentDiscovery(false);
177
+ return;
178
+ }
156
179
  // Listen out for discovery results directly sent to us
157
180
  await this.#mqttClient.subscribeAsync(`${this.#sessionDetails.sessionRootTopic}/commands/${this.#discovery.id}`);
158
181
  this.#discoveryTimeout = setTimeout(() => this.#endIntentDiscovery(), clampedTimeout);
@@ -163,10 +186,8 @@ class IntentController {
163
186
  throw new CloudInteropAPIError('Error starting intent discovery', 'ERR_STARTING_INTENT_DISCOVERY', error);
164
187
  }
165
188
  }
166
- async #endIntentDiscovery() {
189
+ async #endIntentDiscovery(mqttUnsubscribe = true) {
167
190
  if (this.#discovery.state !== 'in-progress') {
168
- // TODO: remove debug logs
169
- this.#logger('debug', 'Intent discovery not in progress');
170
191
  return;
171
192
  }
172
193
  if (this.#discoveryTimeout) {
@@ -176,10 +197,12 @@ class IntentController {
176
197
  this.#discovery.state = 'ended';
177
198
  // emit our aggregated events
178
199
  this.#events.emitEvent('aggregate-intent-details', { responses: this.#discovery.pendingIntentDetailsEvents });
179
- // gracefully end discovery
180
- await this.#mqttClient.unsubscribeAsync(`${this.#sessionDetails.sessionRootTopic}/commands/${this.#discovery.id}`).catch(() => {
181
- this.#logger('warn', `Error ending intent discovery: could not unsubscribe from discovery id ${this.#discovery.id}`);
182
- });
200
+ if (mqttUnsubscribe) {
201
+ // gracefully end discovery
202
+ await this.#mqttClient.unsubscribeAsync(`${this.#sessionDetails.sessionRootTopic}/commands/${this.#discovery.id}`).catch(() => {
203
+ this.#logger('warn', `Error ending intent discovery: could not unsubscribe from discovery id ${this.#discovery.id}`);
204
+ });
205
+ }
183
206
  await fetch(`${this.#url}/api/intents/${this.#sessionDetails.sessionId}/${this.#discovery.id}`, {
184
207
  method: 'DELETE',
185
208
  headers: getRequestHeaders(this.#connectionParams),
@@ -188,7 +211,6 @@ class IntentController {
188
211
  if (!deleteResponse.ok) {
189
212
  throw new Error(`Error ending intent discovery: ${deleteResponse.statusText}`);
190
213
  }
191
- this.#logger('debug', 'Intent discovery ended');
192
214
  })
193
215
  .catch((error) => {
194
216
  this.#logger('warn', `Error ending intent discovery: ${error}`);
@@ -197,7 +219,7 @@ class IntentController {
197
219
  this.#discovery = newDiscovery();
198
220
  }
199
221
  async raiseIntent({ raiseOptions, appId }) {
200
- const targetSessionId = parseSessionId(appId);
222
+ const targetSessionId = parseCloudAppId(appId).sessionId;
201
223
  if (!targetSessionId) {
202
224
  // TODO: should we add more info here about the format?
203
225
  throw new CloudInteropAPIError(`Invalid AppId specified, must be encoded as a cloud-session app id`, 'ERR_INVALID_TARGET_SESSION_ID');
@@ -232,6 +254,13 @@ class IntentController {
232
254
  return false;
233
255
  }
234
256
  async sendIntentResult(initiatingSessionId, result) {
257
+ if (!isErrorIntentResult(result)) {
258
+ // cloud-encode the source app id to support chained intent actions over cloud
259
+ // https://fdc3.finos.org/docs/2.0/api/spec#resolution-object -> "Use metadata about the resolving app instance to target a further intent"
260
+ const source = getSourceFromSession(this.#sessionDetails);
261
+ const encoded = encodeAppId(typeof result.source === 'string' ? result.source : result.source.appId, source);
262
+ result.source = typeof result.source === 'string' ? encoded : { ...result.source, appId: encoded };
263
+ }
235
264
  const { sessionId } = getSourceFromSession(this.#sessionDetails);
236
265
  const resultResponse = await fetch(`${this.#url}/api/intents/${initiatingSessionId}/result/${sessionId}`, {
237
266
  method: 'POST',
@@ -309,9 +338,8 @@ const BadUserNamePasswordError = 134;
309
338
  /**
310
339
  * Represents a single connection to a Cloud Interop service
311
340
  *
312
- * @export
313
- * @class CloudInteropAPI
314
- * @implements {Client}
341
+ * @public
342
+ * @class
315
343
  */
316
344
  class CloudInteropAPI {
317
345
  #cloudInteropSettings;
@@ -327,6 +355,7 @@ class CloudInteropAPI {
327
355
  #attemptingToReconnect = false;
328
356
  #events = new EventController();
329
357
  #intents;
358
+ #sessionTimer;
330
359
  constructor(cloudInteropSettings) {
331
360
  this.#cloudInteropSettings = cloudInteropSettings;
332
361
  }
@@ -339,11 +368,11 @@ class CloudInteropAPI {
339
368
  /**
340
369
  * Connects and creates a session on the Cloud Interop service
341
370
  *
342
- * @param {ConnectParameters} parameters - The parameters to use to connect
343
- * @return {*} {Promise<void>}
371
+ * @param parameters - The parameters to use to connect
372
+ * @returns Promise that resolves when connection is established
344
373
  * @memberof CloudInteropAPI
345
- * @throws {CloudInteropAPIError} - If an error occurs during connection
346
- * @throws {AuthorizationError} - If the connection is unauthorized
374
+ * @throws CloudInteropAPIError - If an error occurs during connection
375
+ * @throws AuthorizationError - If the connection is unauthorized
347
376
  */
348
377
  async connect(parameters) {
349
378
  this.#validateConnectParams(parameters);
@@ -367,6 +396,11 @@ class CloudInteropAPI {
367
396
  throw new CloudInteropAPIError(`Failed to connect to the Cloud Interop service: ${this.#cloudInteropSettings.url}`, 'ERR_CONNECT', new Error(createSessionResponse.statusText));
368
397
  }
369
398
  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
+ }
370
404
  const sessionRootTopic = this.#sessionDetails.sessionRootTopic;
371
405
  const clientOptions = {
372
406
  keepalive: this.#keepAliveIntervalSeconds,
@@ -396,9 +430,7 @@ class CloudInteropAPI {
396
430
  if (error instanceof mqtt.ErrorWithReasonCode) {
397
431
  switch (error.code) {
398
432
  case BadUserNamePasswordError: {
399
- await this.#disconnect(false);
400
- this.#logger('warn', `Session expired`);
401
- this.#events.emitEvent('session-expired');
433
+ this.#handleSessionExpiry();
402
434
  return;
403
435
  }
404
436
  default: {
@@ -452,9 +484,9 @@ class CloudInteropAPI {
452
484
  /**
453
485
  * Disconnects from the Cloud Interop service
454
486
  *
455
- * @return {*} {Promise<void>}
487
+ * @returns Promise that resolves when disconnected
456
488
  * @memberof CloudInteropAPI
457
- * @throws {CloudInteropAPIError} - If an error occurs during disconnection
489
+ * @throws CloudInteropAPIError - If an error occurs during disconnection
458
490
  */
459
491
  async disconnect() {
460
492
  await this.#disconnect(true);
@@ -462,9 +494,9 @@ class CloudInteropAPI {
462
494
  /**
463
495
  * Publishes a new context for the given context group to the other connected sessions
464
496
  *
465
- * @param {string} contextGroup - The context group to publish to
466
- * @param {object} context - The context to publish
467
- * @return {*} {Promise<void>}
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
468
500
  * @memberof CloudInteropAPI
469
501
  */
470
502
  async setContext(contextGroup, context) {
@@ -491,9 +523,9 @@ class CloudInteropAPI {
491
523
  /**
492
524
  * Starts an intent discovery operation
493
525
  *
494
- * @return {*} {Promise<void>}
526
+ * @returns Promise that resolves when intent discovery is started
495
527
  * @memberof CloudInteropAPI
496
- * @throws {CloudInteropAPIError} - If an error occurs during intent discovery
528
+ * @throws CloudInteropAPIError - If an error occurs during intent discovery
497
529
  */
498
530
  async startIntentDiscovery(options) {
499
531
  this.#throwIfNotConnected();
@@ -512,7 +544,10 @@ class CloudInteropAPI {
512
544
  return this.#intents?.sendIntentResult(initiatingSessionId, result);
513
545
  }
514
546
  parseSessionId(appId) {
515
- return parseSessionId(appId);
547
+ return parseCloudAppId(appId).sessionId;
548
+ }
549
+ parseAppId(appId) {
550
+ return parseCloudAppId(appId).appId;
516
551
  }
517
552
  addEventListener(type, callback) {
518
553
  this.#events.addEventListener(type, callback);
@@ -524,10 +559,18 @@ class CloudInteropAPI {
524
559
  this.#events.once(type, callback);
525
560
  }
526
561
  async #disconnect(fireDisconnectedEvent) {
527
- if (!this.#sessionDetails || !this.#connectionParams) {
562
+ if (!this.#sessionDetails) {
528
563
  return;
529
564
  }
530
565
  try {
566
+ if (!this.#connectionParams) {
567
+ throw new Error('Connect parameters must be provided');
568
+ }
569
+ // Cancel session timer if it's running
570
+ if (this.#sessionTimer) {
571
+ clearTimeout(this.#sessionTimer);
572
+ this.#sessionTimer = undefined;
573
+ }
531
574
  const disconnectResponse = await fetch(`${this.#cloudInteropSettings.url}/api/sessions/${this.#sessionDetails.sessionId}`, {
532
575
  method: 'DELETE',
533
576
  headers: getRequestHeaders(this.#connectionParams),
@@ -563,8 +606,13 @@ class CloudInteropAPI {
563
606
  if (contextEvent.source.sessionId === sessionDetails.sessionId) {
564
607
  return;
565
608
  }
566
- const { contextGroup, context, source, history } = contextEvent;
567
- this.#events.emitEvent('context', { contextGroup, context, source, history: { ...history, clientReceived: Date.now() } });
609
+ const { context, payload, contextGroup, channelName, source, history } = contextEvent;
610
+ this.#events.emitEvent('context', {
611
+ contextGroup: channelName || contextGroup,
612
+ context: payload || context,
613
+ source,
614
+ history: { ...history, clientReceived: Date.now() },
615
+ });
568
616
  }
569
617
  else if (topic.startsWith(`${sessionDetails.sessionRootTopic}/commands`)) {
570
618
  this.#handleCommandMessage(messageEnvelope);
@@ -621,6 +669,88 @@ class CloudInteropAPI {
621
669
  throw new Error('MQTT client not connected');
622
670
  }
623
671
  }
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
+ }
624
754
  }
625
755
 
626
756
  export { AuthorizationError, CloudInteropAPI, CloudInteropAPIError };
package/package.json CHANGED
@@ -1,241 +1,15 @@
1
1
  {
2
- "name": "@openfin/cloud-interop-core-api",
3
- "version": "0.0.1-alpha.6d7b62b",
4
- "type": "module",
5
- "description": "",
6
- "files": [
7
- "./dist/*"
8
- ],
9
- "main": "./dist/index.cjs",
10
- "browser": "./dist/index.mjs",
11
- "types": "./dist/bundle.d.ts",
12
- "scripts": {
13
- "build": "rimraf dist && tsx scripts/build.ts",
14
- "build:watch": "NODE_ENV=development npx nodemon --watch ./src -e .ts -x \"npm run build || exit 1\"",
15
- "typecheck": "tsc --noEmit",
16
- "test": "jest --coverage",
17
- "lint": "eslint . --max-warnings 0",
18
- "lint:fix": "eslint . --fix --max-warnings 0",
19
- "pack": "pushd dist && npm pack && popd"
20
- },
21
- "author": "",
22
- "license": "SEE LICENSE IN LICENSE.md",
23
- "devDependencies": {
24
- "@microsoft/api-extractor": "^7.49.1",
25
- "@rollup/plugin-commonjs": "^28.0.1",
26
- "@rollup/plugin-inject": "^5.0.5",
27
- "@rollup/plugin-node-resolve": "^15.2.3",
28
- "@rollup/plugin-typescript": "^11.1.6",
29
- "@types/jest": "^29.5.14",
30
- "@types/node": "^22.7.7",
31
- "@typescript-eslint/eslint-plugin": "^7.5.0",
32
- "@typescript-eslint/parser": "^7.15.0",
33
- "dotenv-defaults": "^5.0.2",
34
- "eslint": "^8.57.0",
35
- "eslint-config-prettier": "^9.1.0",
36
- "eslint-plugin-check-file": "^2.8.0",
37
- "eslint-plugin-prettier": "^5.2.1",
38
- "eslint-plugin-simple-import-sort": "^12.1.1",
39
- "eslint-plugin-unicorn": "^55.0.0",
40
- "eslint-plugin-unused-imports": "^4.1.4",
41
- "jest": "^29.7.0",
42
- "nodemon": "^3.1.9",
43
- "prettier": "^3.3.3",
44
- "rollup": "^4.30.1",
45
- "ts-jest": "^29.2.5",
46
- "tsx": "^4.19.2",
47
- "typescript": "^5.7.3"
48
- },
49
- "optionalDependencies": {
50
- "@rollup/rollup-linux-x64-gnu": "*"
51
- },
52
- "dependencies": {
53
- "@openfin/shared-utils": "file:../shared-utils",
54
- "mqtt": "^5.3.1",
55
- "zod": "^3.24.1"
56
- },
57
- "eslintConfig": {
58
- "env": {
59
- "browser": true,
60
- "node": true
61
- },
62
- "parser": "@typescript-eslint/parser",
63
- "parserOptions": {
64
- "ecmaVersion": "latest",
65
- "project": true,
66
- "sourceType": "module"
67
- },
68
- "extends": [
69
- "eslint:recommended",
70
- "plugin:@typescript-eslint/recommended",
71
- "plugin:@typescript-eslint/strict",
72
- "plugin:unicorn/recommended",
73
- "plugin:prettier/recommended"
74
- ],
75
- "plugins": [
76
- "prettier",
77
- "check-file",
78
- "simple-import-sort",
79
- "unused-imports"
80
- ],
81
- "rules": {
82
- "unused-imports/no-unused-imports": "warn",
83
- "unicorn/prevent-abbreviations": [
84
- "error",
85
- {
86
- "replacements": {
87
- "props": false,
88
- "prop": false,
89
- "ref": false,
90
- "args": false,
91
- "arg": false,
92
- "src": false,
93
- "dev": false,
94
- "str": false,
95
- "req": false,
96
- "res": false
97
- }
98
- }
99
- ],
100
- "@typescript-eslint/no-non-null-assertion": "error",
101
- "unicorn/no-nested-ternary": "off",
102
- "unicorn/no-array-for-each": "off",
103
- "unicorn/no-useless-undefined": "off",
104
- "unicorn/no-null": "off",
105
- "eqeqeq": [
106
- "error",
107
- "always"
108
- ],
109
- "no-alert": "error",
110
- "no-eval": "error",
111
- "prettier/prettier": "warn",
112
- "simple-import-sort/imports": [
113
- "error",
114
- {
115
- "groups": [
116
- [
117
- "^react$"
118
- ],
119
- [
120
- "^react"
121
- ],
122
- [
123
- "^next"
124
- ],
125
- [
126
- "^zod"
127
- ],
128
- [
129
- "^@radix-ui/"
130
- ],
131
- [
132
- "^[^.]"
133
- ],
134
- [
135
- "@/components/ui/.*"
136
- ],
137
- [
138
- "@/components/.*"
139
- ],
140
- [
141
- "@/config/.*"
142
- ],
143
- [
144
- "@/lib/.*"
145
- ],
146
- [
147
- "^\\.\\.(?!/?$)",
148
- "^\\.\\./?$"
149
- ],
150
- [
151
- "^\\./(?=.*/)(?!/?$)",
152
- "^\\.(?!/?$)",
153
- "^\\./?$"
154
- ],
155
- [
156
- "^.+\\.s?css$"
157
- ]
158
- ]
159
- }
160
- ],
161
- "check-file/no-index": "off",
162
- "check-file/filename-naming-convention": [
163
- "error",
164
- {
165
- "**/*.{jsx,tsx}": "KEBAB_CASE",
166
- "**/*.{js,ts}": "KEBAB_CASE"
167
- },
168
- {
169
- "ignoreMiddleExtensions": true
170
- }
171
- ],
172
- "check-file/filename-blocklist": [
173
- "error",
174
- {
175
- "**/*.spec.js": "*.test.js",
176
- "**/*.spec.jsx": "*.test.jsx",
177
- "**/*.spec.ts": "*.test.ts",
178
- "**/*.spec.tsx": "*.test.tsx"
179
- }
180
- ],
181
- "no-restricted-syntax": [
182
- "error",
183
- {
184
- "selector": "TSEnumDeclaration",
185
- "message": "Prefer string unions to enums."
186
- }
187
- ],
188
- "curly": [
189
- "error",
190
- "multi-line"
191
- ],
192
- "@typescript-eslint/consistent-type-definitions": [
193
- "error",
194
- "type"
195
- ],
196
- "@typescript-eslint/no-unused-vars": [
197
- "warn",
198
- {
199
- "argsIgnorePattern": "^_",
200
- "varsIgnorePattern": "^_"
201
- }
202
- ],
203
- "@typescript-eslint/no-explicit-any": "warn"
204
- },
205
- "ignorePatterns": [
206
- "node_modules",
207
- "out",
208
- "build",
209
- "scripts",
210
- "dist",
211
- "coverage",
212
- "tests",
213
- "rollup.config.mjs",
214
- "examples"
215
- ]
216
- },
217
- "jest": {
218
- "collectCoverage": true,
219
- "collectCoverageFrom": [
220
- "src/**/*.ts"
221
- ],
222
- "coverageReporters": [
223
- "lcov",
224
- "text-summary"
225
- ],
226
- "preset": "ts-jest",
227
- "restoreMocks": true,
228
- "setupFiles": [],
229
- "testMatch": [
230
- "**/tests/*.test.ts"
231
- ],
232
- "testTimeout": 100000
233
- },
234
- "prettier": {
235
- "printWidth": 160,
236
- "semi": true,
237
- "singleQuote": true,
238
- "tabWidth": 4,
239
- "trailingComma": "all"
240
- }
2
+ "name": "@openfin/cloud-interop-core-api",
3
+ "version": "0.0.1-alpha.6d9e190",
4
+ "description": "",
5
+ "type": "module",
6
+ "main": "./index.cjs",
7
+ "browser": "./index.mjs",
8
+ "types": "./bundle.d.ts",
9
+ "author": "support@here.io",
10
+ "license": "SEE LICENSE IN LICENSE.md",
11
+ "dependencies": {
12
+ "mqtt": "catalog:",
13
+ "zod": "catalog:"
14
+ }
241
15
  }
package/dist/LICENSE.md DELETED
@@ -1,4 +0,0 @@
1
- Learn more about OpenFin licensing at the links listed below or email us at support@openfin.co with questions.
2
-
3
- - [Developer agreement](https://openfin.co/developer-agreement)
4
-
package/dist/README.md DELETED
@@ -1,14 +0,0 @@
1
- # @openfin/cloud-interop-core-api
2
-
3
- This package contains the core interop library that handles all interactions with the Here™ Cloud Interop Service.
4
-
5
- It is callable via browser or node applications.
6
-
7
-
8
- ## Authentication
9
-
10
- The library supports authentication with the Here™ Cloud Interop Service using the following methods:
11
- - Basic Authentication
12
- - JWT Token Authentication
13
- - Default Authentication i.e. Interactive session based authentication using cookies
14
-