whio-api-sdk 1.0.0

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/src/index.ts ADDED
@@ -0,0 +1,101 @@
1
+ import { title } from 'process';
2
+ import { ApiSDK } from './sdk';
3
+ import { LoginCredentials, User, SDKConfig } from './types';
4
+
5
+ const keepAlive = setInterval(() => {}, 1000);
6
+
7
+ class storage {
8
+ constructor() {
9
+ console.log("Storage initialized");
10
+ }
11
+
12
+ private items: { [key: string]: string } = {};
13
+
14
+ public getItem(key: string): string | null | Promise<string | null> {
15
+ return this.items[key] || null;
16
+ }
17
+
18
+ public setItem(key: string, value: string): void | Promise<void> {
19
+ this.items[key] = value;
20
+ }
21
+
22
+ public removeItem(key: string): void | Promise<void> {
23
+ delete this.items[key];
24
+ }
25
+
26
+ }
27
+
28
+ const config: SDKConfig = {
29
+ baseUrl: 'http://localhost:3000',
30
+ storage: new storage(),
31
+ };
32
+
33
+ const loginCredentials: LoginCredentials = {
34
+ email: "rimu.boddy@make.nz",
35
+ password: "cbr400rr",
36
+ }
37
+
38
+ const sdk = new ApiSDK(config);
39
+ async function main() {
40
+ await sdk.login(loginCredentials);
41
+ const user: User | null = sdk.getCurrentUser();
42
+ const newUser: User = await sdk.createEditorUser(
43
+ "Rimu",
44
+ "Rimu",
45
+ "chiscs2snw2@bread.com",
46
+ "cbr400rr",
47
+ );
48
+
49
+ const team = await sdk.createTeam(
50
+ "best team ever",
51
+ "this is the best team ever",
52
+ );
53
+
54
+ console.log(team);
55
+
56
+ const assignRes = await sdk.addUserToTeam(team.id, newUser.id, "admin");
57
+
58
+ const template = await sdk.createTemplate(
59
+ "Test Template",
60
+ "This is a test template",
61
+ );
62
+
63
+ const updatedTemplate = await sdk.updateTemplate(
64
+ "Updated Template",
65
+ "This is an updated test template",
66
+ template.id,
67
+ );
68
+
69
+ const userTemplate = await sdk.createUserTemplate(
70
+ "User Template",
71
+ "This is a user template",
72
+ template.id,
73
+ );
74
+
75
+ const updatedUserTemplate = await sdk.updateUserTemplate(
76
+ "User templated updated",
77
+ "This is an updated user template",
78
+ userTemplate.id,
79
+ );
80
+
81
+ //console.log("Usertemplate", userTemplate);
82
+ //console.log("Updated User Template", updatedUserTemplate);
83
+
84
+ const templates = await sdk.getTemplates();
85
+ const userTemplates = await sdk.getUserTemplates();
86
+
87
+
88
+
89
+ }
90
+
91
+ main().catch((error) => {
92
+ console.error("Error:", error);
93
+ });
94
+
95
+ //make sure no exit
96
+
97
+
98
+
99
+
100
+
101
+
package/src/sdk.ts ADDED
@@ -0,0 +1,353 @@
1
+ // sdk.ts
2
+ import {
3
+ LoginResponse,
4
+ LoginCredentials,
5
+ SDKConfig,
6
+ User,
7
+ AssignTeamRoleDto,
8
+ CreateTeamDto,
9
+ UpdateTeamDto,
10
+ CreateTemplateDto,
11
+ UpdateTemplateDto,
12
+ GenerateTranscriptionSummaryDto,
13
+ UpdateTranscriptionSummaryDto,
14
+ AssignOrganizationRoleDto,
15
+ CreateUserTemplateDto,
16
+ UpdateUserTemplateDto,
17
+ CreateUserDto,
18
+ UpdateUserDto,
19
+ OrganizationRoleType,
20
+ Organization,
21
+ TemplateCategory,
22
+ Template,
23
+ Team,
24
+ UserTemplate,
25
+ TranscriptionSummary,
26
+ } from './types';
27
+ import urls from './urls';
28
+ import jwtDecode from 'jwt-decode';
29
+
30
+ export class ApiSDK {
31
+ private baseUrl: string;
32
+ private storage: SDKConfig['storage'];
33
+ private accessToken: string | null = null;
34
+ private refreshToken: string | null = null;
35
+ private user: User | null = null;
36
+
37
+ constructor(config: SDKConfig = {}) {
38
+ this.baseUrl = config.baseUrl || '/api';
39
+ this.storage = config.storage || {
40
+ getItem: (key) => localStorage.getItem(key),
41
+ setItem: (key, value) => localStorage.setItem(key, value),
42
+ removeItem: (key) => localStorage.removeItem(key),
43
+ };
44
+
45
+ this.initialize();
46
+ }
47
+
48
+ private async initialize() {
49
+ this.accessToken = await this.storage!.getItem('access_token');
50
+ const userString = await this.storage!.getItem('user');
51
+ this.user = userString ? JSON.parse(userString) : null;
52
+ }
53
+
54
+ private async request<T>(
55
+ endpoint: string,
56
+ method: string = 'GET',
57
+ body?: any,
58
+ headers: Record<string, string> = {}
59
+ ): Promise<T> {
60
+ const url = `${this.baseUrl}${endpoint}`;
61
+ const defaultHeaders: Record<string, string> = {
62
+ 'Content-Type': 'application/json',
63
+ 'ngrok-skip-browser-warning': 'true'
64
+ };
65
+
66
+ if (this.accessToken) {
67
+ defaultHeaders['Authorization'] = `Bearer ${this.accessToken}`;
68
+ }
69
+
70
+ const response = await fetch(url, {
71
+ method,
72
+ headers: { ...defaultHeaders, ...headers },
73
+ body: body ? JSON.stringify(body) : undefined,
74
+ });
75
+
76
+ if (!response.ok) {
77
+ const errorData = await response.json().catch(() => ({}));
78
+ throw new Error(
79
+ errorData.message || `Request failed with status ${response.status}`
80
+ );
81
+ }
82
+
83
+ return response.json();
84
+ }
85
+
86
+ public async login(credentials: LoginCredentials): Promise<LoginResponse> {
87
+ try {
88
+ const response = await this.request<LoginResponse>(
89
+ '/auth/login',
90
+ 'POST',
91
+ credentials
92
+ );
93
+ this.accessToken = response.access_token;
94
+ this.refreshToken = response.referesh_token;
95
+
96
+ this.user = response.user;
97
+
98
+ await this.storage!.setItem('access_token', response.access_token);
99
+ await this.storage!.setItem('user', JSON.stringify(response.user));
100
+
101
+ return response;
102
+ } catch (error) {
103
+ await this.clearAuth();
104
+ throw error;
105
+ }
106
+ }
107
+
108
+ public async logout(): Promise<void> {
109
+ try {
110
+ await this.request('/auth/logout', 'POST');
111
+ } finally {
112
+ await this.clearAuth();
113
+ }
114
+ }
115
+
116
+ private async clearAuth(): Promise<void> {
117
+ this.accessToken = null;
118
+ this.user = null;
119
+ await this.storage!.removeItem('access_token');
120
+ await this.storage!.removeItem('user');
121
+ }
122
+
123
+ public isAuthenticated(): boolean {
124
+ return !!this.accessToken;
125
+ }
126
+
127
+ public getCurrentUser(): User | null {
128
+ return this.user;
129
+ }
130
+
131
+ public getAccessToken(): string | null {
132
+ return this.accessToken;
133
+ }
134
+
135
+ public getRefreshToken(): string | null {
136
+ return this.refreshToken;
137
+ }
138
+
139
+ private async createUser(
140
+ firstName: string, lastName: string,
141
+ email: string, password: string): Promise<User> {
142
+
143
+ const createUserDto: CreateUserDto = {
144
+ firstName,
145
+ lastName,
146
+ email,
147
+ password,
148
+ organizationId: this.user?.organizationId,
149
+ };
150
+
151
+ const user = await this.request<User>(
152
+ urls.users,
153
+ 'POST',
154
+ createUserDto
155
+ );
156
+ return user;
157
+ }
158
+
159
+ private async assignRoleToUser(userId: string, roleName: OrganizationRoleType): Promise<User> {
160
+ const organization = await this.request<Organization>(
161
+ `${urls.organizations}/${this.user?.organizationId}`,
162
+ 'GET'
163
+ );
164
+ const orgRoleEditor = organization.roles!.find(
165
+ r => r.name === roleName);
166
+ const assignRoleDto:AssignOrganizationRoleDto = {
167
+ userId: userId,
168
+ organizationRoleId: orgRoleEditor!.id,
169
+ };
170
+ this.request(urls.userOrganizationRoles, 'POST', assignRoleDto);
171
+ const userWithOrgRole = await this.request<User>(
172
+ `${urls.user}/${userId}`,
173
+ 'GET'
174
+ );
175
+ return userWithOrgRole;
176
+ }
177
+
178
+ public async assignEditorToRoleToUser(userId: string): Promise<User> {
179
+ return this.assignRoleToUser(userId, OrganizationRoleType.EDITOR);
180
+ }
181
+
182
+ public async assignAdminToRoleToUser(userId: string): Promise<User> {
183
+ return this.assignRoleToUser(userId, OrganizationRoleType.ADMIN);
184
+ }
185
+
186
+ public async assignDisabledToRoleToUser(userId: string): Promise<User> {
187
+ return this.assignRoleToUser(userId, OrganizationRoleType.DISABLED);
188
+ }
189
+
190
+ public async createEditorUser(firstName: string, lastName: string,
191
+ email: string, password: string): Promise<User> {
192
+ const user = await this.createUser(firstName, lastName, email, password);
193
+ const userWithOrgRole = await this.assignEditorToRoleToUser(user.id);
194
+ return userWithOrgRole;
195
+ }
196
+
197
+ public async createAdminUser(firstName: string, lastName: string,
198
+ email: string, password: string): Promise<User> {
199
+ const user = await this.createUser(firstName, lastName, email, password);
200
+ const userWithOrgRole = await this.assignAdminToRoleToUser(user.id);
201
+ return userWithOrgRole;
202
+ }
203
+
204
+ public async createDisabledUser(firstName: string, lastName: string,
205
+ email: string, password: string): Promise<User> {
206
+ const user = await this.createUser(firstName, lastName, email, password);
207
+ const userWithOrgRole = await this.assignDisabledToRoleToUser(user.id);
208
+ return userWithOrgRole;
209
+ }
210
+
211
+ public async createTeam(name: string, description: string): Promise<Team> {
212
+ const teamDto: CreateTeamDto = {
213
+ name,
214
+ description,
215
+ organizationId: this.user!.organizationId,
216
+ };
217
+ return this.request(urls.teams, 'POST', teamDto);
218
+ }
219
+
220
+ public async updateTeam(id: string, name: string, description: string): Promise<any> {
221
+ const teamDto: UpdateTeamDto = {
222
+ name,
223
+ description,
224
+ };
225
+ return this.request(`${urls.teams}/${id}`, 'PUT', teamDto);
226
+ }
227
+
228
+ public async addUserToTeam(teamId: string, userId: string, roleName: string): Promise<any> {
229
+ const assignRoleDto: AssignTeamRoleDto = {
230
+ teamId,
231
+ userId,
232
+ name: roleName,
233
+ };
234
+ return this.request(urls.teamRoles, 'POST', assignRoleDto);
235
+ }
236
+
237
+ public async removeUserFromTeam(teamId: string, userId: string): Promise<any> {
238
+ const url = `${urls.teamRoles}/user/${userId}/team/${teamId}`;
239
+ return this.request(urls.teamRoles, 'DELETE');
240
+ }
241
+ //unsure how we are going to deal with template categories just yet
242
+ public async createTemplate(title: string, content: string): Promise<any> {
243
+ const templateCategories = await this.request<TemplateCategory[]>(
244
+ urls.templateCatedories,
245
+ 'GET'
246
+ );
247
+ const createTemplateDto: CreateTemplateDto = {
248
+ title,
249
+ content,
250
+ isGlobal: false,
251
+ categoryId: templateCategories[0]!.id,
252
+ createdById: this.user!.id,
253
+ organizationId: this.user!.organizationId,
254
+ };
255
+ return this.request(urls.templates, 'POST', createTemplateDto);
256
+ }
257
+
258
+ public async createUserTemplate(
259
+ title: string, content: string, originalTemplateId: string | undefined): Promise<UserTemplate> {
260
+ const createUserTemplateDto: CreateUserTemplateDto = {
261
+ title,
262
+ content,
263
+ originalTemplateId,
264
+ userId: this.user!.id,
265
+ };
266
+ return this.request(urls.userTemplates, 'POST', createUserTemplateDto);
267
+ }
268
+
269
+ public async updateTemplate(
270
+ title: string, content: string, id: string): Promise<Template> {
271
+ const templateDto: UpdateTemplateDto = {
272
+ title,
273
+ content,
274
+ isGlobal: false,
275
+ organizationId: this.user!.organizationId,
276
+ };
277
+ return this.request<Template>(
278
+ `${urls.templates}/${id}`,
279
+ 'PATCH',
280
+ templateDto,
281
+ );
282
+ }
283
+
284
+ public async updateUserTemplate(
285
+ title: string, content: string, id: string): Promise<UserTemplate> {
286
+ const userTemplateDto: UpdateUserTemplateDto = {
287
+ title,
288
+ content,
289
+ };
290
+ return this.request<UserTemplate>(
291
+ `${urls.userTemplates}/${id}`,
292
+ 'PATCH',
293
+ userTemplateDto,
294
+ );
295
+ }
296
+
297
+ public async getTemplates(): Promise<Template[]> {
298
+ return this.request<Template[]>(urls.templates, 'GET');
299
+ }
300
+
301
+ public async getUserTemplates(): Promise<UserTemplate[]> {
302
+ const url = `${urls.userTemplates}/user/${this.user!.id}`;
303
+ return this.request<UserTemplate[]>(url, 'GET');
304
+ }
305
+
306
+ public async generateTranscriptionSummary(
307
+ transcript: string, templateId: string): Promise<TranscriptionSummary> {
308
+ const generateSummaryDto: GenerateTranscriptionSummaryDto = {
309
+ transcript,
310
+ templateId,
311
+ userId: this.user!.id,
312
+ fromUserTemplate: false,
313
+ };
314
+ const transcriptionSummary:TranscriptionSummary = await this.request(
315
+ urls.transcriptionSummary,
316
+ 'POST',
317
+ generateSummaryDto
318
+ );
319
+ return transcriptionSummary;
320
+ }
321
+
322
+ public async generateTranscriptionSummaryFromUserTemplate(
323
+ transcript: string, userTemplateId: string): Promise<TranscriptionSummary> {
324
+ const generateSummaryDto: GenerateTranscriptionSummaryDto = {
325
+ transcript,
326
+ templateId: userTemplateId,
327
+ userId: this.user!.id,
328
+ fromUserTemplate: true,
329
+ };
330
+ const transcriptionSummary: TranscriptionSummary = await this.request(
331
+ urls.transcriptionSummary,
332
+ 'POST',
333
+ generateSummaryDto
334
+ );
335
+ return transcriptionSummary;
336
+ }
337
+
338
+ public async updateTranscriptionSummary(
339
+ id: string, content: string): Promise<TranscriptionSummary> {
340
+ const updateSummaryDto: UpdateTranscriptionSummaryDto = {
341
+ content,
342
+ };
343
+ return this.request<TranscriptionSummary>(
344
+ `${urls.transcriptionSummary}/${id}`,
345
+ 'PATCH',
346
+ updateSummaryDto,
347
+ );
348
+ }
349
+
350
+
351
+
352
+
353
+ }
package/src/types.ts ADDED
@@ -0,0 +1,278 @@
1
+ // types.ts
2
+
3
+ // Role type
4
+ export interface Role {
5
+ id: string;
6
+ name: string;
7
+ createdAt: string;
8
+ updatedAt: string;
9
+ }
10
+
11
+ // Organization Role type
12
+ export interface OrganizationRole {
13
+ id: string;
14
+ name: string;
15
+ createdAt: string;
16
+ updatedAt: string;
17
+ organizationId: string;
18
+ }
19
+
20
+ // User Role association
21
+ export interface UserRole {
22
+ userId: string;
23
+ roleId: string;
24
+ createdAt: string;
25
+ role: Role;
26
+ }
27
+
28
+ // User Organization Role association
29
+ export interface UserOrganizationRole {
30
+ userId: string;
31
+ organizationRoleId: string;
32
+ createdAt: string;
33
+ organizationRole: OrganizationRole;
34
+ }
35
+
36
+ // Organization type
37
+ export interface Organization {
38
+ id: string;
39
+ name: string;
40
+ description: string;
41
+ createdAt: string;
42
+ updatedAt: string;
43
+
44
+ users?: User[];
45
+ roles?: OrganizationRole[];
46
+ }
47
+
48
+ // User type
49
+ export interface User {
50
+ id: string;
51
+ email: string;
52
+ firstName: string;
53
+ lastName: string;
54
+ createdAt: string;
55
+ updatedAt: string;
56
+ organizationId: string;
57
+ organization: Organization;
58
+ roles: UserRole[];
59
+ organizationRoles: UserOrganizationRole[];
60
+ }
61
+
62
+ // Login response type
63
+ export interface LoginResponse {
64
+ access_token: string;
65
+ referesh_token: string;
66
+ user: User;
67
+ }
68
+
69
+ // Login credentials type
70
+ export interface LoginCredentials {
71
+ email: string;
72
+ password: string;
73
+ }
74
+
75
+ // SDK configuration type
76
+ export interface SDKConfig {
77
+ baseUrl?: string;
78
+ storage?: {
79
+ getItem: (key: string) => string | null | Promise<string | null>;
80
+ setItem: (key: string, value: string) => void | Promise<void>;
81
+ removeItem: (key: string) => void | Promise<void>;
82
+ };
83
+ }
84
+
85
+ // Team Role assignment DTO
86
+ export interface AssignTeamRoleDto {
87
+ userId: string;
88
+ teamId: string;
89
+ name: string;
90
+ }
91
+
92
+ // Team creation DTO
93
+ export interface CreateTeamDto {
94
+ name: string;
95
+ description?: string;
96
+ organizationId: string;
97
+ }
98
+
99
+ // Team update DTO
100
+ export interface UpdateTeamDto {
101
+ name?: string;
102
+ description?: string;
103
+ organizationId?: string;
104
+ }
105
+
106
+ // Template creation DTO
107
+ export interface CreateTemplateDto {
108
+ title: string;
109
+ content: string;
110
+ isGlobal?: boolean;
111
+ organizationId: string;
112
+ categoryId: string;
113
+ createdById: string;
114
+ }
115
+
116
+ // Template update DTO
117
+ export interface UpdateTemplateDto {
118
+ title?: string;
119
+ content?: string;
120
+ isGlobal?: boolean;
121
+ organizationId: string;
122
+ categoryId?: string;
123
+ }
124
+
125
+ // Transcription summary generation DTO
126
+ export interface GenerateTranscriptionSummaryDto {
127
+ transcript?: string;
128
+ templateId: string;
129
+ userId?: string;
130
+ fromUserTemplate?: boolean;
131
+ }
132
+
133
+ // Transcription summary update DTO
134
+ export interface UpdateTranscriptionSummaryDto {
135
+ anonymisedTranscript?: string;
136
+ content?: string;
137
+ metadata?: Record<string, any>;
138
+ templateId?: string;
139
+ }
140
+
141
+ // Organization role assignment DTO
142
+ export interface AssignOrganizationRoleDto {
143
+ userId: string;
144
+ organizationRoleId: string;
145
+ }
146
+
147
+ // User template creation DTO
148
+ export interface CreateUserTemplateDto {
149
+ title: string;
150
+ content: string;
151
+ userId: string;
152
+ originalTemplateId?: string;
153
+ }
154
+
155
+ // User template update DTO
156
+ export interface UpdateUserTemplateDto {
157
+ title?: string;
158
+ content?: string;
159
+ }
160
+
161
+ // User creation DTO
162
+ export interface CreateUserDto {
163
+ email: string;
164
+ password: string;
165
+ firstName?: string;
166
+ lastName?: string;
167
+ organizationId?: string;
168
+ }
169
+
170
+ // User update DTO
171
+ export interface UpdateUserDto {
172
+ email?: string;
173
+ password?: string;
174
+ firstName?: string;
175
+ lastName?: string;
176
+ organizationId?: string;
177
+ }
178
+
179
+ export enum OrganizationRoleType {
180
+ ADMIN = 'ADMIN',
181
+ EDITOR = 'EDITOR',
182
+ DISABLED = 'DISABLED',
183
+ }
184
+
185
+ export interface AdminUser {
186
+ id: string;
187
+ email: string;
188
+ password_hash: string;
189
+ role: string;
190
+ created_at: Date;
191
+ }
192
+
193
+ export interface TemplateCategory {
194
+ id: string;
195
+ name: string;
196
+ }
197
+
198
+ export interface Template {
199
+ id: string;
200
+ title: string;
201
+ content: string;
202
+ createdAt: string;
203
+ updatesAt: string;
204
+ isGlobal: boolean;
205
+ organizationId?: string;
206
+ categoryId: string;
207
+ createdById: string;
208
+
209
+ organization?: Organization;
210
+ category?: TemplateCategory;
211
+ createdBy?: User;
212
+ userTemplates?: UserTemplate[];
213
+ transcriptionSummaries?: TranscriptionSummary[];
214
+ teamTemplates?: TeamTemplate[];
215
+ }
216
+
217
+ export interface UserTemplate {
218
+ id: string;
219
+ title: string;
220
+ content: string;
221
+ createdAt: string;
222
+ updatesAt: string;
223
+ userId: string;
224
+ originalTemplateId?: string;
225
+
226
+ user?: User;
227
+ originalTemplate?: Template;
228
+ }
229
+
230
+ export interface TranscriptionSummary {
231
+ id: string;
232
+ anonymisedTranscript?: string;
233
+ content: string;
234
+ metadata?: any;
235
+ createdAt: string;
236
+ updatesAt: string;
237
+ templateId: string;
238
+ userId: string;
239
+
240
+ template?: Template;
241
+ user?: User;
242
+ }
243
+
244
+ export interface TeamTemplate {
245
+ teamId: string;
246
+ templateId: string;
247
+ createdAt: string;
248
+
249
+ team?: Team;
250
+ template?: Template;
251
+ }
252
+
253
+ export interface TeamRole {
254
+ id: string;
255
+ name: string;
256
+ createdAt: string;
257
+ updatesAt: string;
258
+ userId: string;
259
+ teamId: string;
260
+
261
+ user?: User;
262
+ team?: Team;
263
+ }
264
+
265
+ export interface Team {
266
+ id: string;
267
+ name: string;
268
+ description?: string;
269
+ createdAt: string;
270
+ updatesAt: string;
271
+ organizationId: string;
272
+
273
+ organization?: Organization;
274
+ teamRoles?: TeamRole[];
275
+ teamTemplates?: TeamTemplate[];
276
+ }
277
+
278
+