whio-api-sdk 1.0.225-beta-staging → 1.0.226-beta-staging

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.
@@ -10,4 +10,5 @@ export declare class AuthModule extends BaseClient {
10
10
  getProfile(): Promise<User>;
11
11
  changePassword(currentPassword: string, newPassword: string): Promise<PasswordChangeResponse>;
12
12
  adminChangePassword(userId: string, newPassword: string): Promise<PasswordChangeResponse>;
13
+ private updateAuthState;
13
14
  }
@@ -14,12 +14,7 @@ export class AuthModule extends BaseClient {
14
14
  return __awaiter(this, void 0, void 0, function* () {
15
15
  try {
16
16
  const response = yield this.request('/auth/login', 'POST', credentials, {}, true);
17
- this.accessToken = response.access_token;
18
- this.refreshToken = response.refresh_token;
19
- this.user = response.user;
20
- yield this.storage.setItem('access_token', JSON.stringify(response.access_token));
21
- yield this.storage.setItem('refresh_token', JSON.stringify(response.refresh_token));
22
- yield this.storage.setItem('user', JSON.stringify(response.user));
17
+ yield this.updateAuthState(response);
23
18
  return response;
24
19
  }
25
20
  catch (error) {
@@ -38,12 +33,7 @@ export class AuthModule extends BaseClient {
38
33
  try {
39
34
  const response = yield this.request('/auth/login-with-code', 'POST', { email, code }, {}, true);
40
35
  console.log(response);
41
- this.accessToken = response.access_token;
42
- this.refreshToken = response.refresh_token;
43
- this.user = response.user;
44
- yield this.storage.setItem('access_token', JSON.stringify(response.access_token));
45
- yield this.storage.setItem('refresh_token', JSON.stringify(response.refresh_token));
46
- yield this.storage.setItem('user', JSON.stringify(response.user));
36
+ yield this.updateAuthState(response);
47
37
  return response;
48
38
  }
49
39
  catch (error) {
@@ -80,4 +70,16 @@ export class AuthModule extends BaseClient {
80
70
  return this.request(urls.adminChangePassword, 'PATCH', dto);
81
71
  });
82
72
  }
73
+ updateAuthState(response) {
74
+ return __awaiter(this, void 0, void 0, function* () {
75
+ this.accessToken = response.access_token;
76
+ this.refreshToken = response.refresh_token;
77
+ this.user = response.user;
78
+ if (this.storage) {
79
+ yield this.storage.setItem('access_token', JSON.stringify(response.access_token));
80
+ yield this.storage.setItem('refresh_token', JSON.stringify(response.refresh_token));
81
+ yield this.storage.setItem('user', JSON.stringify(response.user));
82
+ }
83
+ });
84
+ }
83
85
  }
@@ -8,8 +8,9 @@ export declare class BaseClient {
8
8
  protected accessToken: string | null;
9
9
  protected refreshToken: string | null;
10
10
  protected user: User | null;
11
+ private isInitialized;
11
12
  constructor(config?: SDKConfig);
12
- protected initialize(): Promise<void>;
13
+ initialize(): Promise<void>;
13
14
  fetchConfig(url: string): Promise<void>;
14
15
  protected getToken(): Promise<void>;
15
16
  protected request<T>(endpoint: string, method?: string, body?: any, headers?: Record<string, string>, noToken?: boolean): Promise<T>;
@@ -21,6 +22,9 @@ export declare class BaseClient {
21
22
  protected refreshAccessToken(): Promise<void>;
22
23
  isAuthenticated(): boolean;
23
24
  getCurrentUser(): User | null;
25
+ protected ensureInitialized(): Promise<void>;
26
+ protected validateUser(): User;
27
+ syncUserState(user: User | null, accessToken: string | null, refreshToken: string | null): Promise<void>;
24
28
  getAccessToken(): string | null;
25
29
  getRefreshToken(): string | null;
26
30
  }
@@ -16,18 +16,29 @@ export class BaseClient {
16
16
  this.accessToken = null;
17
17
  this.refreshToken = null;
18
18
  this.user = null;
19
+ this.isInitialized = false;
19
20
  this.baseUrl = config.baseUrl || '/api';
20
21
  this.storage = config.storage;
21
- this.initialize();
22
+ // Don't call initialize() in constructor to avoid race conditions
22
23
  }
23
24
  initialize() {
24
25
  return __awaiter(this, void 0, void 0, function* () {
25
- const accessToken = yield this.storage.getItem('access_token');
26
- const refreshToken = yield this.storage.getItem('refresh_token');
27
- const userString = yield this.storage.getItem('user');
28
- this.user = userString ? JSON.parse(userString) : null;
29
- this.accessToken = accessToken ? JSON.parse(accessToken) : null;
30
- this.refreshToken = refreshToken ? JSON.parse(refreshToken) : null;
26
+ if (this.isInitialized || !this.storage) {
27
+ return;
28
+ }
29
+ try {
30
+ const accessToken = yield this.storage.getItem('access_token');
31
+ const refreshToken = yield this.storage.getItem('refresh_token');
32
+ const userString = yield this.storage.getItem('user');
33
+ this.user = userString ? JSON.parse(userString) : null;
34
+ this.accessToken = accessToken ? JSON.parse(accessToken) : null;
35
+ this.refreshToken = refreshToken ? JSON.parse(refreshToken) : null;
36
+ this.isInitialized = true;
37
+ }
38
+ catch (error) {
39
+ console.error('Failed to initialize BaseClient:', error);
40
+ this.isInitialized = true; // Mark as initialized even on error to prevent infinite loops
41
+ }
31
42
  });
32
43
  }
33
44
  fetchConfig(url) {
@@ -59,6 +70,7 @@ export class BaseClient {
59
70
  }
60
71
  request(endpoint, method = 'GET', body, headers = {}, noToken = false) {
61
72
  return __awaiter(this, void 0, void 0, function* () {
73
+ yield this.ensureInitialized();
62
74
  const url = `${this.baseUrl}${endpoint}`;
63
75
  const defaultHeaders = {
64
76
  'Content-Type': 'application/json',
@@ -87,6 +99,7 @@ export class BaseClient {
87
99
  }
88
100
  fileUploadRequest(endpoint, body, headers = {}, onProgress) {
89
101
  return __awaiter(this, void 0, void 0, function* () {
102
+ yield this.ensureInitialized();
90
103
  const url = `${this.baseUrl}${endpoint}`;
91
104
  const defaultHeaders = {
92
105
  'ngrok-skip-browser-warning': 'true'
@@ -143,6 +156,7 @@ export class BaseClient {
143
156
  }
144
157
  downloadRequest(endpoint) {
145
158
  return __awaiter(this, void 0, void 0, function* () {
159
+ yield this.ensureInitialized();
146
160
  const url = `${this.baseUrl}${endpoint}`;
147
161
  yield this.getToken();
148
162
  const defaultHeaders = {
@@ -164,6 +178,7 @@ export class BaseClient {
164
178
  }
165
179
  textRequest(endpoint) {
166
180
  return __awaiter(this, void 0, void 0, function* () {
181
+ yield this.ensureInitialized();
167
182
  const url = `${this.baseUrl}${endpoint}`;
168
183
  yield this.getToken();
169
184
  const defaultHeaders = {
@@ -214,9 +229,11 @@ export class BaseClient {
214
229
  this.accessToken = response.access_token;
215
230
  this.refreshToken = response.refresh_token;
216
231
  this.user = response.user;
217
- yield this.storage.setItem('access_token', JSON.stringify(response.access_token));
218
- yield this.storage.setItem('refresh_token', JSON.stringify(response.refresh_token));
219
- yield this.storage.setItem('user', JSON.stringify(response.user));
232
+ if (this.storage) {
233
+ yield this.storage.setItem('access_token', JSON.stringify(response.access_token));
234
+ yield this.storage.setItem('refresh_token', JSON.stringify(response.refresh_token));
235
+ yield this.storage.setItem('user', JSON.stringify(response.user));
236
+ }
220
237
  }
221
238
  catch (error) {
222
239
  yield this.clearAuth();
@@ -225,11 +242,31 @@ export class BaseClient {
225
242
  });
226
243
  }
227
244
  isAuthenticated() {
228
- return !!this.accessToken;
245
+ return !!this.accessToken && !!this.user;
229
246
  }
230
247
  getCurrentUser() {
231
248
  return this.user;
232
249
  }
250
+ ensureInitialized() {
251
+ return __awaiter(this, void 0, void 0, function* () {
252
+ if (!this.isInitialized) {
253
+ yield this.initialize();
254
+ }
255
+ });
256
+ }
257
+ validateUser() {
258
+ if (!this.user) {
259
+ throw new Error('User not authenticated. Please log in first.');
260
+ }
261
+ return this.user;
262
+ }
263
+ syncUserState(user, accessToken, refreshToken) {
264
+ return __awaiter(this, void 0, void 0, function* () {
265
+ this.user = user;
266
+ this.accessToken = accessToken;
267
+ this.refreshToken = refreshToken;
268
+ });
269
+ }
233
270
  getAccessToken() {
234
271
  return this.accessToken;
235
272
  }
@@ -15,9 +15,10 @@ export class TranscriptionSummaryModule extends BaseClient {
15
15
  // ======================
16
16
  generateTranscriptionSummary(templateId, sessionId) {
17
17
  return __awaiter(this, void 0, void 0, function* () {
18
+ const user = this.validateUser();
18
19
  const generateSummaryDto = {
19
20
  templateId,
20
- userId: this.user.id,
21
+ userId: user.id,
21
22
  fromUserTemplate: false,
22
23
  sessionId: sessionId,
23
24
  };
@@ -27,9 +28,10 @@ export class TranscriptionSummaryModule extends BaseClient {
27
28
  }
28
29
  generateTranscriptionSummaryFromUserTemplate(userTemplateId, sessionId) {
29
30
  return __awaiter(this, void 0, void 0, function* () {
31
+ const user = this.validateUser();
30
32
  const generateSummaryDto = {
31
33
  templateId: userTemplateId,
32
- userId: this.user.id,
34
+ userId: user.id,
33
35
  fromUserTemplate: true,
34
36
  sessionId: sessionId,
35
37
  };
@@ -1,4 +1,4 @@
1
- import { SDKConfig } from './types';
1
+ import { SDKConfig, User } from './types';
2
2
  import { BaseClient } from './modules/base-client';
3
3
  import { AuthModule } from './modules/auth.module';
4
4
  import { UserModule } from './modules/user.module';
@@ -36,27 +36,33 @@ export declare class ApiSDK extends BaseClient {
36
36
  readonly websocket: WebSocketModule;
37
37
  readonly reports: ReportsModule;
38
38
  readonly patients: PatientModule;
39
+ private modules;
40
+ private sdkInitialized;
39
41
  constructor(config?: SDKConfig);
42
+ initialize(): Promise<void>;
43
+ isReady(): boolean;
44
+ private syncUserStateAcrossModules;
45
+ syncUserState(user: User | null, accessToken: string | null, refreshToken: string | null): Promise<void>;
40
46
  login(...args: Parameters<AuthModule['login']>): Promise<import("./types").LoginResponse>;
41
47
  logout(...args: Parameters<AuthModule['logout']>): Promise<void>;
42
- getProfile(...args: Parameters<AuthModule['getProfile']>): Promise<import("./types").User>;
48
+ getProfile(...args: Parameters<AuthModule['getProfile']>): Promise<User>;
43
49
  changePassword(...args: Parameters<AuthModule['changePassword']>): Promise<import("./types").PasswordChangeResponse>;
44
50
  adminChangePassword(...args: Parameters<AuthModule['adminChangePassword']>): Promise<import("./types").PasswordChangeResponse>;
45
51
  requestLoginCode(...args: Parameters<AuthModule['requestLoginCode']>): Promise<{
46
52
  message: string;
47
53
  }>;
48
54
  loginWithCode(...args: Parameters<AuthModule['loginWithCode']>): Promise<import("./types").LoginResponse>;
49
- createUser(...args: Parameters<UserModule['createUser']>): Promise<import("./types").User>;
50
- assignEditorToRoleToUser(...args: Parameters<UserModule['assignEditorToRoleToUser']>): Promise<import("./types").User>;
51
- assignAdminToRoleToUser(...args: Parameters<UserModule['assignAdminToRoleToUser']>): Promise<import("./types").User>;
52
- assignDisabledToRoleToUser(...args: Parameters<UserModule['assignDisabledToRoleToUser']>): Promise<import("./types").User>;
53
- createEditorUser(...args: Parameters<UserModule['createEditorUser']>): Promise<import("./types").User>;
54
- createAdminUser(...args: Parameters<UserModule['createAdminUser']>): Promise<import("./types").User>;
55
- createDisabledUser(...args: Parameters<UserModule['createDisabledUser']>): Promise<import("./types").User>;
56
- getUsers(...args: Parameters<UserModule['getUsers']>): Promise<import("./types").User[]>;
57
- getUser(...args: Parameters<UserModule['getUser']>): Promise<import("./types").User>;
58
- getUsersByOrganization(...args: Parameters<UserModule['getUsersByOrganization']>): Promise<import("./types").User[]>;
59
- updateUser(...args: Parameters<UserModule['updateUser']>): Promise<import("./types").User>;
55
+ createUser(...args: Parameters<UserModule['createUser']>): Promise<User>;
56
+ assignEditorToRoleToUser(...args: Parameters<UserModule['assignEditorToRoleToUser']>): Promise<User>;
57
+ assignAdminToRoleToUser(...args: Parameters<UserModule['assignAdminToRoleToUser']>): Promise<User>;
58
+ assignDisabledToRoleToUser(...args: Parameters<UserModule['assignDisabledToRoleToUser']>): Promise<User>;
59
+ createEditorUser(...args: Parameters<UserModule['createEditorUser']>): Promise<User>;
60
+ createAdminUser(...args: Parameters<UserModule['createAdminUser']>): Promise<User>;
61
+ createDisabledUser(...args: Parameters<UserModule['createDisabledUser']>): Promise<User>;
62
+ getUsers(...args: Parameters<UserModule['getUsers']>): Promise<User[]>;
63
+ getUser(...args: Parameters<UserModule['getUser']>): Promise<User>;
64
+ getUsersByOrganization(...args: Parameters<UserModule['getUsersByOrganization']>): Promise<User[]>;
65
+ updateUser(...args: Parameters<UserModule['updateUser']>): Promise<User>;
60
66
  deleteUser(...args: Parameters<UserModule['deleteUser']>): Promise<void>;
61
67
  createOrganization(...args: Parameters<OrganizationModule['createOrganization']>): Promise<import("./types").Organization>;
62
68
  getOrganizations(...args: Parameters<OrganizationModule['getOrganizations']>): Promise<import("./types").Organization[]>;
@@ -30,6 +30,7 @@ import { PatientModule } from './modules/patient.module';
30
30
  export class ApiSDK extends BaseClient {
31
31
  constructor(config = {}) {
32
32
  super(config);
33
+ this.sdkInitialized = false;
33
34
  // Initialize all domain modules with the same config
34
35
  this.auth = new AuthModule(config);
35
36
  this.users = new UserModule(config);
@@ -47,6 +48,53 @@ export class ApiSDK extends BaseClient {
47
48
  this.websocket = new WebSocketModule(config);
48
49
  this.reports = new ReportsModule(config);
49
50
  this.patients = new PatientModule(config);
51
+ // Store all modules for batch operations
52
+ this.modules = [
53
+ this.auth, this.users, this.organizations, this.teams, this.templates,
54
+ this.transcriptionSummaries, this.sessions, this.agents, this.audio,
55
+ this.workflows, this.logs, this.debug, this.externalIntegrations,
56
+ this.websocket, this.reports, this.patients
57
+ ];
58
+ }
59
+ initialize() {
60
+ const _super = Object.create(null, {
61
+ initialize: { get: () => super.initialize }
62
+ });
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ if (this.sdkInitialized) {
65
+ return;
66
+ }
67
+ // Initialize the main SDK (base client)
68
+ yield _super.initialize.call(this);
69
+ // Initialize all modules and sync their state
70
+ yield Promise.all(this.modules.map(module => module.initialize()));
71
+ // Sync user state across all modules
72
+ yield this.syncUserStateAcrossModules();
73
+ this.sdkInitialized = true;
74
+ });
75
+ }
76
+ isReady() {
77
+ return this.sdkInitialized;
78
+ }
79
+ syncUserStateAcrossModules() {
80
+ return __awaiter(this, void 0, void 0, function* () {
81
+ const currentUser = this.getCurrentUser();
82
+ const accessToken = this.getAccessToken();
83
+ const refreshToken = this.getRefreshToken();
84
+ // Sync state to all modules
85
+ yield Promise.all(this.modules.map(module => module.syncUserState(currentUser, accessToken, refreshToken)));
86
+ });
87
+ }
88
+ syncUserState(user, accessToken, refreshToken) {
89
+ const _super = Object.create(null, {
90
+ syncUserState: { get: () => super.syncUserState }
91
+ });
92
+ return __awaiter(this, void 0, void 0, function* () {
93
+ // Update main SDK state
94
+ yield _super.syncUserState.call(this, user, accessToken, refreshToken);
95
+ // Sync to all modules
96
+ yield Promise.all(this.modules.map(module => module.syncUserState(user, accessToken, refreshToken)));
97
+ });
50
98
  }
51
99
  // ======================
52
100
  // BACKWARD COMPATIBILITY LAYER
@@ -55,12 +103,18 @@ export class ApiSDK extends BaseClient {
55
103
  // Auth methods
56
104
  login(...args) {
57
105
  return __awaiter(this, void 0, void 0, function* () {
58
- return this.auth.login(...args);
106
+ const result = yield this.auth.login(...args);
107
+ // Sync user state across all modules after successful login
108
+ yield this.syncUserStateAcrossModules();
109
+ return result;
59
110
  });
60
111
  }
61
112
  logout(...args) {
62
113
  return __awaiter(this, void 0, void 0, function* () {
63
- return this.auth.logout(...args);
114
+ const result = yield this.auth.logout(...args);
115
+ // Sync cleared state across all modules after logout
116
+ yield this.syncUserStateAcrossModules();
117
+ return result;
64
118
  });
65
119
  }
66
120
  getProfile(...args) {
@@ -85,7 +139,10 @@ export class ApiSDK extends BaseClient {
85
139
  }
86
140
  loginWithCode(...args) {
87
141
  return __awaiter(this, void 0, void 0, function* () {
88
- return this.auth.loginWithCode(...args);
142
+ const result = yield this.auth.loginWithCode(...args);
143
+ // Sync user state across all modules after successful login
144
+ yield this.syncUserStateAcrossModules();
145
+ return result;
89
146
  });
90
147
  }
91
148
  // User methods
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whio-api-sdk",
3
- "version": "1.0.225-beta-staging",
3
+ "version": "1.0.226-beta-staging",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -12,14 +12,7 @@ export class AuthModule extends BaseClient {
12
12
  {},
13
13
  true
14
14
  );
15
- this.accessToken = response.access_token;
16
- this.refreshToken = response.refresh_token;
17
- this.user = response.user;
18
-
19
- await this.storage!.setItem('access_token', JSON.stringify(response.access_token));
20
- await this.storage!.setItem('refresh_token', JSON.stringify(response.refresh_token));
21
- await this.storage!.setItem('user', JSON.stringify(response.user));
22
-
15
+ await this.updateAuthState(response);
23
16
  return response;
24
17
  } catch (error) {
25
18
  await this.clearAuth();
@@ -47,14 +40,7 @@ export class AuthModule extends BaseClient {
47
40
  true
48
41
  );
49
42
  console.log(response);
50
- this.accessToken = response.access_token;
51
- this.refreshToken = response.refresh_token;
52
- this.user = response.user;
53
-
54
- await this.storage!.setItem('access_token', JSON.stringify(response.access_token));
55
- await this.storage!.setItem('refresh_token', JSON.stringify(response.refresh_token));
56
- await this.storage!.setItem('user', JSON.stringify(response.user));
57
-
43
+ await this.updateAuthState(response);
58
44
  return response;
59
45
  } catch (error) {
60
46
  await this.clearAuth();
@@ -85,4 +71,16 @@ export class AuthModule extends BaseClient {
85
71
  };
86
72
  return this.request<PasswordChangeResponse>(urls.adminChangePassword, 'PATCH', dto);
87
73
  }
74
+
75
+ private async updateAuthState(response: LoginResponse): Promise<void> {
76
+ this.accessToken = response.access_token;
77
+ this.refreshToken = response.refresh_token;
78
+ this.user = response.user;
79
+
80
+ if (this.storage) {
81
+ await this.storage.setItem('access_token', JSON.stringify(response.access_token));
82
+ await this.storage.setItem('refresh_token', JSON.stringify(response.refresh_token));
83
+ await this.storage.setItem('user', JSON.stringify(response.user));
84
+ }
85
+ }
88
86
  }
@@ -10,19 +10,31 @@ export class BaseClient {
10
10
  protected accessToken: string | null = null;
11
11
  protected refreshToken: string | null = null;
12
12
  protected user: User | null = null;
13
+ private isInitialized: boolean = false;
14
+
13
15
  constructor(config: SDKConfig = {}) {
14
16
  this.baseUrl = config.baseUrl || '/api';
15
17
  this.storage = config.storage;
16
- this.initialize();
18
+ // Don't call initialize() in constructor to avoid race conditions
17
19
  }
18
20
 
19
- protected async initialize() {
20
- const accessToken = await this.storage!.getItem('access_token');
21
- const refreshToken = await this.storage!.getItem('refresh_token');
22
- const userString = await this.storage!.getItem('user');
23
- this.user = userString ? JSON.parse(userString) : null;
24
- this.accessToken = accessToken ? JSON.parse(accessToken) : null;
25
- this.refreshToken = refreshToken ? JSON.parse(refreshToken) : null;
21
+ public async initialize(): Promise<void> {
22
+ if (this.isInitialized || !this.storage) {
23
+ return;
24
+ }
25
+
26
+ try {
27
+ const accessToken = await this.storage.getItem('access_token');
28
+ const refreshToken = await this.storage.getItem('refresh_token');
29
+ const userString = await this.storage.getItem('user');
30
+ this.user = userString ? JSON.parse(userString) : null;
31
+ this.accessToken = accessToken ? JSON.parse(accessToken) : null;
32
+ this.refreshToken = refreshToken ? JSON.parse(refreshToken) : null;
33
+ this.isInitialized = true;
34
+ } catch (error) {
35
+ console.error('Failed to initialize BaseClient:', error);
36
+ this.isInitialized = true; // Mark as initialized even on error to prevent infinite loops
37
+ }
26
38
  }
27
39
 
28
40
  public async fetchConfig(url: string): Promise<void> {
@@ -57,6 +69,8 @@ export class BaseClient {
57
69
  headers: Record<string, string> = {},
58
70
  noToken: boolean = false,
59
71
  ): Promise<T> {
72
+ await this.ensureInitialized();
73
+
60
74
  const url = `${this.baseUrl}${endpoint}`;
61
75
  const defaultHeaders: Record<string, string> = {
62
76
  'Content-Type': 'application/json',
@@ -95,6 +109,8 @@ export class BaseClient {
95
109
  headers: Record<string, string> = {},
96
110
  onProgress?: (percentage: number) => void
97
111
  ): Promise<T> {
112
+ await this.ensureInitialized();
113
+
98
114
  const url = `${this.baseUrl}${endpoint}`;
99
115
  const defaultHeaders: Record<string, string> = {
100
116
  'ngrok-skip-browser-warning': 'true'
@@ -156,6 +172,8 @@ export class BaseClient {
156
172
  }
157
173
 
158
174
  protected async downloadRequest(endpoint: string): Promise<Blob> {
175
+ await this.ensureInitialized();
176
+
159
177
  const url = `${this.baseUrl}${endpoint}`;
160
178
 
161
179
  await this.getToken();
@@ -184,6 +202,8 @@ export class BaseClient {
184
202
  }
185
203
 
186
204
  protected async textRequest(endpoint: string): Promise<string> {
205
+ await this.ensureInitialized();
206
+
187
207
  const url = `${this.baseUrl}${endpoint}`;
188
208
 
189
209
  await this.getToken();
@@ -250,9 +270,11 @@ export class BaseClient {
250
270
  this.refreshToken = response.refresh_token;
251
271
  this.user = response.user;
252
272
 
253
- await this.storage!.setItem('access_token', JSON.stringify(response.access_token));
254
- await this.storage!.setItem('refresh_token', JSON.stringify(response.refresh_token));
255
- await this.storage!.setItem('user', JSON.stringify(response.user));
273
+ if (this.storage) {
274
+ await this.storage.setItem('access_token', JSON.stringify(response.access_token));
275
+ await this.storage.setItem('refresh_token', JSON.stringify(response.refresh_token));
276
+ await this.storage.setItem('user', JSON.stringify(response.user));
277
+ }
256
278
  } catch (error) {
257
279
  await this.clearAuth();
258
280
  throw new Error('Failed to refresh access token');
@@ -260,13 +282,32 @@ export class BaseClient {
260
282
  }
261
283
 
262
284
  public isAuthenticated(): boolean {
263
- return !!this.accessToken;
285
+ return !!this.accessToken && !!this.user;
264
286
  }
265
287
 
266
288
  public getCurrentUser(): User | null {
267
289
  return this.user;
268
290
  }
269
291
 
292
+ protected async ensureInitialized(): Promise<void> {
293
+ if (!this.isInitialized) {
294
+ await this.initialize();
295
+ }
296
+ }
297
+
298
+ protected validateUser(): User {
299
+ if (!this.user) {
300
+ throw new Error('User not authenticated. Please log in first.');
301
+ }
302
+ return this.user;
303
+ }
304
+
305
+ public async syncUserState(user: User | null, accessToken: string | null, refreshToken: string | null): Promise<void> {
306
+ this.user = user;
307
+ this.accessToken = accessToken;
308
+ this.refreshToken = refreshToken;
309
+ }
310
+
270
311
  public getAccessToken(): string | null {
271
312
  return this.accessToken;
272
313
  }
@@ -13,9 +13,10 @@ export class TranscriptionSummaryModule extends BaseClient {
13
13
  // ======================
14
14
 
15
15
  public async generateTranscriptionSummary(templateId: string, sessionId: string): Promise<TranscriptionSummary> {
16
+ const user = this.validateUser();
16
17
  const generateSummaryDto: GenerateTranscriptionSummaryDto = {
17
18
  templateId,
18
- userId: this.user!.id,
19
+ userId: user.id,
19
20
  fromUserTemplate: false,
20
21
  sessionId: sessionId,
21
22
  };
@@ -28,9 +29,10 @@ export class TranscriptionSummaryModule extends BaseClient {
28
29
  }
29
30
 
30
31
  public async generateTranscriptionSummaryFromUserTemplate(userTemplateId: string, sessionId: string): Promise<TranscriptionSummary> {
32
+ const user = this.validateUser();
31
33
  const generateSummaryDto: GenerateTranscriptionSummaryDto = {
32
34
  templateId: userTemplateId,
33
- userId: this.user!.id,
35
+ userId: user.id,
34
36
  fromUserTemplate: true,
35
37
  sessionId: sessionId,
36
38
  };
package/src/sdk/sdk.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // Main SDK class that composes all domain modules
2
- import { SDKConfig } from './types';
2
+ import { SDKConfig, User } from './types';
3
3
  import { BaseClient } from './modules/base-client';
4
4
  import { AuthModule } from './modules/auth.module';
5
5
  import { UserModule } from './modules/user.module';
@@ -38,6 +38,9 @@ export class ApiSDK extends BaseClient {
38
38
  public readonly websocket: WebSocketModule;
39
39
  public readonly reports: ReportsModule;
40
40
  public readonly patients: PatientModule;
41
+
42
+ private modules: BaseClient[];
43
+ private sdkInitialized: boolean = false;
41
44
 
42
45
  constructor(config: SDKConfig = {}) {
43
46
  super(config);
@@ -59,6 +62,60 @@ export class ApiSDK extends BaseClient {
59
62
  this.websocket = new WebSocketModule(config);
60
63
  this.reports = new ReportsModule(config);
61
64
  this.patients = new PatientModule(config);
65
+
66
+ // Store all modules for batch operations
67
+ this.modules = [
68
+ this.auth, this.users, this.organizations, this.teams, this.templates,
69
+ this.transcriptionSummaries, this.sessions, this.agents, this.audio,
70
+ this.workflows, this.logs, this.debug, this.externalIntegrations,
71
+ this.websocket, this.reports, this.patients
72
+ ];
73
+ }
74
+
75
+ public async initialize(): Promise<void> {
76
+ if (this.sdkInitialized) {
77
+ return;
78
+ }
79
+
80
+ // Initialize the main SDK (base client)
81
+ await super.initialize();
82
+
83
+ // Initialize all modules and sync their state
84
+ await Promise.all(this.modules.map(module => module.initialize()));
85
+
86
+ // Sync user state across all modules
87
+ await this.syncUserStateAcrossModules();
88
+
89
+ this.sdkInitialized = true;
90
+ }
91
+
92
+ public isReady(): boolean {
93
+ return this.sdkInitialized;
94
+ }
95
+
96
+ private async syncUserStateAcrossModules(): Promise<void> {
97
+ const currentUser = this.getCurrentUser();
98
+ const accessToken = this.getAccessToken();
99
+ const refreshToken = this.getRefreshToken();
100
+
101
+ // Sync state to all modules
102
+ await Promise.all(
103
+ this.modules.map(module =>
104
+ module.syncUserState(currentUser, accessToken, refreshToken)
105
+ )
106
+ );
107
+ }
108
+
109
+ public async syncUserState(user: User | null, accessToken: string | null, refreshToken: string | null): Promise<void> {
110
+ // Update main SDK state
111
+ await super.syncUserState(user, accessToken, refreshToken);
112
+
113
+ // Sync to all modules
114
+ await Promise.all(
115
+ this.modules.map(module =>
116
+ module.syncUserState(user, accessToken, refreshToken)
117
+ )
118
+ );
62
119
  }
63
120
 
64
121
  // ======================
@@ -68,11 +125,17 @@ export class ApiSDK extends BaseClient {
68
125
 
69
126
  // Auth methods
70
127
  public async login(...args: Parameters<AuthModule['login']>) {
71
- return this.auth.login(...args);
128
+ const result = await this.auth.login(...args);
129
+ // Sync user state across all modules after successful login
130
+ await this.syncUserStateAcrossModules();
131
+ return result;
72
132
  }
73
133
 
74
134
  public async logout(...args: Parameters<AuthModule['logout']>) {
75
- return this.auth.logout(...args);
135
+ const result = await this.auth.logout(...args);
136
+ // Sync cleared state across all modules after logout
137
+ await this.syncUserStateAcrossModules();
138
+ return result;
76
139
  }
77
140
 
78
141
  public async getProfile(...args: Parameters<AuthModule['getProfile']>) {
@@ -92,7 +155,10 @@ export class ApiSDK extends BaseClient {
92
155
  }
93
156
 
94
157
  public async loginWithCode(...args: Parameters<AuthModule['loginWithCode']>) {
95
- return this.auth.loginWithCode(...args);
158
+ const result = await this.auth.loginWithCode(...args);
159
+ // Sync user state across all modules after successful login
160
+ await this.syncUserStateAcrossModules();
161
+ return result;
96
162
  }
97
163
 
98
164
  // User methods