tale-js-sdk 0.1.4 → 1.1.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.
@@ -1,2 +1,1123 @@
1
- // 导出 RBAC 功能函数,使用命名空间避免与现有模块冲突
2
- export * as rbac from './rbac.js';
1
+ import { getAppToken } from "../token.js";
2
+ import { ApiError, ConfigurationError, NetworkError } from "../errors.js";
3
+ // ==================== Role Management ====================
4
+ /**
5
+ * Gets a role by ID.
6
+ *
7
+ * @param roleId - Role ID
8
+ * @param options - Optional configuration
9
+ * @returns Promise resolving to role information
10
+ * @throws {ConfigurationError} When required environment variables are missing
11
+ * @throws {ApiError} When API request fails
12
+ * @throws {NetworkError} When network request fails
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { getRole } from '@tale/client';
17
+ *
18
+ * try {
19
+ * const role = await getRole('role_id_here');
20
+ * console.log('Role name:', role.role_name);
21
+ * } catch (error) {
22
+ * console.error('Failed to get role:', error.message);
23
+ * }
24
+ * ```
25
+ */
26
+ export async function getRole(roleId, options) {
27
+ if (!roleId || roleId.trim() === "") {
28
+ throw new ApiError("role_id is required", 400, "9400");
29
+ }
30
+ const token = options?.appToken ?? (await getAppToken(options));
31
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
32
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
33
+ if (!base) {
34
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
35
+ }
36
+ const url = String(base).replace(/\/+$/, "") +
37
+ `/rbac/v1/roles/${encodeURIComponent(roleId)}`;
38
+ let response;
39
+ try {
40
+ response = await globalThis.fetch(url, {
41
+ method: "GET",
42
+ headers: {
43
+ "Content-Type": "application/json",
44
+ "x-t-token": token,
45
+ },
46
+ });
47
+ }
48
+ catch (error) {
49
+ throw new NetworkError(`Failed to get role: ${error instanceof Error ? error.message : "Unknown error"}`);
50
+ }
51
+ const json = (await response.json());
52
+ if (json.code !== 200) {
53
+ const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to get role";
54
+ throw new ApiError(errorMsg, response.status, json.code);
55
+ }
56
+ if (!json.data) {
57
+ throw new ApiError("Invalid role response: missing data", response.status);
58
+ }
59
+ return json.data;
60
+ }
61
+ /**
62
+ * Lists roles with pagination and optional filtering.
63
+ *
64
+ * @param options - Optional parameters for pagination and filtering
65
+ * @returns Promise resolving to paginated role list
66
+ * @throws {ConfigurationError} When required environment variables are missing
67
+ * @throws {ApiError} When API request fails
68
+ * @throws {NetworkError} When network request fails
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * import { listRoles } from '@tale/client';
73
+ *
74
+ * try {
75
+ * const result = await listRoles({
76
+ * page: 0,
77
+ * size: 20,
78
+ * role_type: 'admin'
79
+ * });
80
+ * console.log(`Found ${result.totalElements} roles`);
81
+ * } catch (error) {
82
+ * console.error('Failed to list roles:', error.message);
83
+ * }
84
+ * ```
85
+ */
86
+ export async function listRoles(options) {
87
+ const token = options?.appToken ?? (await getAppToken(options));
88
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
89
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
90
+ if (!base) {
91
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
92
+ }
93
+ const url = new URL(String(base).replace(/\/+$/, "") + "/rbac/v1/roles");
94
+ const queryParams = {
95
+ page: 0,
96
+ size: 20,
97
+ sort_by: "createdAt",
98
+ sort_direction: "desc",
99
+ ...options,
100
+ };
101
+ Object.entries(queryParams).forEach(([key, value]) => {
102
+ if (value !== undefined) {
103
+ url.searchParams.append(key, String(value));
104
+ }
105
+ });
106
+ let response;
107
+ try {
108
+ response = await globalThis.fetch(url.toString(), {
109
+ method: "GET",
110
+ headers: {
111
+ "Content-Type": "application/json",
112
+ "x-t-token": token,
113
+ },
114
+ });
115
+ }
116
+ catch (error) {
117
+ throw new NetworkError(`Failed to list roles: ${error instanceof Error ? error.message : "Unknown error"}`);
118
+ }
119
+ const json = (await response.json());
120
+ if (json.code !== 200) {
121
+ const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to list roles";
122
+ throw new ApiError(errorMsg, response.status, json.code);
123
+ }
124
+ if (!json.data || !Array.isArray(json.data.content)) {
125
+ throw new ApiError("Invalid roles response: missing data", response.status);
126
+ }
127
+ return json.data;
128
+ }
129
+ /**
130
+ * Creates a new role.
131
+ *
132
+ * @param request - Role creation request
133
+ * @param options - Optional configuration
134
+ * @returns Promise resolving to created role
135
+ * @throws {ConfigurationError} When required environment variables are missing
136
+ * @throws {ApiError} When API request fails
137
+ * @throws {NetworkError} When network request fails
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * import { createRole } from '@tale/client';
142
+ *
143
+ * try {
144
+ * const role = await createRole({
145
+ * roleName: 'Administrator',
146
+ * role_type: 'admin',
147
+ * privilege_ids: ['priv1', 'priv2']
148
+ * });
149
+ * console.log('Role created:', role.role_id);
150
+ * } catch (error) {
151
+ * console.error('Failed to create role:', error.message);
152
+ * }
153
+ * ```
154
+ */
155
+ export async function createRole(request, options) {
156
+ if (!request.role_name || request.role_name.trim() === "") {
157
+ throw new ApiError("role_name is required", 400, "9400");
158
+ }
159
+ const token = options?.appToken ?? (await getAppToken(options));
160
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
161
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
162
+ if (!base) {
163
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
164
+ }
165
+ const url = String(base).replace(/\/+$/, "") + "/rbac/v1/roles";
166
+ let response;
167
+ try {
168
+ response = await globalThis.fetch(url, {
169
+ method: "POST",
170
+ headers: {
171
+ "Content-Type": "application/json",
172
+ "x-t-token": token,
173
+ },
174
+ body: JSON.stringify(request),
175
+ });
176
+ }
177
+ catch (error) {
178
+ throw new NetworkError(`Failed to create role: ${error instanceof Error ? error.message : "Unknown error"}`);
179
+ }
180
+ const json = (await response.json());
181
+ if (json.code !== 200) {
182
+ const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to create role";
183
+ throw new ApiError(errorMsg, response.status, json.code);
184
+ }
185
+ if (!json.data) {
186
+ throw new ApiError("Invalid role creation response: missing data", response.status);
187
+ }
188
+ return json.data;
189
+ }
190
+ /**
191
+ * Updates an existing role.
192
+ *
193
+ * @param roleId - Role ID to update
194
+ * @param request - Update request with fields to modify
195
+ * @param options - Optional configuration
196
+ * @returns Promise resolving to updated role
197
+ * @throws {ConfigurationError} When required environment variables are missing
198
+ * @throws {ApiError} When API request fails
199
+ * @throws {NetworkError} When network request fails
200
+ *
201
+ * @example
202
+ * ```typescript
203
+ * import { updateRole } from '@tale/client';
204
+ *
205
+ * try {
206
+ * const role = await updateRole('role_id_here', {
207
+ * roleName: 'Updated Role Name',
208
+ * remark: 'Updated description'
209
+ * });
210
+ * console.log('Role updated:', role.role_name);
211
+ * } catch (error) {
212
+ * console.error('Failed to update role:', error.message);
213
+ * }
214
+ * ```
215
+ */
216
+ export async function updateRole(roleId, request, options) {
217
+ if (!roleId || roleId.trim() === "") {
218
+ throw new ApiError("role_id is required", 400, "9400");
219
+ }
220
+ const token = options?.appToken ?? (await getAppToken(options));
221
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
222
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
223
+ if (!base) {
224
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
225
+ }
226
+ const url = String(base).replace(/\/+$/, "") +
227
+ `/rbac/v1/roles/${encodeURIComponent(roleId)}`;
228
+ let response;
229
+ try {
230
+ response = await globalThis.fetch(url, {
231
+ method: "PUT",
232
+ headers: {
233
+ "Content-Type": "application/json",
234
+ "x-t-token": token,
235
+ },
236
+ body: JSON.stringify(request),
237
+ });
238
+ }
239
+ catch (error) {
240
+ throw new NetworkError(`Failed to update role: ${error instanceof Error ? error.message : "Unknown error"}`);
241
+ }
242
+ const json = (await response.json());
243
+ if (json.code !== 200) {
244
+ const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to update role";
245
+ throw new ApiError(errorMsg, response.status, json.code);
246
+ }
247
+ if (!json.data) {
248
+ throw new ApiError("Invalid role update response: missing data", response.status);
249
+ }
250
+ return json.data;
251
+ }
252
+ /**
253
+ * Deletes a role.
254
+ *
255
+ * @param roleId - Role ID to delete
256
+ * @param options - Optional configuration
257
+ * @returns Promise that resolves when deletion is successful
258
+ * @throws {ConfigurationError} When required environment variables are missing
259
+ * @throws {ApiError} When API request fails
260
+ * @throws {NetworkError} When network request fails
261
+ *
262
+ * @example
263
+ * ```typescript
264
+ * import { deleteRole } from '@tale/client';
265
+ *
266
+ * try {
267
+ * await deleteRole('role_id_here');
268
+ * console.log('Role deleted successfully');
269
+ * } catch (error) {
270
+ * console.error('Failed to delete role:', error.message);
271
+ * }
272
+ * ```
273
+ */
274
+ export async function deleteRole(roleId, options) {
275
+ if (!roleId || roleId.trim() === "") {
276
+ throw new ApiError("role_id is required", 400, "9400");
277
+ }
278
+ const token = options?.appToken ?? (await getAppToken(options));
279
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
280
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
281
+ if (!base) {
282
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
283
+ }
284
+ const url = String(base).replace(/\/+$/, "") +
285
+ `/rbac/v1/roles/${encodeURIComponent(roleId)}`;
286
+ let response;
287
+ try {
288
+ response = await globalThis.fetch(url, {
289
+ method: "DELETE",
290
+ headers: {
291
+ "Content-Type": "application/json",
292
+ "x-t-token": token,
293
+ },
294
+ });
295
+ }
296
+ catch (error) {
297
+ throw new NetworkError(`Failed to delete role: ${error instanceof Error ? error.message : "Unknown error"}`);
298
+ }
299
+ const json = (await response.json());
300
+ if (json.code !== 200) {
301
+ const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to delete role";
302
+ throw new ApiError(errorMsg, response.status, json.code);
303
+ }
304
+ }
305
+ // ==================== Privilege Management ====================
306
+ /**
307
+ * Gets a privilege by ID.
308
+ *
309
+ * @param privilegeId - Privilege ID
310
+ * @param options - Optional configuration
311
+ * @returns Promise resolving to privilege information
312
+ * @throws {ConfigurationError} When required environment variables are missing
313
+ * @throws {ApiError} When API request fails
314
+ * @throws {NetworkError} When network request fails
315
+ *
316
+ * @example
317
+ * ```typescript
318
+ * import { getPrivilege } from '@tale/client';
319
+ *
320
+ * try {
321
+ * const privilege = await getPrivilege('privilege_id_here');
322
+ * console.log('Privilege name:', privilege.privilege_name);
323
+ * } catch (error) {
324
+ * console.error('Failed to get privilege:', error.message);
325
+ * }
326
+ * ```
327
+ */
328
+ export async function getPrivilege(privilegeId, options) {
329
+ if (!privilegeId || privilegeId.trim() === "") {
330
+ throw new ApiError("privilege_id is required", 400, "9400");
331
+ }
332
+ const token = options?.appToken ?? (await getAppToken(options));
333
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
334
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
335
+ if (!base) {
336
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
337
+ }
338
+ const url = String(base).replace(/\/+$/, "") +
339
+ `/rbac/v1/privileges/${encodeURIComponent(privilegeId)}`;
340
+ let response;
341
+ try {
342
+ response = await globalThis.fetch(url, {
343
+ method: "GET",
344
+ headers: {
345
+ "Content-Type": "application/json",
346
+ "x-t-token": token,
347
+ },
348
+ });
349
+ }
350
+ catch (error) {
351
+ throw new NetworkError(`Failed to get privilege: ${error instanceof Error ? error.message : "Unknown error"}`);
352
+ }
353
+ const json = (await response.json());
354
+ if (json.code !== 200) {
355
+ const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to get privilege";
356
+ throw new ApiError(errorMsg, response.status, json.code);
357
+ }
358
+ if (!json.data) {
359
+ throw new ApiError("Invalid privilege response: missing data", response.status);
360
+ }
361
+ return json.data;
362
+ }
363
+ /**
364
+ * Lists privileges with pagination and optional filtering.
365
+ *
366
+ * @param options - Optional parameters for pagination and filtering
367
+ * @returns Promise resolving to paginated privilege list
368
+ * @throws {ConfigurationError} When required environment variables are missing
369
+ * @throws {ApiError} When API request fails
370
+ * @throws {NetworkError} When network request fails
371
+ *
372
+ * @example
373
+ * ```typescript
374
+ * import { listPrivileges } from '@tale/client';
375
+ *
376
+ * try {
377
+ * const result = await listPrivileges({
378
+ * page: 0,
379
+ * size: 20,
380
+ * privilege_type: 'read'
381
+ * });
382
+ * console.log(`Found ${result.totalElements} privileges`);
383
+ * } catch (error) {
384
+ * console.error('Failed to list privileges:', error.message);
385
+ * }
386
+ * ```
387
+ */
388
+ export async function listPrivileges(options) {
389
+ const token = options?.appToken ?? (await getAppToken(options));
390
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
391
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
392
+ if (!base) {
393
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
394
+ }
395
+ const url = new URL(String(base).replace(/\/+$/, "") + "/rbac/v1/privileges");
396
+ const queryParams = {
397
+ page: 0,
398
+ size: 20,
399
+ sort_by: "createdAt",
400
+ sort_direction: "desc",
401
+ ...options,
402
+ };
403
+ Object.entries(queryParams).forEach(([key, value]) => {
404
+ if (value !== undefined) {
405
+ url.searchParams.append(key, String(value));
406
+ }
407
+ });
408
+ let response;
409
+ try {
410
+ response = await globalThis.fetch(url.toString(), {
411
+ method: "GET",
412
+ headers: {
413
+ "Content-Type": "application/json",
414
+ "x-t-token": token,
415
+ },
416
+ });
417
+ }
418
+ catch (error) {
419
+ throw new NetworkError(`Failed to list privileges: ${error instanceof Error ? error.message : "Unknown error"}`);
420
+ }
421
+ const json = (await response.json());
422
+ if (json.code !== 200) {
423
+ const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to list privileges";
424
+ throw new ApiError(errorMsg, response.status, json.code);
425
+ }
426
+ if (!json.data || !Array.isArray(json.data.content)) {
427
+ throw new ApiError("Invalid privileges response: missing data", response.status);
428
+ }
429
+ return json.data;
430
+ }
431
+ /**
432
+ * Creates a new privilege.
433
+ *
434
+ * @param request - Privilege creation request
435
+ * @param options - Optional configuration
436
+ * @returns Promise resolving to created privilege
437
+ * @throws {ConfigurationError} When required environment variables are missing
438
+ * @throws {ApiError} When API request fails
439
+ * @throws {NetworkError} When network request fails
440
+ *
441
+ * @example
442
+ * ```typescript
443
+ * import { createPrivilege } from '@tale/client';
444
+ *
445
+ * try {
446
+ * const privilege = await createPrivilege({
447
+ * privilegeName: 'read_posts',
448
+ * privilege_type: 'read',
449
+ * resourceIds: ['posts']
450
+ * });
451
+ * console.log('Privilege created:', privilege.privilege_id);
452
+ * } catch (error) {
453
+ * console.error('Failed to create privilege:', error.message);
454
+ * }
455
+ * ```
456
+ */
457
+ export async function createPrivilege(request, options) {
458
+ if (!request.privilege_name || request.privilege_name.trim() === "") {
459
+ throw new ApiError("privilege_name is required", 400, "9400");
460
+ }
461
+ const token = options?.appToken ?? (await getAppToken(options));
462
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
463
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
464
+ if (!base) {
465
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
466
+ }
467
+ const url = String(base).replace(/\/+$/, "") + "/rbac/v1/privileges";
468
+ let response;
469
+ try {
470
+ response = await globalThis.fetch(url, {
471
+ method: "POST",
472
+ headers: {
473
+ "Content-Type": "application/json",
474
+ "x-t-token": token,
475
+ },
476
+ body: JSON.stringify(request),
477
+ });
478
+ }
479
+ catch (error) {
480
+ throw new NetworkError(`Failed to create privilege: ${error instanceof Error ? error.message : "Unknown error"}`);
481
+ }
482
+ const json = (await response.json());
483
+ if (json.code !== 200) {
484
+ const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to create privilege";
485
+ throw new ApiError(errorMsg, response.status, json.code);
486
+ }
487
+ if (!json.data) {
488
+ throw new ApiError("Invalid privilege creation response: missing data", response.status);
489
+ }
490
+ return json.data;
491
+ }
492
+ /**
493
+ * Updates an existing privilege.
494
+ *
495
+ * @param privilegeId - Privilege ID to update
496
+ * @param request - Update request with fields to modify
497
+ * @param options - Optional configuration
498
+ * @returns Promise resolving to updated privilege
499
+ * @throws {ConfigurationError} When required environment variables are missing
500
+ * @throws {ApiError} When API request fails
501
+ * @throws {NetworkError} When network request fails
502
+ *
503
+ * @example
504
+ * ```typescript
505
+ * import { updatePrivilege } from '@tale/client';
506
+ *
507
+ * try {
508
+ * const privilege = await updatePrivilege('privilege_id_here', {
509
+ * privilegeName: 'updated_name',
510
+ * remark: 'Updated description'
511
+ * });
512
+ * console.log('Privilege updated:', privilege.privilege_name);
513
+ * } catch (error) {
514
+ * console.error('Failed to update privilege:', error.message);
515
+ * }
516
+ * ```
517
+ */
518
+ export async function updatePrivilege(privilegeId, request, options) {
519
+ if (!privilegeId || privilegeId.trim() === "") {
520
+ throw new ApiError("privilege_id is required", 400, "9400");
521
+ }
522
+ const token = options?.appToken ?? (await getAppToken(options));
523
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
524
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
525
+ if (!base) {
526
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
527
+ }
528
+ const url = String(base).replace(/\/+$/, "") +
529
+ `/rbac/v1/privileges/${encodeURIComponent(privilegeId)}`;
530
+ let response;
531
+ try {
532
+ response = await globalThis.fetch(url, {
533
+ method: "PUT",
534
+ headers: {
535
+ "Content-Type": "application/json",
536
+ "x-t-token": token,
537
+ },
538
+ body: JSON.stringify(request),
539
+ });
540
+ }
541
+ catch (error) {
542
+ throw new NetworkError(`Failed to update privilege: ${error instanceof Error ? error.message : "Unknown error"}`);
543
+ }
544
+ const json = (await response.json());
545
+ if (json.code !== 200) {
546
+ const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to update privilege";
547
+ throw new ApiError(errorMsg, response.status, json.code);
548
+ }
549
+ if (!json.data) {
550
+ throw new ApiError("Invalid privilege update response: missing data", response.status);
551
+ }
552
+ return json.data;
553
+ }
554
+ /**
555
+ * Deletes a privilege.
556
+ *
557
+ * @param privilegeId - Privilege ID to delete
558
+ * @param options - Optional configuration
559
+ * @returns Promise that resolves when deletion is successful
560
+ * @throws {ConfigurationError} When required environment variables are missing
561
+ * @throws {ApiError} When API request fails
562
+ * @throws {NetworkError} When network request fails
563
+ *
564
+ * @example
565
+ * ```typescript
566
+ * import { deletePrivilege } from '@tale/client';
567
+ *
568
+ * try {
569
+ * await deletePrivilege('privilege_id_here');
570
+ * console.log('Privilege deleted successfully');
571
+ * } catch (error) {
572
+ * console.error('Failed to delete privilege:', error.message);
573
+ * }
574
+ * ```
575
+ */
576
+ export async function deletePrivilege(privilegeId, options) {
577
+ if (!privilegeId || privilegeId.trim() === "") {
578
+ throw new ApiError("privilege_id is required", 400, "9400");
579
+ }
580
+ const token = options?.appToken ?? (await getAppToken(options));
581
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
582
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
583
+ if (!base) {
584
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
585
+ }
586
+ const url = String(base).replace(/\/+$/, "") +
587
+ `/rbac/v1/privileges/${encodeURIComponent(privilegeId)}`;
588
+ let response;
589
+ try {
590
+ response = await globalThis.fetch(url, {
591
+ method: "DELETE",
592
+ headers: {
593
+ "Content-Type": "application/json",
594
+ "x-t-token": token,
595
+ },
596
+ });
597
+ }
598
+ catch (error) {
599
+ throw new NetworkError(`Failed to delete privilege: ${error instanceof Error ? error.message : "Unknown error"}`);
600
+ }
601
+ const json = (await response.json());
602
+ if (json.code !== 200) {
603
+ const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to delete privilege";
604
+ throw new ApiError(errorMsg, response.status, json.code);
605
+ }
606
+ }
607
+ // ==================== User Role Management ====================
608
+ /**
609
+ * Gets roles assigned to a user.
610
+ *
611
+ * @param userId - User ID
612
+ * @param options - Optional configuration
613
+ * @returns Promise resolving to list of user roles
614
+ * @throws {ConfigurationError} When required environment variables are missing
615
+ * @throws {ApiError} When API request fails
616
+ * @throws {NetworkError} When network request fails
617
+ *
618
+ * @example
619
+ * ```typescript
620
+ * import { getUserRoles } from '@tale/client';
621
+ *
622
+ * try {
623
+ * const roles = await getUserRoles('user_id_here');
624
+ * console.log(`User has ${roles.length} roles`);
625
+ * roles.forEach(role => console.log('-', role.role_name));
626
+ * } catch (error) {
627
+ * console.error('Failed to get user roles:', error.message);
628
+ * }
629
+ * ```
630
+ */
631
+ export async function getUserRoles(userId, options) {
632
+ if (!userId || userId.trim() === "") {
633
+ throw new ApiError("user_id is required", 400, "9400");
634
+ }
635
+ const token = options?.appToken ?? (await getAppToken(options));
636
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
637
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
638
+ if (!base) {
639
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
640
+ }
641
+ const url = String(base).replace(/\/+$/, "") +
642
+ `/rbac/v1/user/${encodeURIComponent(userId)}/roles`;
643
+ let response;
644
+ try {
645
+ response = await globalThis.fetch(url, {
646
+ method: "GET",
647
+ headers: {
648
+ "Content-Type": "application/json",
649
+ "x-t-token": token,
650
+ },
651
+ });
652
+ }
653
+ catch (error) {
654
+ throw new NetworkError(`Failed to get user roles: ${error instanceof Error ? error.message : "Unknown error"}`);
655
+ }
656
+ const json = (await response.json());
657
+ if (json.code !== 200) {
658
+ const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to get user roles";
659
+ throw new ApiError(errorMsg, response.status, json.code);
660
+ }
661
+ if (!json.data || !Array.isArray(json.data)) {
662
+ throw new ApiError("Invalid user roles response: missing data", response.status);
663
+ }
664
+ return json.data;
665
+ }
666
+ /**
667
+ * Assigns roles to a user.
668
+ *
669
+ * @param userId - User ID
670
+ * @param request - Request containing role IDs to assign
671
+ * @param options - Optional configuration
672
+ * @returns Promise resolving to list of assigned roles
673
+ * @throws {ConfigurationError} When required environment variables are missing
674
+ * @throws {ApiError} When API request fails
675
+ * @throws {NetworkError} When network request fails
676
+ *
677
+ * @example
678
+ * ```typescript
679
+ * import { assignRolesToUser } from '@tale/client';
680
+ *
681
+ * try {
682
+ * const roles = await assignRolesToUser('user_id_here', {
683
+ * role_ids: ['role1', 'role2']
684
+ * });
685
+ * console.log('Roles assigned successfully');
686
+ * } catch (error) {
687
+ * console.error('Failed to assign roles:', error.message);
688
+ * }
689
+ * ```
690
+ */
691
+ export async function assignRolesToUser(userId, request, options) {
692
+ if (!userId || userId.trim() === "") {
693
+ throw new ApiError("user_id is required", 400, "9400");
694
+ }
695
+ if (!request.role_ids ||
696
+ !Array.isArray(request.role_ids) ||
697
+ request.role_ids.length === 0) {
698
+ throw new ApiError("role_ids is required and must be a non-empty array", 400, "9400");
699
+ }
700
+ const token = options?.appToken ?? (await getAppToken(options));
701
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
702
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
703
+ if (!base) {
704
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
705
+ }
706
+ const url = String(base).replace(/\/+$/, "") +
707
+ `/rbac/v1/user/${encodeURIComponent(userId)}/roles`;
708
+ let response;
709
+ try {
710
+ response = await globalThis.fetch(url, {
711
+ method: "POST",
712
+ headers: {
713
+ "Content-Type": "application/json",
714
+ "x-t-token": token,
715
+ },
716
+ body: JSON.stringify(request),
717
+ });
718
+ }
719
+ catch (error) {
720
+ throw new NetworkError(`Failed to assign roles to user: ${error instanceof Error ? error.message : "Unknown error"}`);
721
+ }
722
+ const json = (await response.json());
723
+ if (json.code !== 200) {
724
+ const errorMsg = typeof json.msg === "string"
725
+ ? json.msg
726
+ : "Failed to assign roles to user";
727
+ throw new ApiError(errorMsg, response.status, json.code);
728
+ }
729
+ if (!json.data || !Array.isArray(json.data)) {
730
+ throw new ApiError("Invalid role assignment response: missing data", response.status);
731
+ }
732
+ return json.data;
733
+ }
734
+ /**
735
+ * Unassigns roles from a user.
736
+ *
737
+ * @param userId - User ID
738
+ * @param request - Request containing role IDs to unassign
739
+ * @param options - Optional configuration
740
+ * @returns Promise that resolves when unassignment is successful
741
+ * @throws {ConfigurationError} When required environment variables are missing
742
+ * @throws {ApiError} When API request fails
743
+ * @throws {NetworkError} When network request fails
744
+ *
745
+ * @example
746
+ * ```typescript
747
+ * import { unassignRolesFromUser } from '@tale/client';
748
+ *
749
+ * try {
750
+ * await unassignRolesFromUser('user_id_here', {
751
+ * role_ids: ['role1', 'role2']
752
+ * });
753
+ * console.log('Roles unassigned successfully');
754
+ * } catch (error) {
755
+ * console.error('Failed to unassign roles:', error.message);
756
+ * }
757
+ * ```
758
+ */
759
+ export async function unassignRolesFromUser(userId, request, options) {
760
+ if (!userId || userId.trim() === "") {
761
+ throw new ApiError("user_id is required", 400, "9400");
762
+ }
763
+ if (!request.role_ids ||
764
+ !Array.isArray(request.role_ids) ||
765
+ request.role_ids.length === 0) {
766
+ throw new ApiError("role_ids is required and must be a non-empty array", 400, "9400");
767
+ }
768
+ const token = options?.appToken ?? (await getAppToken(options));
769
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
770
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
771
+ if (!base) {
772
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
773
+ }
774
+ const url = String(base).replace(/\/+$/, "") +
775
+ `/rbac/v1/user/${encodeURIComponent(userId)}/roles`;
776
+ let response;
777
+ try {
778
+ response = await globalThis.fetch(url, {
779
+ method: "DELETE",
780
+ headers: {
781
+ "Content-Type": "application/json",
782
+ "x-t-token": token,
783
+ },
784
+ body: JSON.stringify(request),
785
+ });
786
+ }
787
+ catch (error) {
788
+ throw new NetworkError(`Failed to unassign roles from user: ${error instanceof Error ? error.message : "Unknown error"}`);
789
+ }
790
+ const json = (await response.json());
791
+ if (json.code !== 200) {
792
+ const errorMsg = typeof json.msg === "string"
793
+ ? json.msg
794
+ : "Failed to unassign roles from user";
795
+ throw new ApiError(errorMsg, response.status, json.code);
796
+ }
797
+ }
798
+ // ==================== User Privilege Management ====================
799
+ /**
800
+ * Gets privileges assigned to a user.
801
+ *
802
+ * @param userId - User ID
803
+ * @param options - Optional configuration
804
+ * @returns Promise resolving to list of user privileges
805
+ * @throws {ConfigurationError} When required environment variables are missing
806
+ * @throws {ApiError} When API request fails
807
+ * @throws {NetworkError} When network request fails
808
+ *
809
+ * @example
810
+ * ```typescript
811
+ * import { getUserPrivileges } from '@tale/client';
812
+ *
813
+ * try {
814
+ * const privileges = await getUserPrivileges('user_id_here');
815
+ * console.log(`User has ${privileges.length} privileges`);
816
+ * privileges.forEach(priv => console.log('-', priv.privilegeName));
817
+ * } catch (error) {
818
+ * console.error('Failed to get user privileges:', error.message);
819
+ * }
820
+ * ```
821
+ */
822
+ export async function getUserPrivileges(userId, options) {
823
+ if (!userId || userId.trim() === "") {
824
+ throw new ApiError("user_id is required", 400, "9400");
825
+ }
826
+ const token = options?.appToken ?? (await getAppToken(options));
827
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
828
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
829
+ if (!base) {
830
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
831
+ }
832
+ const url = String(base).replace(/\/+$/, "") +
833
+ `/rbac/v1/user/${encodeURIComponent(userId)}/privileges`;
834
+ let response;
835
+ try {
836
+ response = await globalThis.fetch(url, {
837
+ method: "GET",
838
+ headers: {
839
+ "Content-Type": "application/json",
840
+ "x-t-token": token,
841
+ },
842
+ });
843
+ }
844
+ catch (error) {
845
+ throw new NetworkError(`Failed to get user privileges: ${error instanceof Error ? error.message : "Unknown error"}`);
846
+ }
847
+ const json = (await response.json());
848
+ if (json.code !== 200) {
849
+ const errorMsg = typeof json.msg === "string"
850
+ ? json.msg
851
+ : "Failed to get user privileges";
852
+ throw new ApiError(errorMsg, response.status, json.code);
853
+ }
854
+ if (!json.data || !Array.isArray(json.data)) {
855
+ throw new ApiError("Invalid user privileges response: missing data", response.status);
856
+ }
857
+ return json.data;
858
+ }
859
+ /**
860
+ * Assigns privileges to a user.
861
+ *
862
+ * @param userId - User ID
863
+ * @param request - Request containing privilege IDs to assign
864
+ * @param options - Optional configuration
865
+ * @returns Promise resolving to list of assigned privileges
866
+ * @throws {ConfigurationError} When required environment variables are missing
867
+ * @throws {ApiError} When API request fails
868
+ * @throws {NetworkError} When network request fails
869
+ *
870
+ * @example
871
+ * ```typescript
872
+ * import { assignPrivilegesToUser } from '@tale/client';
873
+ *
874
+ * try {
875
+ * const privileges = await assignPrivilegesToUser('user_id_here', {
876
+ * privilege_ids: ['priv1', 'priv2']
877
+ * });
878
+ * console.log('Privileges assigned successfully');
879
+ * } catch (error) {
880
+ * console.error('Failed to assign privileges:', error.message);
881
+ * }
882
+ * ```
883
+ */
884
+ export async function assignPrivilegesToUser(userId, request, options) {
885
+ if (!userId || userId.trim() === "") {
886
+ throw new ApiError("user_id is required", 400, "9400");
887
+ }
888
+ if (!request.privilege_ids ||
889
+ !Array.isArray(request.privilege_ids) ||
890
+ request.privilege_ids.length === 0) {
891
+ throw new ApiError("privilege_ids is required and must be a non-empty array", 400, "9400");
892
+ }
893
+ const token = options?.appToken ?? (await getAppToken(options));
894
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
895
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
896
+ if (!base) {
897
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
898
+ }
899
+ const url = String(base).replace(/\/+$/, "") +
900
+ `/rbac/v1/user/${encodeURIComponent(userId)}/privileges`;
901
+ let response;
902
+ try {
903
+ response = await globalThis.fetch(url, {
904
+ method: "POST",
905
+ headers: {
906
+ "Content-Type": "application/json",
907
+ "x-t-token": token,
908
+ },
909
+ body: JSON.stringify(request),
910
+ });
911
+ }
912
+ catch (error) {
913
+ throw new NetworkError(`Failed to assign privileges to user: ${error instanceof Error ? error.message : "Unknown error"}`);
914
+ }
915
+ const json = (await response.json());
916
+ if (json.code !== 200) {
917
+ const errorMsg = typeof json.msg === "string"
918
+ ? json.msg
919
+ : "Failed to assign privileges to user";
920
+ throw new ApiError(errorMsg, response.status, json.code);
921
+ }
922
+ if (!json.data || !Array.isArray(json.data)) {
923
+ throw new ApiError("Invalid privilege assignment response: missing data", response.status);
924
+ }
925
+ return json.data;
926
+ }
927
+ /**
928
+ * Unassigns privileges from a user.
929
+ *
930
+ * @param userId - User ID
931
+ * @param request - Request containing privilege IDs to unassign
932
+ * @param options - Optional configuration
933
+ * @returns Promise that resolves when unassignment is successful
934
+ * @throws {ConfigurationError} When required environment variables are missing
935
+ * @throws {ApiError} When API request fails
936
+ * @throws {NetworkError} When network request fails
937
+ *
938
+ * @example
939
+ * ```typescript
940
+ * import { unassignPrivilegesFromUser } from '@tale/client';
941
+ *
942
+ * try {
943
+ * await unassignPrivilegesFromUser('user_id_here', {
944
+ * privilege_ids: ['priv1', 'priv2']
945
+ * });
946
+ * console.log('Privileges unassigned successfully');
947
+ * } catch (error) {
948
+ * console.error('Failed to unassign privileges:', error.message);
949
+ * }
950
+ * ```
951
+ */
952
+ export async function unassignPrivilegesFromUser(userId, request, options) {
953
+ if (!userId || userId.trim() === "") {
954
+ throw new ApiError("user_id is required", 400, "9400");
955
+ }
956
+ if (!request.privilege_ids ||
957
+ !Array.isArray(request.privilege_ids) ||
958
+ request.privilege_ids.length === 0) {
959
+ throw new ApiError("privilege_ids is required and must be a non-empty array", 400, "9400");
960
+ }
961
+ const token = options?.appToken ?? (await getAppToken(options));
962
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
963
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
964
+ if (!base) {
965
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
966
+ }
967
+ const url = String(base).replace(/\/+$/, "") +
968
+ `/rbac/v1/user/${encodeURIComponent(userId)}/privileges`;
969
+ let response;
970
+ try {
971
+ response = await globalThis.fetch(url, {
972
+ method: "DELETE",
973
+ headers: {
974
+ "Content-Type": "application/json",
975
+ "x-t-token": token,
976
+ },
977
+ body: JSON.stringify(request),
978
+ });
979
+ }
980
+ catch (error) {
981
+ throw new NetworkError(`Failed to unassign privileges from user: ${error instanceof Error ? error.message : "Unknown error"}`);
982
+ }
983
+ const json = (await response.json());
984
+ if (json.code !== 200) {
985
+ const errorMsg = typeof json.msg === "string"
986
+ ? json.msg
987
+ : "Failed to unassign privileges from user";
988
+ throw new ApiError(errorMsg, response.status, json.code);
989
+ }
990
+ }
991
+ // ==================== Role Privilege Management ====================
992
+ /**
993
+ * Assigns privileges to a role.
994
+ *
995
+ * @param roleId - Role ID
996
+ * @param request - Request containing privilege IDs to assign
997
+ * @param options - Optional configuration
998
+ * @returns Promise resolving to list of assigned privileges
999
+ * @throws {ConfigurationError} When required environment variables are missing
1000
+ * @throws {ApiError} When API request fails
1001
+ * @throws {NetworkError} When network request fails
1002
+ *
1003
+ * @example
1004
+ * ```typescript
1005
+ * import { assignPrivilegesToRole } from '@tale/client';
1006
+ *
1007
+ * try {
1008
+ * const privileges = await assignPrivilegesToRole('role_id_here', {
1009
+ * privilege_ids: ['priv1', 'priv2']
1010
+ * });
1011
+ * console.log('Privileges assigned successfully');
1012
+ * } catch (error) {
1013
+ * console.error('Failed to assign privileges:', error.message);
1014
+ * }
1015
+ * ```
1016
+ */
1017
+ export async function assignPrivilegesToRole(roleId, request, options) {
1018
+ if (!roleId || roleId.trim() === "") {
1019
+ throw new ApiError("role_id is required", 400, "9400");
1020
+ }
1021
+ if (!request.privilege_ids ||
1022
+ !Array.isArray(request.privilege_ids) ||
1023
+ request.privilege_ids.length === 0) {
1024
+ throw new ApiError("privilege_ids is required and must be a non-empty array", 400, "9400");
1025
+ }
1026
+ const token = options?.appToken ?? (await getAppToken(options));
1027
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
1028
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
1029
+ if (!base) {
1030
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
1031
+ }
1032
+ const url = String(base).replace(/\/+$/, "") +
1033
+ `/rbac/v1/role/${encodeURIComponent(roleId)}/privileges`;
1034
+ let response;
1035
+ try {
1036
+ response = await globalThis.fetch(url, {
1037
+ method: "POST",
1038
+ headers: {
1039
+ "Content-Type": "application/json",
1040
+ "x-t-token": token,
1041
+ },
1042
+ body: JSON.stringify(request),
1043
+ });
1044
+ }
1045
+ catch (error) {
1046
+ throw new NetworkError(`Failed to assign privileges to role: ${error instanceof Error ? error.message : "Unknown error"}`);
1047
+ }
1048
+ const json = (await response.json());
1049
+ if (json.code !== 200) {
1050
+ const errorMsg = typeof json.msg === "string"
1051
+ ? json.msg
1052
+ : "Failed to assign privileges to role";
1053
+ throw new ApiError(errorMsg, response.status, json.code);
1054
+ }
1055
+ if (!json.data || !Array.isArray(json.data)) {
1056
+ throw new ApiError("Invalid privilege assignment response: missing data", response.status);
1057
+ }
1058
+ return json.data;
1059
+ }
1060
+ /**
1061
+ * Unassigns privileges from a role.
1062
+ *
1063
+ * @param roleId - Role ID
1064
+ * @param request - Request containing privilege IDs to unassign
1065
+ * @param options - Optional configuration
1066
+ * @returns Promise that resolves when unassignment is successful
1067
+ * @throws {ConfigurationError} When required environment variables are missing
1068
+ * @throws {ApiError} When API request fails
1069
+ * @throws {NetworkError} When network request fails
1070
+ *
1071
+ * @example
1072
+ * ```typescript
1073
+ * import { unassignPrivilegesFromRole } from '@tale/client';
1074
+ *
1075
+ * try {
1076
+ * await unassignPrivilegesFromRole('role_id_here', {
1077
+ * privilege_ids: ['priv1', 'priv2']
1078
+ * });
1079
+ * console.log('Privileges unassigned successfully');
1080
+ * } catch (error) {
1081
+ * console.error('Failed to unassign privileges:', error.message);
1082
+ * }
1083
+ * ```
1084
+ */
1085
+ export async function unassignPrivilegesFromRole(roleId, request, options) {
1086
+ if (!roleId || roleId.trim() === "") {
1087
+ throw new ApiError("role_id is required", 400, "9400");
1088
+ }
1089
+ if (!request.privilege_ids ||
1090
+ !Array.isArray(request.privilege_ids) ||
1091
+ request.privilege_ids.length === 0) {
1092
+ throw new ApiError("privilege_ids is required and must be a non-empty array", 400, "9400");
1093
+ }
1094
+ const token = options?.appToken ?? (await getAppToken(options));
1095
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
1096
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
1097
+ if (!base) {
1098
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
1099
+ }
1100
+ const url = String(base).replace(/\/+$/, "") +
1101
+ `/rbac/v1/role/${encodeURIComponent(roleId)}/privileges`;
1102
+ let response;
1103
+ try {
1104
+ response = await globalThis.fetch(url, {
1105
+ method: "DELETE",
1106
+ headers: {
1107
+ "Content-Type": "application/json",
1108
+ "x-t-token": token,
1109
+ },
1110
+ body: JSON.stringify(request),
1111
+ });
1112
+ }
1113
+ catch (error) {
1114
+ throw new NetworkError(`Failed to unassign privileges from role: ${error instanceof Error ? error.message : "Unknown error"}`);
1115
+ }
1116
+ const json = (await response.json());
1117
+ if (json.code !== 200) {
1118
+ const errorMsg = typeof json.msg === "string"
1119
+ ? json.msg
1120
+ : "Failed to unassign privileges from role";
1121
+ throw new ApiError(errorMsg, response.status, json.code);
1122
+ }
1123
+ }