whio-api-sdk 1.0.155 ā 1.0.156
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/.claude/settings.local.json +6 -1
- package/dist/src/sdk/index.d.ts +1 -0
- package/dist/src/sdk/index.js +1 -0
- package/dist/src/sdk/sdk.d.ts +39 -5
- package/dist/src/sdk/sdk.js +220 -9
- package/dist/src/sdk/types.d.ts +33 -2
- package/dist/src/sdk/types.js +8 -0
- package/dist/src/sdk/urls.d.ts +8 -5
- package/dist/src/sdk/urls.js +15 -5
- package/package.json +3 -2
- package/quick-test.mjs +155 -0
- package/src/sdk/index.ts +2 -1
- package/src/sdk/sdk.ts +214 -16
- package/src/sdk/types.ts +45 -7
- package/src/sdk/urls.ts +21 -5
- package/test-comprehensive.mjs +276 -0
- package/test-sdk.cjs +190 -0
- package/test-sdk.mjs +228 -0
- package/test-sdk.ts +167 -0
- package/test-simple.mjs +90 -0
package/src/sdk/sdk.ts
CHANGED
|
@@ -11,12 +11,19 @@ import {
|
|
|
11
11
|
UpdateTemplateDto,
|
|
12
12
|
GenerateTranscriptionSummaryDto,
|
|
13
13
|
UpdateTranscriptionSummaryDto,
|
|
14
|
+
CreateTranscriptionSummaryDto,
|
|
14
15
|
AssignOrganizationRoleDto,
|
|
15
16
|
CreateUserTemplateDto,
|
|
16
17
|
UpdateUserTemplateDto,
|
|
17
18
|
CreateUserDto,
|
|
18
19
|
UpdateUserDto,
|
|
20
|
+
CreateOrganizationDto,
|
|
21
|
+
UpdateOrganizationDto,
|
|
22
|
+
CreateTemplateCategoryDto,
|
|
23
|
+
UpdateTemplateCategoryDto,
|
|
24
|
+
AssignTeamTemplateDto,
|
|
19
25
|
OrganizationRoleType,
|
|
26
|
+
RoleType,
|
|
20
27
|
Organization,
|
|
21
28
|
TemplateCategory,
|
|
22
29
|
Template,
|
|
@@ -117,7 +124,6 @@ export class ApiSDK {
|
|
|
117
124
|
): Promise<T> {
|
|
118
125
|
const url = `${this.baseUrl}${endpoint}`;
|
|
119
126
|
const defaultHeaders: Record<string, string> = {
|
|
120
|
-
'Content-Type': 'multipart/form-data',
|
|
121
127
|
'ngrok-skip-browser-warning': 'true'
|
|
122
128
|
};
|
|
123
129
|
|
|
@@ -125,6 +131,7 @@ export class ApiSDK {
|
|
|
125
131
|
defaultHeaders['Authorization'] = `Bearer ${this.accessToken}`;
|
|
126
132
|
}
|
|
127
133
|
|
|
134
|
+
// Don't set Content-Type for FormData - let browser set it with boundary
|
|
128
135
|
const response = await fetch(url, {
|
|
129
136
|
method: 'POST',
|
|
130
137
|
headers: { ...defaultHeaders, ...headers },
|
|
@@ -151,7 +158,7 @@ export class ApiSDK {
|
|
|
151
158
|
true
|
|
152
159
|
);
|
|
153
160
|
this.accessToken = response.access_token;
|
|
154
|
-
this.refreshToken = response.
|
|
161
|
+
this.refreshToken = response.refresh_token;
|
|
155
162
|
|
|
156
163
|
this.user = response.user;
|
|
157
164
|
|
|
@@ -277,12 +284,12 @@ export class ApiSDK {
|
|
|
277
284
|
return this.request(urls.teams, 'POST', teamDto);
|
|
278
285
|
}
|
|
279
286
|
|
|
280
|
-
public async updateTeam(id: string, name: string, description: string): Promise<
|
|
287
|
+
public async updateTeam(id: string, name: string, description: string): Promise<Team> {
|
|
281
288
|
const teamDto: UpdateTeamDto = {
|
|
282
289
|
name,
|
|
283
290
|
description,
|
|
284
291
|
};
|
|
285
|
-
return this.request(`${urls.teams}/${id}`, '
|
|
292
|
+
return this.request<Team>(`${urls.teams}/${id}`, 'PATCH', teamDto);
|
|
286
293
|
}
|
|
287
294
|
|
|
288
295
|
public async addUserToTeam(teamId: string, userId: string, roleName: string): Promise<any> {
|
|
@@ -294,25 +301,31 @@ export class ApiSDK {
|
|
|
294
301
|
return this.request(urls.teamRoles, 'POST', assignRoleDto);
|
|
295
302
|
}
|
|
296
303
|
|
|
297
|
-
public async removeUserFromTeam(teamId: string, userId: string): Promise<
|
|
298
|
-
|
|
299
|
-
return this.request(urls.teamRoles, 'DELETE');
|
|
304
|
+
public async removeUserFromTeam(teamId: string, userId: string): Promise<void> {
|
|
305
|
+
await this.request(`${urls.teamRoles}/user/${userId}/team/${teamId}`, 'DELETE');
|
|
300
306
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
+
public async createTemplate(title: string, content: string, categoryId?: string): Promise<Template> {
|
|
308
|
+
let finalCategoryId = categoryId;
|
|
309
|
+
if (!finalCategoryId) {
|
|
310
|
+
const templateCategories = await this.request<TemplateCategory[]>(
|
|
311
|
+
urls.templateCategories,
|
|
312
|
+
'GET'
|
|
313
|
+
);
|
|
314
|
+
finalCategoryId = templateCategories[0]?.id;
|
|
315
|
+
if (!finalCategoryId) {
|
|
316
|
+
throw new Error('No template categories available. Please create one first.');
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
307
320
|
const createTemplateDto: CreateTemplateDto = {
|
|
308
321
|
title,
|
|
309
322
|
content,
|
|
310
323
|
isGlobal: false,
|
|
311
|
-
categoryId:
|
|
324
|
+
categoryId: finalCategoryId,
|
|
312
325
|
createdById: this.user!.id,
|
|
313
326
|
organizationId: this.user!.organizationId,
|
|
314
327
|
};
|
|
315
|
-
return this.request(urls.templates, 'POST', createTemplateDto);
|
|
328
|
+
return this.request<Template>(urls.templates, 'POST', createTemplateDto);
|
|
316
329
|
}
|
|
317
330
|
|
|
318
331
|
public async createUserTemplate(
|
|
@@ -363,6 +376,10 @@ export class ApiSDK {
|
|
|
363
376
|
return this.request<UserTemplate[]>(url, 'GET');
|
|
364
377
|
}
|
|
365
378
|
|
|
379
|
+
// ======================
|
|
380
|
+
// trANSCRIPTION SUMMARY METHODS
|
|
381
|
+
// ======================
|
|
382
|
+
|
|
366
383
|
public async generateTranscriptionSummary(
|
|
367
384
|
transcript: string, templateId: string): Promise<TranscriptionSummary> {
|
|
368
385
|
const generateSummaryDto: GenerateTranscriptionSummaryDto = {
|
|
@@ -379,6 +396,14 @@ export class ApiSDK {
|
|
|
379
396
|
return transcriptionSummary;
|
|
380
397
|
}
|
|
381
398
|
|
|
399
|
+
public async getByOrganizationTranscriptionSummaries(
|
|
400
|
+
organizationId: string): Promise<TranscriptionSummary[]> {
|
|
401
|
+
return this.request<TranscriptionSummary[]>(
|
|
402
|
+
`${urls.transcriptionSummaries}/organization/${organizationId}`,
|
|
403
|
+
'GET'
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
|
|
382
407
|
public async generateTranscriptionSummaryFromUserTemplate(
|
|
383
408
|
transcript: string, userTemplateId: string): Promise<TranscriptionSummary> {
|
|
384
409
|
const generateSummaryDto: GenerateTranscriptionSummaryDto = {
|
|
@@ -426,7 +451,7 @@ export class ApiSDK {
|
|
|
426
451
|
return data;
|
|
427
452
|
}
|
|
428
453
|
|
|
429
|
-
public async transcribeBase64Audio(base64String:
|
|
454
|
+
public async transcribeBase64Audio(base64String: string): Promise<string> {
|
|
430
455
|
const transcript = await this.request<any>(
|
|
431
456
|
urls.transcribeBase64Audio,
|
|
432
457
|
'POST',
|
|
@@ -434,4 +459,177 @@ export class ApiSDK {
|
|
|
434
459
|
return transcript.transcript;
|
|
435
460
|
}
|
|
436
461
|
|
|
462
|
+
// ======================
|
|
463
|
+
// AUTH METHODS
|
|
464
|
+
// ======================
|
|
465
|
+
|
|
466
|
+
public async getProfile(): Promise<User> {
|
|
467
|
+
return this.request<User>(urls.profile, 'GET');
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// ======================
|
|
471
|
+
// ORGANIZATION METHODS
|
|
472
|
+
// ======================
|
|
473
|
+
|
|
474
|
+
public async createOrganization(name: string, description?: string): Promise<Organization> {
|
|
475
|
+
const dto: CreateOrganizationDto = { name, description };
|
|
476
|
+
return this.request<Organization>(urls.organizations, 'POST', dto);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
public async getOrganizations(): Promise<Organization[]> {
|
|
480
|
+
return this.request<Organization[]>(urls.organizations, 'GET');
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
public async getOrganization(id: string): Promise<Organization> {
|
|
484
|
+
return this.request<Organization>(`${urls.organizations}/${id}`, 'GET');
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
public async updateOrganization(id: string, name?: string, description?: string): Promise<Organization> {
|
|
488
|
+
const dto: UpdateOrganizationDto = { name, description };
|
|
489
|
+
return this.request<Organization>(`${urls.organizations}/${id}`, 'PATCH', dto);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
public async deleteOrganization(id: string): Promise<void> {
|
|
493
|
+
await this.request(`${urls.organizations}/${id}`, 'DELETE');
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
public async addUserToOrganization(organizationId: string, userId: string): Promise<void> {
|
|
497
|
+
await this.request(`${urls.organizations}/${organizationId}/users/${userId}`, 'POST');
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
public async removeUserFromOrganization(organizationId: string, userId: string): Promise<void> {
|
|
501
|
+
await this.request(`${urls.organizations}/${organizationId}/users/${userId}`, 'DELETE');
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// ======================
|
|
505
|
+
// USER METHODS
|
|
506
|
+
// ======================
|
|
507
|
+
|
|
508
|
+
public async getUsers(): Promise<User[]> {
|
|
509
|
+
return this.request<User[]>(urls.users, 'GET');
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
public async getUser(id: string): Promise<User> {
|
|
513
|
+
return this.request<User>(`${urls.users}/${id}`, 'GET');
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
public async getUsersByOrganization(organizationId: string): Promise<User[]> {
|
|
517
|
+
return this.request<User[]>(`${urls.users}/organization/${organizationId}`, 'GET');
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
public async updateUser(id: string, data: UpdateUserDto): Promise<User> {
|
|
521
|
+
return this.request<User>(`${urls.users}/${id}`, 'PATCH', data);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
public async deleteUser(id: string): Promise<void> {
|
|
525
|
+
await this.request(`${urls.users}/${id}`, 'DELETE');
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// ======================
|
|
529
|
+
// TEAM METHODS
|
|
530
|
+
// ======================
|
|
531
|
+
|
|
532
|
+
public async getTeams(): Promise<Team[]> {
|
|
533
|
+
return this.request<Team[]>(urls.teams, 'GET');
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
public async getTeam(id: string): Promise<Team> {
|
|
537
|
+
return this.request<Team>(`${urls.teams}/${id}`, 'GET');
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
public async getTeamsByOrganization(organizationId: string): Promise<Team[]> {
|
|
541
|
+
return this.request<Team[]>(`${urls.teams}/organization/${organizationId}`, 'GET');
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
public async deleteTeam(id: string): Promise<void> {
|
|
545
|
+
await this.request(`${urls.teams}/${id}`, 'DELETE');
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// ======================
|
|
549
|
+
// TEMPLATE CATEGORY METHODS
|
|
550
|
+
// ======================
|
|
551
|
+
|
|
552
|
+
public async getTemplateCategories(): Promise<TemplateCategory[]> {
|
|
553
|
+
return this.request<TemplateCategory[]>(urls.templateCategories, 'GET');
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
public async getTemplateCategory(id: string): Promise<TemplateCategory> {
|
|
557
|
+
return this.request<TemplateCategory>(`${urls.templateCategories}/${id}`, 'GET');
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
public async createTemplateCategory(name: string): Promise<TemplateCategory> {
|
|
561
|
+
const dto: CreateTemplateCategoryDto = { name };
|
|
562
|
+
return this.request<TemplateCategory>(urls.templateCategories, 'POST', dto);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
public async updateTemplateCategory(id: string, name: string): Promise<TemplateCategory> {
|
|
566
|
+
const dto: UpdateTemplateCategoryDto = { name };
|
|
567
|
+
return this.request<TemplateCategory>(`${urls.templateCategories}/${id}`, 'PATCH', dto);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
public async deleteTemplateCategory(id: string): Promise<void> {
|
|
571
|
+
await this.request(`${urls.templateCategories}/${id}`, 'DELETE');
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// ======================
|
|
575
|
+
// ENHANCED TEMPLATE METHODS
|
|
576
|
+
// ======================
|
|
577
|
+
|
|
578
|
+
public async getTemplate(id: string): Promise<Template> {
|
|
579
|
+
return this.request<Template>(`${urls.templates}/${id}`, 'GET');
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
public async deleteTemplate(id: string): Promise<void> {
|
|
583
|
+
await this.request(`${urls.templates}/${id}`, 'DELETE');
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
public async getUserTemplate(id: string): Promise<UserTemplate> {
|
|
587
|
+
return this.request<UserTemplate>(`${urls.userTemplates}/${id}`, 'GET');
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
public async deleteUserTemplate(id: string): Promise<void> {
|
|
591
|
+
await this.request(`${urls.userTemplates}/${id}`, 'DELETE');
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// ======================
|
|
595
|
+
// TEAM TEMPLATE METHODS
|
|
596
|
+
// ======================
|
|
597
|
+
|
|
598
|
+
public async assignTemplateToTeam(teamId: string, templateId: string): Promise<void> {
|
|
599
|
+
const dto: AssignTeamTemplateDto = { teamId, templateId };
|
|
600
|
+
await this.request(urls.teamTemplates, 'POST', dto);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
public async removeTemplateFromTeam(teamId: string, templateId: string): Promise<void> {
|
|
604
|
+
await this.request(`${urls.teamTemplates}/team/${teamId}/template/${templateId}`, 'DELETE');
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// ======================
|
|
608
|
+
// TRANSCRIPTION SUMMARY METHODS
|
|
609
|
+
// ======================
|
|
610
|
+
|
|
611
|
+
public async getTranscriptionSummaries(): Promise<TranscriptionSummary[]> {
|
|
612
|
+
return this.request<TranscriptionSummary[]>(urls.transcriptionSummaries, 'GET');
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
public async getTranscriptionSummary(id: string): Promise<TranscriptionSummary> {
|
|
616
|
+
return this.request<TranscriptionSummary>(`${urls.transcriptionSummaries}/${id}`, 'GET');
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
public async getTranscriptionSummariesByUser(userId: string): Promise<TranscriptionSummary[]> {
|
|
620
|
+
return this.request<TranscriptionSummary[]>(`${urls.transcriptionSummaries}/user/${userId}`, 'GET');
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
public async deleteTranscriptionSummary(id: string): Promise<void> {
|
|
624
|
+
await this.request(`${urls.transcriptionSummaries}/${id}`, 'DELETE');
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// ======================
|
|
628
|
+
// ENHANCED TEAM ROLE METHODS
|
|
629
|
+
// ======================
|
|
630
|
+
|
|
631
|
+
public async removeUserFromTeamFixed(teamId: string, userId: string): Promise<void> {
|
|
632
|
+
await this.request(`${urls.teamRoles}/user/${userId}/team/${teamId}`, 'DELETE');
|
|
633
|
+
}
|
|
634
|
+
|
|
437
635
|
}
|
package/src/sdk/types.ts
CHANGED
|
@@ -62,7 +62,7 @@ export interface User {
|
|
|
62
62
|
// Login response type
|
|
63
63
|
export interface LoginResponse {
|
|
64
64
|
access_token: string;
|
|
65
|
-
|
|
65
|
+
refresh_token: string;
|
|
66
66
|
user: User;
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -276,12 +276,50 @@ export interface Team {
|
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
export interface TranscriptionAudioUploadResponse {
|
|
279
|
-
success:
|
|
280
|
-
transcription: string
|
|
281
|
-
model_version: string
|
|
282
|
-
metadata: any[]
|
|
283
|
-
duration: number
|
|
284
|
-
log: string
|
|
279
|
+
success: boolean;
|
|
280
|
+
transcription: string;
|
|
281
|
+
model_version: string;
|
|
282
|
+
metadata: any[];
|
|
283
|
+
duration: number;
|
|
284
|
+
log: string;
|
|
285
285
|
}
|
|
286
286
|
|
|
287
|
+
// Additional DTOs for missing functionality
|
|
288
|
+
export interface CreateOrganizationDto {
|
|
289
|
+
name: string;
|
|
290
|
+
description?: string;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export interface UpdateOrganizationDto {
|
|
294
|
+
name?: string;
|
|
295
|
+
description?: string;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export interface CreateTemplateCategoryDto {
|
|
299
|
+
name: string;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export interface UpdateTemplateCategoryDto {
|
|
303
|
+
name?: string;
|
|
304
|
+
}
|
|
287
305
|
|
|
306
|
+
export interface CreateTranscriptionSummaryDto {
|
|
307
|
+
userId: string;
|
|
308
|
+
templateId: string;
|
|
309
|
+
content: string;
|
|
310
|
+
anonymisedTranscript?: string;
|
|
311
|
+
metadata?: Record<string, any>;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export interface AssignTeamTemplateDto {
|
|
315
|
+
teamId: string;
|
|
316
|
+
templateId: string;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Enum for global role types to match API
|
|
320
|
+
export enum RoleType {
|
|
321
|
+
SUPERUSER = 'SUPERUSER',
|
|
322
|
+
ADMIN = 'ADMIN',
|
|
323
|
+
TRIAL = 'TRIAL',
|
|
324
|
+
PAID = 'PAID',
|
|
325
|
+
}
|
package/src/sdk/urls.ts
CHANGED
|
@@ -1,24 +1,40 @@
|
|
|
1
1
|
const urls = {
|
|
2
|
+
// Auth
|
|
2
3
|
login: '/auth/login',
|
|
4
|
+
profile: '/auth/profile',
|
|
3
5
|
register: '/auth/register',
|
|
4
6
|
refreshToken: '/auth/refresh-token',
|
|
5
7
|
logout: '/auth/logout',
|
|
8
|
+
|
|
9
|
+
// Users
|
|
6
10
|
user: '/users',
|
|
7
11
|
users: '/users',
|
|
8
|
-
|
|
9
|
-
|
|
12
|
+
|
|
13
|
+
// Organizations
|
|
10
14
|
organizations: '/organizations',
|
|
11
15
|
organizationRoles: '/organization-roles',
|
|
12
|
-
|
|
16
|
+
userOrganizationRoles: '/user-organization-roles',
|
|
17
|
+
|
|
18
|
+
// Teams
|
|
19
|
+
teams: '/teams',
|
|
13
20
|
teamRoles: '/team-roles',
|
|
21
|
+
teamTemplates: '/team-templates',
|
|
22
|
+
|
|
23
|
+
// Templates
|
|
14
24
|
templates: '/templates',
|
|
15
|
-
|
|
25
|
+
templateCategories: '/template-categories',
|
|
16
26
|
userTemplates: '/user-templates',
|
|
17
|
-
|
|
27
|
+
|
|
28
|
+
// Transcription Summaries
|
|
29
|
+
transcriptionSummaries: '/transcription-summaries',
|
|
18
30
|
transcriptionSummary: '/transcription-summaries/generate',
|
|
19
31
|
uploadAudioLarge: '/transcription-summaries/upload-audio-large',
|
|
20
32
|
uploadAudio: '/transcription-summaries/upload-audio',
|
|
21
33
|
transcribeBase64Audio: '/transcription-summaries/transcribe-base64',
|
|
34
|
+
|
|
35
|
+
// Roles
|
|
36
|
+
roles: '/roles',
|
|
37
|
+
userRoles: '/user-roles',
|
|
22
38
|
}
|
|
23
39
|
|
|
24
40
|
export default urls;
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
// Comprehensive SDK test against localhost:3000
|
|
2
|
+
import { ApiSDK } from './dist/index.js';
|
|
3
|
+
|
|
4
|
+
class TestStorage {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.storage = new Map();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async getItem(key) {
|
|
10
|
+
return this.storage.get(key) || null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async setItem(key, value) {
|
|
14
|
+
this.storage.set(key, value);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async removeItem(key) {
|
|
18
|
+
this.storage.delete(key);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function runTests() {
|
|
23
|
+
console.log('š§Ŗ Starting comprehensive SDK tests against localhost:3000\n');
|
|
24
|
+
|
|
25
|
+
const storage = new TestStorage();
|
|
26
|
+
const sdk = new ApiSDK({
|
|
27
|
+
baseUrl: 'http://localhost:3000',
|
|
28
|
+
storage
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
let testResults = {
|
|
32
|
+
passed: 0,
|
|
33
|
+
failed: 0,
|
|
34
|
+
errors: []
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
async function test(name, testFn) {
|
|
38
|
+
try {
|
|
39
|
+
console.log(`š Testing: ${name}`);
|
|
40
|
+
await testFn();
|
|
41
|
+
console.log(`ā
${name} - PASSED\n`);
|
|
42
|
+
testResults.passed++;
|
|
43
|
+
} catch (error) {
|
|
44
|
+
console.log(`ā ${name} - FAILED: ${error.message}\n`);
|
|
45
|
+
testResults.failed++;
|
|
46
|
+
testResults.errors.push({ test: name, error: error.message });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Test authentication
|
|
51
|
+
await test('Login with credentials', async () => {
|
|
52
|
+
const response = await sdk.login({
|
|
53
|
+
email: 'test@example.com',
|
|
54
|
+
password: 'password'
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (!response.access_token) throw new Error('No access token returned');
|
|
58
|
+
if (!response.user) throw new Error('No user returned');
|
|
59
|
+
console.log(` User: ${response.user.firstName} ${response.user.lastName}`);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
await test('Check authentication status', async () => {
|
|
63
|
+
const isAuth = sdk.isAuthenticated();
|
|
64
|
+
if (!isAuth) throw new Error('Should be authenticated after login');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
await test('Get current user', async () => {
|
|
68
|
+
const user = sdk.getCurrentUser();
|
|
69
|
+
if (!user) throw new Error('Current user should be available');
|
|
70
|
+
console.log(` Current user: ${user.firstName} ${user.lastName}`);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
await test('Get profile', async () => {
|
|
74
|
+
const profile = await sdk.getProfile();
|
|
75
|
+
if (!profile.id) throw new Error('Profile should have ID');
|
|
76
|
+
console.log(` Profile ID: ${profile.id}`);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Test organization methods
|
|
80
|
+
await test('Get organizations', async () => {
|
|
81
|
+
const orgs = await sdk.getOrganizations();
|
|
82
|
+
if (!Array.isArray(orgs)) throw new Error('Should return array of organizations');
|
|
83
|
+
console.log(` Found ${orgs.length} organizations`);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
await test('Get current organization', async () => {
|
|
87
|
+
const user = sdk.getCurrentUser();
|
|
88
|
+
const org = await sdk.getOrganization(user.organizationId);
|
|
89
|
+
if (!org.id) throw new Error('Organization should have ID');
|
|
90
|
+
console.log(` Organization: ${org.name}`);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Test user methods
|
|
94
|
+
await test('Get users', async () => {
|
|
95
|
+
const users = await sdk.getUsers();
|
|
96
|
+
if (!Array.isArray(users)) throw new Error('Should return array of users');
|
|
97
|
+
console.log(` Found ${users.length} users`);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
await test('Get users by organization', async () => {
|
|
101
|
+
const user = sdk.getCurrentUser();
|
|
102
|
+
const users = await sdk.getUsersByOrganization(user.organizationId);
|
|
103
|
+
if (!Array.isArray(users)) throw new Error('Should return array of users');
|
|
104
|
+
console.log(` Found ${users.length} users in organization`);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Test team methods
|
|
108
|
+
await test('Get teams', async () => {
|
|
109
|
+
const teams = await sdk.getTeams();
|
|
110
|
+
if (!Array.isArray(teams)) throw new Error('Should return array of teams');
|
|
111
|
+
console.log(` Found ${teams.length} teams`);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
await test('Create team', async () => {
|
|
115
|
+
const team = await sdk.createTeam('Test Team', 'A test team for SDK testing');
|
|
116
|
+
if (!team.id) throw new Error('Created team should have ID');
|
|
117
|
+
console.log(` Created team: ${team.name} (ID: ${team.id})`);
|
|
118
|
+
|
|
119
|
+
// Store team ID for cleanup
|
|
120
|
+
global.testTeamId = team.id;
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Test template category methods
|
|
124
|
+
await test('Get template categories', async () => {
|
|
125
|
+
const categories = await sdk.getTemplateCategories();
|
|
126
|
+
if (!Array.isArray(categories)) throw new Error('Should return array of categories');
|
|
127
|
+
console.log(` Found ${categories.length} template categories`);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
await test('Create template category', async () => {
|
|
131
|
+
const category = await sdk.createTemplateCategory('Test Category');
|
|
132
|
+
if (!category.id) throw new Error('Created category should have ID');
|
|
133
|
+
console.log(` Created category: ${category.name} (ID: ${category.id})`);
|
|
134
|
+
|
|
135
|
+
global.testCategoryId = category.id;
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// Test template methods
|
|
139
|
+
await test('Get templates', async () => {
|
|
140
|
+
const templates = await sdk.getTemplates();
|
|
141
|
+
if (!Array.isArray(templates)) throw new Error('Should return array of templates');
|
|
142
|
+
console.log(` Found ${templates.length} templates`);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
await test('Create template', async () => {
|
|
146
|
+
const template = await sdk.createTemplate(
|
|
147
|
+
'Test Template',
|
|
148
|
+
'This is a test template content',
|
|
149
|
+
global.testCategoryId
|
|
150
|
+
);
|
|
151
|
+
if (!template.id) throw new Error('Created template should have ID');
|
|
152
|
+
console.log(` Created template: ${template.title} (ID: ${template.id})`);
|
|
153
|
+
|
|
154
|
+
global.testTemplateId = template.id;
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
await test('Update template', async () => {
|
|
158
|
+
const updated = await sdk.updateTemplate(
|
|
159
|
+
'Updated Test Template',
|
|
160
|
+
'Updated test template content',
|
|
161
|
+
global.testTemplateId
|
|
162
|
+
);
|
|
163
|
+
if (updated.title !== 'Updated Test Template') {
|
|
164
|
+
throw new Error('Template title should be updated');
|
|
165
|
+
}
|
|
166
|
+
console.log(` Updated template title: ${updated.title}`);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Test user template methods
|
|
170
|
+
await test('Get user templates', async () => {
|
|
171
|
+
const userTemplates = await sdk.getUserTemplates();
|
|
172
|
+
if (!Array.isArray(userTemplates)) throw new Error('Should return array of user templates');
|
|
173
|
+
console.log(` Found ${userTemplates.length} user templates`);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
await test('Create user template', async () => {
|
|
177
|
+
const userTemplate = await sdk.createUserTemplate(
|
|
178
|
+
'Test User Template',
|
|
179
|
+
'This is a test user template',
|
|
180
|
+
global.testTemplateId
|
|
181
|
+
);
|
|
182
|
+
if (!userTemplate.id) throw new Error('Created user template should have ID');
|
|
183
|
+
console.log(` Created user template: ${userTemplate.title} (ID: ${userTemplate.id})`);
|
|
184
|
+
|
|
185
|
+
global.testUserTemplateId = userTemplate.id;
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Test transcription summary methods
|
|
189
|
+
await test('Get transcription summaries', async () => {
|
|
190
|
+
const summaries = await sdk.getTranscriptionSummaries();
|
|
191
|
+
if (!Array.isArray(summaries)) throw new Error('Should return array of summaries');
|
|
192
|
+
console.log(` Found ${summaries.length} transcription summaries`);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
await test('Generate transcription summary', async () => {
|
|
196
|
+
const summary = await sdk.generateTranscriptionSummary(
|
|
197
|
+
'This is a test transcript for testing purposes',
|
|
198
|
+
global.testTemplateId
|
|
199
|
+
);
|
|
200
|
+
if (!summary.id) throw new Error('Generated summary should have ID');
|
|
201
|
+
console.log(` Generated summary (ID: ${summary.id})`);
|
|
202
|
+
|
|
203
|
+
global.testSummaryId = summary.id;
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
await test('Update transcription summary', async () => {
|
|
207
|
+
const updated = await sdk.updateTranscriptionSummary(
|
|
208
|
+
global.testSummaryId,
|
|
209
|
+
'Updated summary content'
|
|
210
|
+
);
|
|
211
|
+
if (updated.content !== 'Updated summary content') {
|
|
212
|
+
throw new Error('Summary content should be updated');
|
|
213
|
+
}
|
|
214
|
+
console.log(` Updated summary content`);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// Test audio upload (mock file)
|
|
218
|
+
await test('Upload audio file', async () => {
|
|
219
|
+
const formData = new FormData();
|
|
220
|
+
const blob = new Blob(['fake audio data'], { type: 'audio/wav' });
|
|
221
|
+
formData.append('audio', blob, 'test.wav');
|
|
222
|
+
|
|
223
|
+
try {
|
|
224
|
+
const result = await sdk.uploadAudioFile(formData);
|
|
225
|
+
console.log(` Upload result: ${result ? 'Success' : 'No response'}`);
|
|
226
|
+
} catch (error) {
|
|
227
|
+
if (error.message.includes('413') || error.message.includes('file')) {
|
|
228
|
+
console.log(` Upload failed as expected (file validation): ${error.message}`);
|
|
229
|
+
} else {
|
|
230
|
+
throw error;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// Test base64 audio transcription
|
|
236
|
+
await test('Transcribe base64 audio', async () => {
|
|
237
|
+
try {
|
|
238
|
+
const transcript = await sdk.transcribeBase64Audio('fake-base64-audio-data');
|
|
239
|
+
console.log(` Transcript: ${transcript}`);
|
|
240
|
+
} catch (error) {
|
|
241
|
+
if (error.message.includes('400') || error.message.includes('base64')) {
|
|
242
|
+
console.log(` Transcription failed as expected (invalid base64): ${error.message}`);
|
|
243
|
+
} else {
|
|
244
|
+
throw error;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// Test logout
|
|
250
|
+
await test('Logout', async () => {
|
|
251
|
+
await sdk.logout();
|
|
252
|
+
const isAuth = sdk.isAuthenticated();
|
|
253
|
+
if (isAuth) throw new Error('Should not be authenticated after logout');
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// Print test results
|
|
257
|
+
console.log('\nš Test Results:');
|
|
258
|
+
console.log(`ā
Passed: ${testResults.passed}`);
|
|
259
|
+
console.log(`ā Failed: ${testResults.failed}`);
|
|
260
|
+
console.log(`š Success Rate: ${((testResults.passed / (testResults.passed + testResults.failed)) * 100).toFixed(1)}%`);
|
|
261
|
+
|
|
262
|
+
if (testResults.errors.length > 0) {
|
|
263
|
+
console.log('\nš„ Errors:');
|
|
264
|
+
testResults.errors.forEach(({ test, error }) => {
|
|
265
|
+
console.log(` ${test}: ${error}`);
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Handle process termination
|
|
271
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
272
|
+
console.log('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// Run the tests
|
|
276
|
+
runTests().catch(console.error);
|