@turinhub/tale-js-sdk 1.3.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.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +56 -0
  3. package/dist/acl/index.d.ts +295 -0
  4. package/dist/acl/index.js +653 -0
  5. package/dist/acl/types.d.ts +142 -0
  6. package/dist/acl/types.js +1 -0
  7. package/dist/auth/index.d.ts +166 -0
  8. package/dist/auth/index.js +522 -0
  9. package/dist/auth/types.d.ts +127 -0
  10. package/dist/auth/types.js +1 -0
  11. package/dist/cms/file.d.ts +398 -0
  12. package/dist/cms/file.js +800 -0
  13. package/dist/cms/folder.d.ts +128 -0
  14. package/dist/cms/folder.js +294 -0
  15. package/dist/cms/index.d.ts +3 -0
  16. package/dist/cms/index.js +6 -0
  17. package/dist/cms/types.d.ts +157 -0
  18. package/dist/cms/types.js +1 -0
  19. package/dist/common/types.d.ts +91 -0
  20. package/dist/common/types.js +2 -0
  21. package/dist/errors.d.ts +52 -0
  22. package/dist/errors.js +109 -0
  23. package/dist/index.d.ts +13 -0
  24. package/dist/index.js +12 -0
  25. package/dist/rbac/acl.d.ts +152 -0
  26. package/dist/rbac/acl.js +723 -0
  27. package/dist/rbac/index.d.ts +464 -0
  28. package/dist/rbac/index.js +1121 -0
  29. package/dist/rbac/rbac.d.ts +198 -0
  30. package/dist/rbac/rbac.js +984 -0
  31. package/dist/rbac/types.d.ts +125 -0
  32. package/dist/rbac/types.js +1 -0
  33. package/dist/rbac/user-group.d.ts +122 -0
  34. package/dist/rbac/user-group.js +570 -0
  35. package/dist/status.d.ts +40 -0
  36. package/dist/status.js +56 -0
  37. package/dist/task/index.d.ts +163 -0
  38. package/dist/task/index.js +495 -0
  39. package/dist/task/types.d.ts +116 -0
  40. package/dist/task/types.js +1 -0
  41. package/dist/task-type/index.d.ts +92 -0
  42. package/dist/task-type/index.js +256 -0
  43. package/dist/task-type/types.d.ts +54 -0
  44. package/dist/task-type/types.js +1 -0
  45. package/dist/token.d.ts +21 -0
  46. package/dist/token.js +114 -0
  47. package/dist/user/index.d.ts +267 -0
  48. package/dist/user/index.js +786 -0
  49. package/dist/user/types.d.ts +145 -0
  50. package/dist/user/types.js +1 -0
  51. package/dist/user-attribute/index.d.ts +186 -0
  52. package/dist/user-attribute/index.js +615 -0
  53. package/dist/user-attribute/types.d.ts +109 -0
  54. package/dist/user-attribute/types.js +1 -0
  55. package/dist/user-group/index.d.ts +231 -0
  56. package/dist/user-group/index.js +566 -0
  57. package/dist/user-group/types.d.ts +50 -0
  58. package/dist/user-group/types.js +1 -0
  59. package/package.json +50 -0
@@ -0,0 +1,653 @@
1
+ import { getAppToken } from "../token.js";
2
+ import { ApiError, ConfigurationError, NetworkError } from "../errors.js";
3
+ // ==================== Helper Functions ====================
4
+ /**
5
+ * Parses standard API response format: { code, msg, data }
6
+ */
7
+ function parseApiResponse(json, errorMessage, statusCode) {
8
+ if (typeof json !== "object" || json === null) {
9
+ throw new ApiError(`Invalid response: ${errorMessage} - not an object`, statusCode);
10
+ }
11
+ const response = json;
12
+ if (response.code !== 200) {
13
+ const errorMsg = typeof response.msg === "string" ? response.msg : errorMessage;
14
+ throw new ApiError(errorMsg, statusCode, response.code);
15
+ }
16
+ if (!response.data) {
17
+ throw new ApiError(`Invalid response: ${errorMessage} - missing data`, statusCode);
18
+ }
19
+ return response.data;
20
+ }
21
+ // ==================== ACL Record Management (v2) ====================
22
+ /**
23
+ * Gets an ACL record by ID.
24
+ *
25
+ * @param recordId - Record ID
26
+ * @param options - Optional configuration
27
+ * @returns Promise resolving to ACL record information
28
+ * @throws {ConfigurationError} When required environment variables are missing
29
+ * @throws {ApiError} When API request fails
30
+ * @throws {NetworkError} When network request fails
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * import { getAclRecord } from '@tale/client';
35
+ *
36
+ * try {
37
+ * const record = await getAclRecord('record_id_here');
38
+ * console.log('Record effect:', record.effect_type);
39
+ * } catch (error) {
40
+ * console.error('Failed to get ACL record:', error.message);
41
+ * }
42
+ * ```
43
+ */
44
+ export async function getAclRecord(recordId, options) {
45
+ if (!recordId || recordId.trim() === "") {
46
+ throw new ApiError("record_id is required", 400, "9400");
47
+ }
48
+ const token = options?.appToken ?? (await getAppToken(options));
49
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
50
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
51
+ if (!base) {
52
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
53
+ }
54
+ const url = String(base).replace(/\/+$/, "") +
55
+ `/acl/v2/records/${encodeURIComponent(recordId)}`;
56
+ let response;
57
+ try {
58
+ response = await globalThis.fetch(url, {
59
+ method: "GET",
60
+ headers: {
61
+ "Content-Type": "application/json",
62
+ "x-t-token": token,
63
+ },
64
+ });
65
+ }
66
+ catch (error) {
67
+ throw new NetworkError(`Failed to get ACL record: ${error instanceof Error ? error.message : "Unknown error"}`);
68
+ }
69
+ const json = await response.json();
70
+ return parseApiResponse(json, "Failed to get ACL record", response.status);
71
+ }
72
+ /**
73
+ * Lists ACL records with pagination and optional filtering.
74
+ *
75
+ * @param options - Optional parameters for pagination and filtering
76
+ * @returns Promise resolving to paginated ACL record list
77
+ * @throws {ConfigurationError} When required environment variables are missing
78
+ * @throws {ApiError} When API request fails
79
+ * @throws {NetworkError} When network request fails
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * import { listAclRecords } from '@tale/client';
84
+ *
85
+ * try {
86
+ * const result = await listAclRecords({
87
+ * page: 0,
88
+ * size: 20,
89
+ * resource_type: 'document'
90
+ * });
91
+ * console.log(`Found ${result.total} records`);
92
+ * } catch (error) {
93
+ * console.error('Failed to list ACL records:', error.message);
94
+ * }
95
+ * ```
96
+ */
97
+ export async function listAclRecords(options) {
98
+ const token = options?.appToken ?? (await getAppToken(options));
99
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
100
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
101
+ if (!base) {
102
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
103
+ }
104
+ const url = new URL(String(base).replace(/\/+$/, "") + "/acl/v2/records");
105
+ // 分离 AclOptions 字段,只保留请求参数
106
+ const { appToken, baseUrl, ...requestParams } = options || {};
107
+ const queryParams = {
108
+ page: 0,
109
+ size: 20,
110
+ sort: "createdAt,desc",
111
+ ...requestParams,
112
+ };
113
+ Object.entries(queryParams).forEach(([key, value]) => {
114
+ if (value !== undefined) {
115
+ url.searchParams.append(key, String(value));
116
+ }
117
+ });
118
+ let response;
119
+ try {
120
+ response = await globalThis.fetch(url.toString(), {
121
+ method: "GET",
122
+ headers: {
123
+ "Content-Type": "application/json",
124
+ "x-t-token": token,
125
+ },
126
+ });
127
+ }
128
+ catch (error) {
129
+ throw new NetworkError(`Failed to list ACL records: ${error instanceof Error ? error.message : "Unknown error"}`);
130
+ }
131
+ const json = await response.json();
132
+ return parseApiResponse(json, "Failed to list ACL records", response.status);
133
+ }
134
+ /**
135
+ * Creates a new ACL record.
136
+ *
137
+ * @param request - ACL record creation request
138
+ * @param options - Optional configuration
139
+ * @returns Promise resolving to created ACL record
140
+ * @throws {ConfigurationError} When required environment variables are missing
141
+ * @throws {ApiError} When API request fails
142
+ * @throws {NetworkError} When network request fails
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * import { createAclRecord } from '@tale/client';
147
+ *
148
+ * try {
149
+ * const record = await createAclRecord({
150
+ * subject_type: 'user',
151
+ * subject_id: 'user123',
152
+ * resource_type: 'document',
153
+ * resource_id: 'doc456',
154
+ * effect_type: 'allow'
155
+ * });
156
+ * console.log('Record created:', record.record_id);
157
+ * } catch (error) {
158
+ * console.error('Failed to create ACL record:', error.message);
159
+ * }
160
+ * ```
161
+ */
162
+ export async function createAclRecord(request, options) {
163
+ if (!request.subject_type || request.subject_type.trim() === "") {
164
+ throw new ApiError("subject_type is required", 400, "9400");
165
+ }
166
+ if (!request.resource_type || request.resource_type.trim() === "") {
167
+ throw new ApiError("resource_type is required", 400, "9400");
168
+ }
169
+ if (!request.effect_type || request.effect_type.trim() === "") {
170
+ throw new ApiError("effect_type is required", 400, "9400");
171
+ }
172
+ const token = options?.appToken ?? (await getAppToken(options));
173
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
174
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
175
+ if (!base) {
176
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
177
+ }
178
+ const url = String(base).replace(/\/+$/, "") + "/acl/v2/records";
179
+ let response;
180
+ try {
181
+ response = await globalThis.fetch(url, {
182
+ method: "POST",
183
+ headers: {
184
+ "Content-Type": "application/json",
185
+ "x-t-token": token,
186
+ },
187
+ body: JSON.stringify(request),
188
+ });
189
+ }
190
+ catch (error) {
191
+ throw new NetworkError(`Failed to create ACL record: ${error instanceof Error ? error.message : "Unknown error"}`);
192
+ }
193
+ const json = await response.json();
194
+ return parseApiResponse(json, "Failed to create ACL record", response.status);
195
+ }
196
+ /**
197
+ * Batch creates ACL records.
198
+ *
199
+ * @param requests - Array of ACL record creation requests
200
+ * @param options - Optional configuration
201
+ * @returns Promise resolving to batch creation response with success/failure details
202
+ * @throws {ConfigurationError} When required environment variables are missing
203
+ * @throws {ApiError} When API request fails
204
+ * @throws {NetworkError} When network request fails
205
+ *
206
+ * @example
207
+ * ```typescript
208
+ * import { batchCreateAclRecords } from '@tale/client';
209
+ *
210
+ * try {
211
+ * const result = await batchCreateAclRecords([
212
+ * {
213
+ * subject_type: 'user',
214
+ * subject_id: 'user1',
215
+ * resource_type: 'document',
216
+ * effect_type: 'allow'
217
+ * },
218
+ * {
219
+ * subject_type: 'user',
220
+ * subject_id: 'user2',
221
+ * resource_type: 'document',
222
+ * effect_type: 'deny'
223
+ * }
224
+ * ]);
225
+ * console.log(`Created ${result.success_count}, Failed ${result.failure_count}`);
226
+ * } catch (error) {
227
+ * console.error('Failed to batch create ACL records:', error.message);
228
+ * }
229
+ * ```
230
+ */
231
+ export async function batchCreateAclRecords(requests, options) {
232
+ if (!Array.isArray(requests) || requests.length === 0) {
233
+ throw new ApiError("requests is required and must be a non-empty array", 400, "9400");
234
+ }
235
+ const token = options?.appToken ?? (await getAppToken(options));
236
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
237
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
238
+ if (!base) {
239
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
240
+ }
241
+ const url = String(base).replace(/\/+$/, "") + "/acl/v2/records/batch";
242
+ let response;
243
+ try {
244
+ response = await globalThis.fetch(url, {
245
+ method: "POST",
246
+ headers: {
247
+ "Content-Type": "application/json",
248
+ "x-t-token": token,
249
+ },
250
+ body: JSON.stringify(requests),
251
+ });
252
+ }
253
+ catch (error) {
254
+ throw new NetworkError(`Failed to batch create ACL records: ${error instanceof Error ? error.message : "Unknown error"}`);
255
+ }
256
+ const json = await response.json();
257
+ return parseApiResponse(json, "Failed to batch create ACL records", response.status);
258
+ }
259
+ /**
260
+ * Updates an existing ACL record.
261
+ *
262
+ * @param recordId - Record ID to update
263
+ * @param request - Update request with fields to modify
264
+ * @param options - Optional configuration
265
+ * @returns Promise resolving to updated ACL record
266
+ * @throws {ConfigurationError} When required environment variables are missing
267
+ * @throws {ApiError} When API request fails
268
+ * @throws {NetworkError} When network request fails
269
+ *
270
+ * @example
271
+ * ```typescript
272
+ * import { updateAclRecord } from '@tale/client';
273
+ *
274
+ * try {
275
+ * const record = await updateAclRecord('record_id_here', {
276
+ * effect_type: 'deny',
277
+ * priority: 100
278
+ * });
279
+ * console.log('Record updated:', record.record_id);
280
+ * } catch (error) {
281
+ * console.error('Failed to update ACL record:', error.message);
282
+ * }
283
+ * ```
284
+ */
285
+ export async function updateAclRecord(recordId, request, options) {
286
+ if (!recordId || recordId.trim() === "") {
287
+ throw new ApiError("record_id is required", 400, "9400");
288
+ }
289
+ const token = options?.appToken ?? (await getAppToken(options));
290
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
291
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
292
+ if (!base) {
293
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
294
+ }
295
+ const url = String(base).replace(/\/+$/, "") +
296
+ `/acl/v2/records/${encodeURIComponent(recordId)}`;
297
+ let response;
298
+ try {
299
+ response = await globalThis.fetch(url, {
300
+ method: "PUT",
301
+ headers: {
302
+ "Content-Type": "application/json",
303
+ "x-t-token": token,
304
+ },
305
+ body: JSON.stringify(request),
306
+ });
307
+ }
308
+ catch (error) {
309
+ throw new NetworkError(`Failed to update ACL record: ${error instanceof Error ? error.message : "Unknown error"}`);
310
+ }
311
+ const json = await response.json();
312
+ return parseApiResponse(json, "Failed to update ACL record", response.status);
313
+ }
314
+ /**
315
+ * Deletes an ACL record.
316
+ *
317
+ * @param recordId - Record ID to delete
318
+ * @param options - Optional configuration
319
+ * @returns Promise that resolves when deletion is successful
320
+ * @throws {ConfigurationError} When required environment variables are missing
321
+ * @throws {ApiError} When API request fails
322
+ * @throws {NetworkError} When network request fails
323
+ *
324
+ * @example
325
+ * ```typescript
326
+ * import { deleteAclRecord } from '@tale/client';
327
+ *
328
+ * try {
329
+ * await deleteAclRecord('record_id_here');
330
+ * console.log('ACL record deleted successfully');
331
+ * } catch (error) {
332
+ * console.error('Failed to delete ACL record:', error.message);
333
+ * }
334
+ * ```
335
+ */
336
+ export async function deleteAclRecord(recordId, options) {
337
+ if (!recordId || recordId.trim() === "") {
338
+ throw new ApiError("record_id is required", 400, "9400");
339
+ }
340
+ const token = options?.appToken ?? (await getAppToken(options));
341
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
342
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
343
+ if (!base) {
344
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
345
+ }
346
+ const url = String(base).replace(/\/+$/, "") +
347
+ `/acl/v2/records/${encodeURIComponent(recordId)}`;
348
+ let response;
349
+ try {
350
+ response = await globalThis.fetch(url, {
351
+ method: "DELETE",
352
+ headers: {
353
+ "Content-Type": "application/json",
354
+ "x-t-token": token,
355
+ },
356
+ });
357
+ }
358
+ catch (error) {
359
+ throw new NetworkError(`Failed to delete ACL record: ${error instanceof Error ? error.message : "Unknown error"}`);
360
+ }
361
+ const json = await response.json();
362
+ // Delete response may not have data field, handle differently
363
+ if (typeof json !== "object" || json === null) {
364
+ throw new ApiError("Invalid ACL record deletion response", response.status);
365
+ }
366
+ const apiResponse = json;
367
+ if (apiResponse.code !== 200) {
368
+ const errorMsg = typeof apiResponse.msg === "string"
369
+ ? apiResponse.msg
370
+ : "Failed to delete ACL record";
371
+ throw new ApiError(errorMsg, response.status, apiResponse.code);
372
+ }
373
+ }
374
+ // ==================== ACL Template Management ====================
375
+ /**
376
+ * Gets an ACL template by ID or code.
377
+ *
378
+ * @param templateId - Template ID or code
379
+ * @param options - Optional configuration
380
+ * @returns Promise resolving to ACL template information
381
+ * @throws {ConfigurationError} When required environment variables are missing
382
+ * @throws {ApiError} When API request fails
383
+ * @throws {NetworkError} When network request fails
384
+ *
385
+ * @example
386
+ * ```typescript
387
+ * import { getAclTemplate } from '@tale/client';
388
+ *
389
+ * try {
390
+ * const template = await getAclTemplate('template_code_here');
391
+ * console.log('Template name:', template.template_name);
392
+ * } catch (error) {
393
+ * console.error('Failed to get ACL template:', error.message);
394
+ * }
395
+ * ```
396
+ */
397
+ export async function getAclTemplate(templateId, options) {
398
+ if (!templateId || templateId.trim() === "") {
399
+ throw new ApiError("template_id is required", 400, "9400");
400
+ }
401
+ const token = options?.appToken ?? (await getAppToken(options));
402
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
403
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
404
+ if (!base) {
405
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
406
+ }
407
+ const url = String(base).replace(/\/+$/, "") +
408
+ `/acl/v1/templates/${encodeURIComponent(templateId)}`;
409
+ let response;
410
+ try {
411
+ response = await globalThis.fetch(url, {
412
+ method: "GET",
413
+ headers: {
414
+ "Content-Type": "application/json",
415
+ "x-t-token": token,
416
+ },
417
+ });
418
+ }
419
+ catch (error) {
420
+ throw new NetworkError(`Failed to get ACL template: ${error instanceof Error ? error.message : "Unknown error"}`);
421
+ }
422
+ const json = await response.json();
423
+ return parseApiResponse(json, "Failed to get ACL template", response.status);
424
+ }
425
+ /**
426
+ * Lists ACL templates with pagination and optional filtering.
427
+ *
428
+ * @param options - Optional parameters for pagination and filtering
429
+ * @returns Promise resolving to paginated ACL template list
430
+ * @throws {ConfigurationError} When required environment variables are missing
431
+ * @throws {ApiError} When API request fails
432
+ * @throws {NetworkError} When network request fails
433
+ *
434
+ * @example
435
+ * ```typescript
436
+ * import { listAclTemplates } from '@tale/client';
437
+ *
438
+ * try {
439
+ * const result = await listAclTemplates({
440
+ * page: 0,
441
+ * size: 20,
442
+ * resource_type: 'document'
443
+ * });
444
+ * console.log(`Found ${result.total} templates`);
445
+ * } catch (error) {
446
+ * console.error('Failed to list ACL templates:', error.message);
447
+ * }
448
+ * ```
449
+ */
450
+ export async function listAclTemplates(options) {
451
+ const token = options?.appToken ?? (await getAppToken(options));
452
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
453
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
454
+ if (!base) {
455
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
456
+ }
457
+ const url = new URL(String(base).replace(/\/+$/, "") + "/acl/v2/templates");
458
+ // 分离 AclOptions 字段,只保留请求参数
459
+ const { appToken, baseUrl, ...requestParams } = options || {};
460
+ const queryParams = {
461
+ page: 0,
462
+ size: 20,
463
+ sort: "createdAt,desc",
464
+ ...requestParams,
465
+ };
466
+ Object.entries(queryParams).forEach(([key, value]) => {
467
+ if (value !== undefined) {
468
+ url.searchParams.append(key, String(value));
469
+ }
470
+ });
471
+ let response;
472
+ try {
473
+ response = await globalThis.fetch(url.toString(), {
474
+ method: "GET",
475
+ headers: {
476
+ "Content-Type": "application/json",
477
+ "x-t-token": token,
478
+ },
479
+ });
480
+ }
481
+ catch (error) {
482
+ throw new NetworkError(`Failed to list ACL templates: ${error instanceof Error ? error.message : "Unknown error"}`);
483
+ }
484
+ const json = await response.json();
485
+ return parseApiResponse(json, "Failed to list ACL templates", response.status);
486
+ }
487
+ /**
488
+ * Creates a new ACL template.
489
+ *
490
+ * @param request - ACL template creation request
491
+ * @param options - Optional configuration
492
+ * @returns Promise resolving to created ACL template
493
+ * @throws {ConfigurationError} When required environment variables are missing
494
+ * @throws {ApiError} When API request fails
495
+ * @throws {NetworkError} When network request fails
496
+ *
497
+ * @example
498
+ * ```typescript
499
+ * import { createAclTemplate } from '@tale/client';
500
+ *
501
+ * try {
502
+ * const template = await createAclTemplate({
503
+ * template_name: 'Document Access',
504
+ * template_code: 'doc_access',
505
+ * subject_type: 'user',
506
+ * resource_type: 'document',
507
+ * effect_type: 'allow'
508
+ * });
509
+ * console.log('Template created:', template.template_id);
510
+ * } catch (error) {
511
+ * console.error('Failed to create ACL template:', error.message);
512
+ * }
513
+ * ```
514
+ */
515
+ export async function createAclTemplate(request, options) {
516
+ if (!request.template_name || request.template_name.trim() === "") {
517
+ throw new ApiError("template_name is required", 400, "9400");
518
+ }
519
+ if (!request.template_code || request.template_code.trim() === "") {
520
+ throw new ApiError("template_code 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(/\/+$/, "") + "/acl/v1/templates";
529
+ let response;
530
+ try {
531
+ response = await globalThis.fetch(url, {
532
+ method: "POST",
533
+ headers: {
534
+ "Content-Type": "application/json",
535
+ "x-t-token": token,
536
+ },
537
+ body: JSON.stringify(request),
538
+ });
539
+ }
540
+ catch (error) {
541
+ throw new NetworkError(`Failed to create ACL template: ${error instanceof Error ? error.message : "Unknown error"}`);
542
+ }
543
+ const json = await response.json();
544
+ return parseApiResponse(json, "Failed to create ACL template", response.status);
545
+ }
546
+ /**
547
+ * Updates an existing ACL template.
548
+ *
549
+ * @param templateId - Template ID or code to update
550
+ * @param request - Update request with fields to modify
551
+ * @param options - Optional configuration
552
+ * @returns Promise resolving to updated ACL template
553
+ * @throws {ConfigurationError} When required environment variables are missing
554
+ * @throws {ApiError} When API request fails
555
+ * @throws {NetworkError} When network request fails
556
+ *
557
+ * @example
558
+ * ```typescript
559
+ * import { updateAclTemplate } from '@tale/client';
560
+ *
561
+ * try {
562
+ * const template = await updateAclTemplate('template_code_here', {
563
+ * template_name: 'Updated Template Name',
564
+ * effect_type: 'deny'
565
+ * });
566
+ * console.log('Template updated:', template.template_id);
567
+ * } catch (error) {
568
+ * console.error('Failed to update ACL template:', error.message);
569
+ * }
570
+ * ```
571
+ */
572
+ export async function updateAclTemplate(templateId, request, options) {
573
+ if (!templateId || templateId.trim() === "") {
574
+ throw new ApiError("template_id is required", 400, "9400");
575
+ }
576
+ const token = options?.appToken ?? (await getAppToken(options));
577
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
578
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
579
+ if (!base) {
580
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
581
+ }
582
+ const url = String(base).replace(/\/+$/, "") +
583
+ `/acl/v1/templates/${encodeURIComponent(templateId)}`;
584
+ let response;
585
+ try {
586
+ response = await globalThis.fetch(url, {
587
+ method: "PUT",
588
+ headers: {
589
+ "Content-Type": "application/json",
590
+ "x-t-token": token,
591
+ },
592
+ body: JSON.stringify(request),
593
+ });
594
+ }
595
+ catch (error) {
596
+ throw new NetworkError(`Failed to update ACL template: ${error instanceof Error ? error.message : "Unknown error"}`);
597
+ }
598
+ const json = await response.json();
599
+ return parseApiResponse(json, "Failed to update ACL template", response.status);
600
+ }
601
+ /**
602
+ * Deletes an ACL template.
603
+ *
604
+ * @param templateId - Template ID or code to delete
605
+ * @param options - Optional configuration
606
+ * @returns Promise that resolves when deletion is successful
607
+ * @throws {ConfigurationError} When required environment variables are missing
608
+ * @throws {ApiError} When API request fails
609
+ * @throws {NetworkError} When network request fails
610
+ *
611
+ * @example
612
+ * ```typescript
613
+ * import { deleteAclTemplate } from '@tale/client';
614
+ *
615
+ * try {
616
+ * await deleteAclTemplate('template_code_here');
617
+ * console.log('ACL template deleted successfully');
618
+ * } catch (error) {
619
+ * console.error('Failed to delete ACL template:', error.message);
620
+ * }
621
+ * ```
622
+ */
623
+ export async function deleteAclTemplate(templateId, options) {
624
+ if (!templateId || templateId.trim() === "") {
625
+ throw new ApiError("template_id is required", 400, "9400");
626
+ }
627
+ const token = options?.appToken ?? (await getAppToken(options));
628
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
629
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
630
+ if (!base) {
631
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
632
+ }
633
+ const url = String(base).replace(/\/+$/, "") +
634
+ `/acl/v1/templates/${encodeURIComponent(templateId)}`;
635
+ let response;
636
+ try {
637
+ response = await globalThis.fetch(url, {
638
+ method: "DELETE",
639
+ headers: {
640
+ "Content-Type": "application/json",
641
+ "x-t-token": token,
642
+ },
643
+ });
644
+ }
645
+ catch (error) {
646
+ throw new NetworkError(`Failed to delete ACL template: ${error instanceof Error ? error.message : "Unknown error"}`);
647
+ }
648
+ const json = (await response.json());
649
+ if (json.code !== 200) {
650
+ const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to delete ACL template";
651
+ throw new ApiError(errorMsg, response.status, json.code);
652
+ }
653
+ }