whio-api-sdk 1.0.243-beta-staging → 1.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.
@@ -27,4 +27,5 @@ export declare class BaseClient {
27
27
  syncUserState(user: User | null, accessToken: string | null, refreshToken: string | null): Promise<void>;
28
28
  getAccessToken(): string | null;
29
29
  getRefreshToken(): string | null;
30
+ getValidToken(): Promise<string | null>;
30
31
  }
@@ -70,25 +70,22 @@ export class BaseClient {
70
70
  }
71
71
  request(endpoint, method = 'GET', body, headers = {}, noToken = false) {
72
72
  return __awaiter(this, void 0, void 0, function* () {
73
- yield this.ensureInitialized();
74
73
  const url = `${this.baseUrl}${endpoint}`;
75
74
  const defaultHeaders = {
76
75
  'Content-Type': 'application/json',
77
76
  'ngrok-skip-browser-warning': 'true'
78
77
  };
79
- if (noToken) {
80
- defaultHeaders['Authorization'] = '';
81
- }
82
- else {
83
- yield this.getToken();
84
- }
85
- if (this.accessToken) {
86
- defaultHeaders['Authorization'] = `Bearer ${this.accessToken}`;
78
+ if (!noToken) {
79
+ const token = yield this.getValidToken();
80
+ if (token) {
81
+ defaultHeaders['Authorization'] = `Bearer ${token}`;
82
+ }
87
83
  }
88
84
  const response = yield fetch(url, {
89
85
  method,
90
86
  headers: Object.assign(Object.assign({}, defaultHeaders), headers),
91
87
  body: body ? JSON.stringify(body) : undefined,
88
+ signal: AbortSignal.timeout(5000),
92
89
  });
93
90
  if (!response.ok) {
94
91
  const errorData = yield response.json().catch(() => ({}));
@@ -99,14 +96,13 @@ export class BaseClient {
99
96
  }
100
97
  fileUploadRequest(endpoint, body, headers = {}, onProgress) {
101
98
  return __awaiter(this, void 0, void 0, function* () {
102
- yield this.ensureInitialized();
103
99
  const url = `${this.baseUrl}${endpoint}`;
104
100
  const defaultHeaders = {
105
101
  'ngrok-skip-browser-warning': 'true'
106
102
  };
107
- yield this.getToken();
108
- if (this.accessToken) {
109
- defaultHeaders['Authorization'] = `Bearer ${this.accessToken}`;
103
+ const token = yield this.getValidToken();
104
+ if (token) {
105
+ defaultHeaders['Authorization'] = `Bearer ${token}`;
110
106
  }
111
107
  return new Promise((resolve, reject) => {
112
108
  const xhr = new XMLHttpRequest();
@@ -156,14 +152,13 @@ export class BaseClient {
156
152
  }
157
153
  downloadRequest(endpoint) {
158
154
  return __awaiter(this, void 0, void 0, function* () {
159
- yield this.ensureInitialized();
160
155
  const url = `${this.baseUrl}${endpoint}`;
161
- yield this.getToken();
162
156
  const defaultHeaders = {
163
157
  'ngrok-skip-browser-warning': 'true'
164
158
  };
165
- if (this.accessToken) {
166
- defaultHeaders['Authorization'] = `Bearer ${this.accessToken}`;
159
+ const token = yield this.getValidToken();
160
+ if (token) {
161
+ defaultHeaders['Authorization'] = `Bearer ${token}`;
167
162
  }
168
163
  const response = yield fetch(url, {
169
164
  method: 'GET',
@@ -178,18 +173,18 @@ export class BaseClient {
178
173
  }
179
174
  textRequest(endpoint) {
180
175
  return __awaiter(this, void 0, void 0, function* () {
181
- yield this.ensureInitialized();
182
176
  const url = `${this.baseUrl}${endpoint}`;
183
- yield this.getToken();
184
177
  const defaultHeaders = {
185
178
  'ngrok-skip-browser-warning': 'true'
186
179
  };
187
- if (this.accessToken) {
188
- defaultHeaders['Authorization'] = `Bearer ${this.accessToken}`;
180
+ const token = yield this.getValidToken();
181
+ if (token) {
182
+ defaultHeaders['Authorization'] = `Bearer ${token}`;
189
183
  }
190
184
  const response = yield fetch(url, {
191
185
  method: 'GET',
192
186
  headers: defaultHeaders,
187
+ signal: AbortSignal.timeout(5000),
193
188
  });
194
189
  if (!response.ok) {
195
190
  const errorData = yield response.json().catch(() => ({}));
@@ -242,7 +237,7 @@ export class BaseClient {
242
237
  });
243
238
  }
244
239
  isAuthenticated() {
245
- return !!this.accessToken && !!this.user;
240
+ return !!this.accessToken && !!this.user && !this.isTokenExpired(this.accessToken);
246
241
  }
247
242
  getCurrentUser() {
248
243
  return this.user;
@@ -273,4 +268,31 @@ export class BaseClient {
273
268
  getRefreshToken() {
274
269
  return this.refreshToken;
275
270
  }
271
+ getValidToken() {
272
+ return __awaiter(this, void 0, void 0, function* () {
273
+ if (!this.storage) {
274
+ return null;
275
+ }
276
+ const storedAccessToken = yield this.storage.getItem('access_token');
277
+ this.accessToken = storedAccessToken ? JSON.parse(storedAccessToken) : null;
278
+ if (!this.accessToken) {
279
+ return null;
280
+ }
281
+ if (!this.isTokenExpired(this.accessToken)) {
282
+ return this.accessToken;
283
+ }
284
+ const storedRefreshToken = yield this.storage.getItem('refresh_token');
285
+ this.refreshToken = storedRefreshToken ? JSON.parse(storedRefreshToken) : null;
286
+ if (!this.refreshToken) {
287
+ return null;
288
+ }
289
+ try {
290
+ yield this.refreshAccessToken();
291
+ return this.accessToken;
292
+ }
293
+ catch (error) {
294
+ return null;
295
+ }
296
+ });
297
+ }
276
298
  }
@@ -37,7 +37,7 @@ export declare class ApiSDK extends BaseClient {
37
37
  readonly logs: LogModule;
38
38
  readonly debug: DebugModule;
39
39
  readonly externalIntegrations: ExternalIntegrationModule;
40
- readonly websocket: WebSocketModule;
40
+ readonly websocket: WebSocketModule | null;
41
41
  readonly reports: ReportsModule;
42
42
  readonly patients: PatientModule;
43
43
  readonly dataStrategies: DataStrategyModule;
@@ -212,6 +212,7 @@ export declare class ApiSDK extends BaseClient {
212
212
  getExternalIntegration(...args: Parameters<ExternalIntegrationModule['getExternalIntegration']>): Promise<import("./types").ExternalIntegration>;
213
213
  updateExternalIntegration(...args: Parameters<ExternalIntegrationModule['updateExternalIntegration']>): Promise<import("./types").ExternalIntegration>;
214
214
  deleteExternalIntegration(...args: Parameters<ExternalIntegrationModule['deleteExternalIntegration']>): Promise<void>;
215
+ private assertWebSocket;
215
216
  connectWebSocket(): Promise<void>;
216
217
  disconnectWebSocket(): void;
217
218
  isWebSocketConnected(): boolean;
@@ -49,7 +49,7 @@ export class ApiSDK extends BaseClient {
49
49
  this.logs = new LogModule(config);
50
50
  this.debug = new DebugModule(config);
51
51
  this.externalIntegrations = new ExternalIntegrationModule(config);
52
- this.websocket = new WebSocketModule(config);
52
+ this.websocket = config.skipWebsocket ? null : new WebSocketModule(config);
53
53
  this.reports = new ReportsModule(config);
54
54
  this.patients = new PatientModule(config);
55
55
  this.dataStrategies = new DataStrategyModule(config);
@@ -59,7 +59,8 @@ export class ApiSDK extends BaseClient {
59
59
  this.auth, this.users, this.organizations, this.teams, this.templates,
60
60
  this.transcriptionSummaries, this.sessions, this.agents, this.audio,
61
61
  this.workflows, this.integrationActions, this.logs, this.debug, this.externalIntegrations,
62
- this.websocket, this.reports, this.patients, this.dataStrategies, this.systemSnapshots
62
+ this.reports, this.patients, this.dataStrategies, this.systemSnapshots,
63
+ ...(this.websocket ? [this.websocket] : [])
63
64
  ];
64
65
  // Auto-initialize the SDK
65
66
  this.initialize().catch(error => {
@@ -872,35 +873,42 @@ export class ApiSDK extends BaseClient {
872
873
  });
873
874
  }
874
875
  // WebSocket methods
876
+ assertWebSocket() {
877
+ if (!this.websocket) {
878
+ throw new Error('WebSocket module is not available. SDK was initialized with skipWebsocket: true');
879
+ }
880
+ return this.websocket;
881
+ }
875
882
  connectWebSocket() {
876
- return this.websocket.connect();
883
+ return this.assertWebSocket().connect();
877
884
  }
878
885
  disconnectWebSocket() {
879
- return this.websocket.disconnect();
886
+ return this.assertWebSocket().disconnect();
880
887
  }
881
888
  isWebSocketConnected() {
882
- return this.websocket.isConnected();
889
+ var _a, _b;
890
+ return (_b = (_a = this.websocket) === null || _a === void 0 ? void 0 : _a.isConnected()) !== null && _b !== void 0 ? _b : false;
883
891
  }
884
892
  streamAudioChunk(...args) {
885
- return this.websocket.streamAudioChunk(...args);
893
+ return this.assertWebSocket().streamAudioChunk(...args);
886
894
  }
887
895
  streamAudioChunks(...args) {
888
- return this.websocket.streamAudioChunks(...args);
896
+ return this.assertWebSocket().streamAudioChunks(...args);
889
897
  }
890
898
  onWebSocketEvent(...args) {
891
- return this.websocket.on(...args);
899
+ return this.assertWebSocket().on(...args);
892
900
  }
893
901
  offWebSocketEvent(...args) {
894
- return this.websocket.off(...args);
902
+ return this.assertWebSocket().off(...args);
895
903
  }
896
904
  getWebSocketStats() {
897
- return this.websocket.getConnectionStats();
905
+ return this.assertWebSocket().getConnectionStats();
898
906
  }
899
907
  subscribe(...args) {
900
- return this.websocket.on(...args);
908
+ return this.assertWebSocket().on(...args);
901
909
  }
902
910
  unsubscribe(...args) {
903
- return this.websocket.off(...args);
911
+ return this.assertWebSocket().off(...args);
904
912
  }
905
913
  // Reports methods
906
914
  getCompanyDailyReportCsv(...args) {
@@ -7,6 +7,7 @@ export interface SDKConfig {
7
7
  removeItem: (key: string) => void | Promise<void>;
8
8
  };
9
9
  websocket?: WebSocketConfig;
10
+ skipWebsocket?: boolean;
10
11
  }
11
12
  export interface Role {
12
13
  id: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whio-api-sdk",
3
- "version": "1.0.243-beta-staging",
3
+ "version": "1.1.2",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -69,28 +69,24 @@ export class BaseClient {
69
69
  headers: Record<string, string> = {},
70
70
  noToken: boolean = false,
71
71
  ): Promise<T> {
72
- await this.ensureInitialized();
73
-
74
72
  const url = `${this.baseUrl}${endpoint}`;
75
73
  const defaultHeaders: Record<string, string> = {
76
74
  'Content-Type': 'application/json',
77
75
  'ngrok-skip-browser-warning': 'true'
78
76
  };
79
77
 
80
- if (noToken) {
81
- defaultHeaders['Authorization'] = '';
82
- } else {
83
- await this.getToken();
84
- }
85
-
86
- if (this.accessToken) {
87
- defaultHeaders['Authorization'] = `Bearer ${this.accessToken}`;
78
+ if (!noToken) {
79
+ const token = await this.getValidToken();
80
+ if (token) {
81
+ defaultHeaders['Authorization'] = `Bearer ${token}`;
82
+ }
88
83
  }
89
84
 
90
85
  const response = await fetch(url, {
91
86
  method,
92
87
  headers: { ...defaultHeaders, ...headers },
93
88
  body: body ? JSON.stringify(body) : undefined,
89
+ signal: AbortSignal.timeout(5000),
94
90
  });
95
91
 
96
92
  if (!response.ok) {
@@ -109,17 +105,14 @@ export class BaseClient {
109
105
  headers: Record<string, string> = {},
110
106
  onProgress?: (percentage: number) => void
111
107
  ): Promise<T> {
112
- await this.ensureInitialized();
113
-
114
108
  const url = `${this.baseUrl}${endpoint}`;
115
109
  const defaultHeaders: Record<string, string> = {
116
110
  'ngrok-skip-browser-warning': 'true'
117
111
  };
118
112
 
119
- await this.getToken();
120
-
121
- if (this.accessToken) {
122
- defaultHeaders['Authorization'] = `Bearer ${this.accessToken}`;
113
+ const token = await this.getValidToken();
114
+ if (token) {
115
+ defaultHeaders['Authorization'] = `Bearer ${token}`;
123
116
  }
124
117
 
125
118
  return new Promise((resolve, reject) => {
@@ -172,18 +165,15 @@ export class BaseClient {
172
165
  }
173
166
 
174
167
  protected async downloadRequest(endpoint: string): Promise<Blob> {
175
- await this.ensureInitialized();
176
-
177
168
  const url = `${this.baseUrl}${endpoint}`;
178
169
 
179
- await this.getToken();
180
-
181
170
  const defaultHeaders: Record<string, string> = {
182
171
  'ngrok-skip-browser-warning': 'true'
183
172
  };
184
173
 
185
- if (this.accessToken) {
186
- defaultHeaders['Authorization'] = `Bearer ${this.accessToken}`;
174
+ const token = await this.getValidToken();
175
+ if (token) {
176
+ defaultHeaders['Authorization'] = `Bearer ${token}`;
187
177
  }
188
178
 
189
179
  const response = await fetch(url, {
@@ -202,23 +192,21 @@ export class BaseClient {
202
192
  }
203
193
 
204
194
  protected async textRequest(endpoint: string): Promise<string> {
205
- await this.ensureInitialized();
206
-
207
195
  const url = `${this.baseUrl}${endpoint}`;
208
196
 
209
- await this.getToken();
210
-
211
197
  const defaultHeaders: Record<string, string> = {
212
198
  'ngrok-skip-browser-warning': 'true'
213
199
  };
214
200
 
215
- if (this.accessToken) {
216
- defaultHeaders['Authorization'] = `Bearer ${this.accessToken}`;
201
+ const token = await this.getValidToken();
202
+ if (token) {
203
+ defaultHeaders['Authorization'] = `Bearer ${token}`;
217
204
  }
218
205
 
219
206
  const response = await fetch(url, {
220
207
  method: 'GET',
221
208
  headers: defaultHeaders,
209
+ signal: AbortSignal.timeout(5000),
222
210
  });
223
211
 
224
212
  if (!response.ok) {
@@ -282,7 +270,7 @@ export class BaseClient {
282
270
  }
283
271
 
284
272
  public isAuthenticated(): boolean {
285
- return !!this.accessToken && !!this.user;
273
+ return !!this.accessToken && !!this.user && !this.isTokenExpired(this.accessToken);
286
274
  }
287
275
 
288
276
  public getCurrentUser(): User | null {
@@ -316,4 +304,35 @@ export class BaseClient {
316
304
  return this.refreshToken;
317
305
  }
318
306
 
307
+ public async getValidToken(): Promise<string | null> {
308
+ if (!this.storage) {
309
+ return null;
310
+ }
311
+
312
+ const storedAccessToken = await this.storage.getItem('access_token');
313
+ this.accessToken = storedAccessToken ? JSON.parse(storedAccessToken) : null;
314
+
315
+ if (!this.accessToken) {
316
+ return null;
317
+ }
318
+
319
+ if (!this.isTokenExpired(this.accessToken)) {
320
+ return this.accessToken;
321
+ }
322
+
323
+ const storedRefreshToken = await this.storage.getItem('refresh_token');
324
+ this.refreshToken = storedRefreshToken ? JSON.parse(storedRefreshToken) : null;
325
+
326
+ if (!this.refreshToken) {
327
+ return null;
328
+ }
329
+
330
+ try {
331
+ await this.refreshAccessToken();
332
+ return this.accessToken;
333
+ } catch (error) {
334
+ return null;
335
+ }
336
+ }
337
+
319
338
  }
package/src/sdk/sdk.ts CHANGED
@@ -39,7 +39,7 @@ export class ApiSDK extends BaseClient {
39
39
  public readonly logs: LogModule;
40
40
  public readonly debug: DebugModule;
41
41
  public readonly externalIntegrations: ExternalIntegrationModule;
42
- public readonly websocket: WebSocketModule;
42
+ public readonly websocket: WebSocketModule | null;
43
43
  public readonly reports: ReportsModule;
44
44
  public readonly patients: PatientModule;
45
45
  public readonly dataStrategies: DataStrategyModule;
@@ -66,7 +66,7 @@ export class ApiSDK extends BaseClient {
66
66
  this.logs = new LogModule(config);
67
67
  this.debug = new DebugModule(config);
68
68
  this.externalIntegrations = new ExternalIntegrationModule(config);
69
- this.websocket = new WebSocketModule(config);
69
+ this.websocket = config.skipWebsocket ? null : new WebSocketModule(config);
70
70
  this.reports = new ReportsModule(config);
71
71
  this.patients = new PatientModule(config);
72
72
  this.dataStrategies = new DataStrategyModule(config);
@@ -77,7 +77,8 @@ export class ApiSDK extends BaseClient {
77
77
  this.auth, this.users, this.organizations, this.teams, this.templates,
78
78
  this.transcriptionSummaries, this.sessions, this.agents, this.audio,
79
79
  this.workflows, this.integrationActions, this.logs, this.debug, this.externalIntegrations,
80
- this.websocket, this.reports, this.patients, this.dataStrategies, this.systemSnapshots
80
+ this.reports, this.patients, this.dataStrategies, this.systemSnapshots,
81
+ ...(this.websocket ? [this.websocket] : [])
81
82
  ];
82
83
 
83
84
  // Auto-initialize the SDK
@@ -751,44 +752,51 @@ export class ApiSDK extends BaseClient {
751
752
  }
752
753
 
753
754
  // WebSocket methods
755
+ private assertWebSocket(): WebSocketModule {
756
+ if (!this.websocket) {
757
+ throw new Error('WebSocket module is not available. SDK was initialized with skipWebsocket: true');
758
+ }
759
+ return this.websocket;
760
+ }
761
+
754
762
  public connectWebSocket() {
755
- return this.websocket.connect();
763
+ return this.assertWebSocket().connect();
756
764
  }
757
765
 
758
766
  public disconnectWebSocket() {
759
- return this.websocket.disconnect();
767
+ return this.assertWebSocket().disconnect();
760
768
  }
761
769
 
762
770
  public isWebSocketConnected() {
763
- return this.websocket.isConnected();
771
+ return this.websocket?.isConnected() ?? false;
764
772
  }
765
773
 
766
774
  public streamAudioChunk(...args: Parameters<WebSocketModule['streamAudioChunk']>) {
767
- return this.websocket.streamAudioChunk(...args);
775
+ return this.assertWebSocket().streamAudioChunk(...args);
768
776
  }
769
777
 
770
778
  public streamAudioChunks(...args: Parameters<WebSocketModule['streamAudioChunks']>) {
771
- return this.websocket.streamAudioChunks(...args);
779
+ return this.assertWebSocket().streamAudioChunks(...args);
772
780
  }
773
781
 
774
782
  public onWebSocketEvent(...args: Parameters<WebSocketModule['on']>) {
775
- return this.websocket.on(...args);
783
+ return this.assertWebSocket().on(...args);
776
784
  }
777
785
 
778
786
  public offWebSocketEvent(...args: Parameters<WebSocketModule['off']>) {
779
- return this.websocket.off(...args);
787
+ return this.assertWebSocket().off(...args);
780
788
  }
781
789
 
782
790
  public getWebSocketStats() {
783
- return this.websocket.getConnectionStats();
791
+ return this.assertWebSocket().getConnectionStats();
784
792
  }
785
793
 
786
794
  public subscribe(...args: Parameters<WebSocketModule['on']>) {
787
- return this.websocket.on(...args);
795
+ return this.assertWebSocket().on(...args);
788
796
  }
789
797
 
790
798
  public unsubscribe(...args: Parameters<WebSocketModule['off']>) {
791
- return this.websocket.off(...args);
799
+ return this.assertWebSocket().off(...args);
792
800
  }
793
801
 
794
802
  // Reports methods
@@ -9,6 +9,7 @@ export interface SDKConfig {
9
9
  removeItem: (key: string) => void | Promise<void>;
10
10
  };
11
11
  websocket?: WebSocketConfig;
12
+ skipWebsocket?: boolean;
12
13
  }
13
14
 
14
15
  // Role type