whio-api-sdk 1.0.225-beta-staging → 1.0.227-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.
- package/dist/src/sdk/modules/auth.module.d.ts +1 -0
- package/dist/src/sdk/modules/auth.module.js +14 -12
- package/dist/src/sdk/modules/base-client.d.ts +5 -1
- package/dist/src/sdk/modules/base-client.js +48 -11
- package/dist/src/sdk/modules/transcription-summary.module.js +4 -2
- package/dist/src/sdk/sdk.d.ts +19 -13
- package/dist/src/sdk/sdk.js +64 -3
- package/package.json +1 -1
- package/src/sdk/modules/auth.module.ts +14 -16
- package/src/sdk/modules/base-client.ts +53 -12
- package/src/sdk/modules/transcription-summary.module.ts +4 -2
- package/src/sdk/sdk.ts +75 -4
|
@@ -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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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:
|
|
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:
|
|
34
|
+
userId: user.id,
|
|
33
35
|
fromUserTemplate: true,
|
|
34
36
|
sessionId: sessionId,
|
|
35
37
|
};
|
package/dist/src/sdk/sdk.d.ts
CHANGED
|
@@ -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<
|
|
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<
|
|
50
|
-
assignEditorToRoleToUser(...args: Parameters<UserModule['assignEditorToRoleToUser']>): Promise<
|
|
51
|
-
assignAdminToRoleToUser(...args: Parameters<UserModule['assignAdminToRoleToUser']>): Promise<
|
|
52
|
-
assignDisabledToRoleToUser(...args: Parameters<UserModule['assignDisabledToRoleToUser']>): Promise<
|
|
53
|
-
createEditorUser(...args: Parameters<UserModule['createEditorUser']>): Promise<
|
|
54
|
-
createAdminUser(...args: Parameters<UserModule['createAdminUser']>): Promise<
|
|
55
|
-
createDisabledUser(...args: Parameters<UserModule['createDisabledUser']>): Promise<
|
|
56
|
-
getUsers(...args: Parameters<UserModule['getUsers']>): Promise<
|
|
57
|
-
getUser(...args: Parameters<UserModule['getUser']>): Promise<
|
|
58
|
-
getUsersByOrganization(...args: Parameters<UserModule['getUsersByOrganization']>): Promise<
|
|
59
|
-
updateUser(...args: Parameters<UserModule['updateUser']>): Promise<
|
|
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[]>;
|
package/dist/src/sdk/sdk.js
CHANGED
|
@@ -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,57 @@ 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
|
+
// Auto-initialize the SDK
|
|
59
|
+
this.initialize().catch(error => {
|
|
60
|
+
console.error('Failed to initialize SDK:', error);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
initialize() {
|
|
64
|
+
const _super = Object.create(null, {
|
|
65
|
+
initialize: { get: () => super.initialize }
|
|
66
|
+
});
|
|
67
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
68
|
+
if (this.sdkInitialized) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
// Initialize the main SDK (base client)
|
|
72
|
+
yield _super.initialize.call(this);
|
|
73
|
+
// Initialize all modules and sync their state
|
|
74
|
+
yield Promise.all(this.modules.map(module => module.initialize()));
|
|
75
|
+
// Sync user state across all modules
|
|
76
|
+
yield this.syncUserStateAcrossModules();
|
|
77
|
+
this.sdkInitialized = true;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
isReady() {
|
|
81
|
+
return this.sdkInitialized;
|
|
82
|
+
}
|
|
83
|
+
syncUserStateAcrossModules() {
|
|
84
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
85
|
+
const currentUser = this.getCurrentUser();
|
|
86
|
+
const accessToken = this.getAccessToken();
|
|
87
|
+
const refreshToken = this.getRefreshToken();
|
|
88
|
+
// Sync state to all modules
|
|
89
|
+
yield Promise.all(this.modules.map(module => module.syncUserState(currentUser, accessToken, refreshToken)));
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
syncUserState(user, accessToken, refreshToken) {
|
|
93
|
+
const _super = Object.create(null, {
|
|
94
|
+
syncUserState: { get: () => super.syncUserState }
|
|
95
|
+
});
|
|
96
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
// Update main SDK state
|
|
98
|
+
yield _super.syncUserState.call(this, user, accessToken, refreshToken);
|
|
99
|
+
// Sync to all modules
|
|
100
|
+
yield Promise.all(this.modules.map(module => module.syncUserState(user, accessToken, refreshToken)));
|
|
101
|
+
});
|
|
50
102
|
}
|
|
51
103
|
// ======================
|
|
52
104
|
// BACKWARD COMPATIBILITY LAYER
|
|
@@ -55,12 +107,18 @@ export class ApiSDK extends BaseClient {
|
|
|
55
107
|
// Auth methods
|
|
56
108
|
login(...args) {
|
|
57
109
|
return __awaiter(this, void 0, void 0, function* () {
|
|
58
|
-
|
|
110
|
+
const result = yield this.auth.login(...args);
|
|
111
|
+
// Sync user state across all modules after successful login
|
|
112
|
+
yield this.syncUserState(result.user, result.access_token, result.refresh_token);
|
|
113
|
+
return result;
|
|
59
114
|
});
|
|
60
115
|
}
|
|
61
116
|
logout(...args) {
|
|
62
117
|
return __awaiter(this, void 0, void 0, function* () {
|
|
63
|
-
|
|
118
|
+
const result = yield this.auth.logout(...args);
|
|
119
|
+
// Sync cleared state across all modules after logout
|
|
120
|
+
yield this.syncUserState(null, null, null);
|
|
121
|
+
return result;
|
|
64
122
|
});
|
|
65
123
|
}
|
|
66
124
|
getProfile(...args) {
|
|
@@ -85,7 +143,10 @@ export class ApiSDK extends BaseClient {
|
|
|
85
143
|
}
|
|
86
144
|
loginWithCode(...args) {
|
|
87
145
|
return __awaiter(this, void 0, void 0, function* () {
|
|
88
|
-
|
|
146
|
+
const result = yield this.auth.loginWithCode(...args);
|
|
147
|
+
// Sync user state across all modules after successful login
|
|
148
|
+
yield this.syncUserState(result.user, result.access_token, result.refresh_token);
|
|
149
|
+
return result;
|
|
89
150
|
});
|
|
90
151
|
}
|
|
91
152
|
// User methods
|
package/package.json
CHANGED
|
@@ -12,14 +12,7 @@ export class AuthModule extends BaseClient {
|
|
|
12
12
|
{},
|
|
13
13
|
true
|
|
14
14
|
);
|
|
15
|
-
this.
|
|
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.
|
|
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
|
-
|
|
18
|
+
// Don't call initialize() in constructor to avoid race conditions
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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:
|
|
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:
|
|
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,65 @@ 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
|
+
// Auto-initialize the SDK
|
|
75
|
+
this.initialize().catch(error => {
|
|
76
|
+
console.error('Failed to initialize SDK:', error);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public async initialize(): Promise<void> {
|
|
81
|
+
if (this.sdkInitialized) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Initialize the main SDK (base client)
|
|
86
|
+
await super.initialize();
|
|
87
|
+
|
|
88
|
+
// Initialize all modules and sync their state
|
|
89
|
+
await Promise.all(this.modules.map(module => module.initialize()));
|
|
90
|
+
|
|
91
|
+
// Sync user state across all modules
|
|
92
|
+
await this.syncUserStateAcrossModules();
|
|
93
|
+
|
|
94
|
+
this.sdkInitialized = true;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public isReady(): boolean {
|
|
98
|
+
return this.sdkInitialized;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private async syncUserStateAcrossModules(): Promise<void> {
|
|
102
|
+
const currentUser = this.getCurrentUser();
|
|
103
|
+
const accessToken = this.getAccessToken();
|
|
104
|
+
const refreshToken = this.getRefreshToken();
|
|
105
|
+
|
|
106
|
+
// Sync state to all modules
|
|
107
|
+
await Promise.all(
|
|
108
|
+
this.modules.map(module =>
|
|
109
|
+
module.syncUserState(currentUser, accessToken, refreshToken)
|
|
110
|
+
)
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
public async syncUserState(user: User | null, accessToken: string | null, refreshToken: string | null): Promise<void> {
|
|
115
|
+
// Update main SDK state
|
|
116
|
+
await super.syncUserState(user, accessToken, refreshToken);
|
|
117
|
+
|
|
118
|
+
// Sync to all modules
|
|
119
|
+
await Promise.all(
|
|
120
|
+
this.modules.map(module =>
|
|
121
|
+
module.syncUserState(user, accessToken, refreshToken)
|
|
122
|
+
)
|
|
123
|
+
);
|
|
62
124
|
}
|
|
63
125
|
|
|
64
126
|
// ======================
|
|
@@ -68,11 +130,17 @@ export class ApiSDK extends BaseClient {
|
|
|
68
130
|
|
|
69
131
|
// Auth methods
|
|
70
132
|
public async login(...args: Parameters<AuthModule['login']>) {
|
|
71
|
-
|
|
133
|
+
const result = await this.auth.login(...args);
|
|
134
|
+
// Sync user state across all modules after successful login
|
|
135
|
+
await this.syncUserState(result.user, result.access_token, result.refresh_token);
|
|
136
|
+
return result;
|
|
72
137
|
}
|
|
73
138
|
|
|
74
139
|
public async logout(...args: Parameters<AuthModule['logout']>) {
|
|
75
|
-
|
|
140
|
+
const result = await this.auth.logout(...args);
|
|
141
|
+
// Sync cleared state across all modules after logout
|
|
142
|
+
await this.syncUserState(null, null, null);
|
|
143
|
+
return result;
|
|
76
144
|
}
|
|
77
145
|
|
|
78
146
|
public async getProfile(...args: Parameters<AuthModule['getProfile']>) {
|
|
@@ -92,7 +160,10 @@ export class ApiSDK extends BaseClient {
|
|
|
92
160
|
}
|
|
93
161
|
|
|
94
162
|
public async loginWithCode(...args: Parameters<AuthModule['loginWithCode']>) {
|
|
95
|
-
|
|
163
|
+
const result = await this.auth.loginWithCode(...args);
|
|
164
|
+
// Sync user state across all modules after successful login
|
|
165
|
+
await this.syncUserState(result.user, result.access_token, result.refresh_token);
|
|
166
|
+
return result;
|
|
96
167
|
}
|
|
97
168
|
|
|
98
169
|
// User methods
|