@turinhub/tale-js-sdk 1.3.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +6 -6
  2. package/dist/acl/index.d.ts +62 -49
  3. package/dist/acl/index.js +262 -67
  4. package/dist/acl/types.d.ts +63 -98
  5. package/dist/attachment/index.d.ts +17 -0
  6. package/dist/attachment/index.js +247 -0
  7. package/dist/attachment/types.d.ts +82 -0
  8. package/dist/attachment/types.js +1 -0
  9. package/dist/attachment-type/index.d.ts +15 -0
  10. package/dist/attachment-type/index.js +203 -0
  11. package/dist/attachment-type/types.d.ts +60 -0
  12. package/dist/attachment-type/types.js +1 -0
  13. package/dist/auth/index.d.ts +21 -21
  14. package/dist/auth/index.js +66 -66
  15. package/dist/auth/types.d.ts +51 -51
  16. package/dist/cms/file.d.ts +88 -70
  17. package/dist/cms/file.js +228 -77
  18. package/dist/cms/folder.d.ts +9 -9
  19. package/dist/cms/folder.js +18 -18
  20. package/dist/cms/types.d.ts +58 -38
  21. package/dist/common/types.d.ts +47 -63
  22. package/dist/index.d.ts +4 -1
  23. package/dist/index.js +2 -0
  24. package/dist/rbac/index.d.ts +37 -42
  25. package/dist/rbac/index.js +96 -98
  26. package/dist/rbac/types.d.ts +38 -40
  27. package/dist/status.d.ts +11 -11
  28. package/dist/status.js +30 -3
  29. package/dist/task/index.d.ts +15 -147
  30. package/dist/task/index.js +170 -161
  31. package/dist/task/types.d.ts +57 -81
  32. package/dist/task-type/index.d.ts +7 -7
  33. package/dist/task-type/index.js +12 -12
  34. package/dist/task-type/types.d.ts +18 -34
  35. package/dist/token.d.ts +3 -3
  36. package/dist/token.js +4 -4
  37. package/dist/user/index.d.ts +28 -29
  38. package/dist/user/index.js +69 -74
  39. package/dist/user/types.d.ts +32 -33
  40. package/dist/user-attribute/index.d.ts +4 -7
  41. package/dist/user-attribute/index.js +19 -22
  42. package/dist/user-attribute/types.d.ts +29 -29
  43. package/dist/user-group/index.d.ts +4 -223
  44. package/dist/user-group/index.js +61 -479
  45. package/dist/user-group/types.d.ts +1 -1
  46. package/package.json +1 -1
package/dist/acl/index.js CHANGED
@@ -31,11 +31,11 @@ function parseApiResponse(json, errorMessage, statusCode) {
31
31
  *
32
32
  * @example
33
33
  * ```typescript
34
- * import { getAclRecord } from '@tale/client';
34
+ * import { getAclRecord } from '@turinhub/tale-js-sdk';
35
35
  *
36
36
  * try {
37
- * const record = await getAclRecord('record_id_here');
38
- * console.log('Record effect:', record.effect_type);
37
+ * const record = await getAclRecord('recordId_here');
38
+ * console.log('Record effect:', record.effectType);
39
39
  * } catch (error) {
40
40
  * console.error('Failed to get ACL record:', error.message);
41
41
  * }
@@ -43,7 +43,7 @@ function parseApiResponse(json, errorMessage, statusCode) {
43
43
  */
44
44
  export async function getAclRecord(recordId, options) {
45
45
  if (!recordId || recordId.trim() === "") {
46
- throw new ApiError("record_id is required", 400, "9400");
46
+ throw new ApiError("recordId is required", 400, "9400");
47
47
  }
48
48
  const token = options?.appToken ?? (await getAppToken(options));
49
49
  const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
@@ -80,13 +80,13 @@ export async function getAclRecord(recordId, options) {
80
80
  *
81
81
  * @example
82
82
  * ```typescript
83
- * import { listAclRecords } from '@tale/client';
83
+ * import { listAclRecords } from '@turinhub/tale-js-sdk';
84
84
  *
85
85
  * try {
86
86
  * const result = await listAclRecords({
87
87
  * page: 0,
88
88
  * size: 20,
89
- * resource_type: 'document'
89
+ * resourceType: 'document'
90
90
  * });
91
91
  * console.log(`Found ${result.total} records`);
92
92
  * } catch (error) {
@@ -143,31 +143,31 @@ export async function listAclRecords(options) {
143
143
  *
144
144
  * @example
145
145
  * ```typescript
146
- * import { createAclRecord } from '@tale/client';
146
+ * import { createAclRecord } from '@turinhub/tale-js-sdk';
147
147
  *
148
148
  * try {
149
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'
150
+ * subjectType: 'user',
151
+ * subjectId: 'user123',
152
+ * resourceType: 'document',
153
+ * resourceId: 'doc456',
154
+ * effectType: 'allow'
155
155
  * });
156
- * console.log('Record created:', record.record_id);
156
+ * console.log('Record created:', record.recordId);
157
157
  * } catch (error) {
158
158
  * console.error('Failed to create ACL record:', error.message);
159
159
  * }
160
160
  * ```
161
161
  */
162
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");
163
+ if (!request.subjectType || request.subjectType.trim() === "") {
164
+ throw new ApiError("subjectType is required", 400, "9400");
165
165
  }
166
- if (!request.resource_type || request.resource_type.trim() === "") {
167
- throw new ApiError("resource_type is required", 400, "9400");
166
+ if (!request.resourceType || request.resourceType.trim() === "") {
167
+ throw new ApiError("resourceType is required", 400, "9400");
168
168
  }
169
- if (!request.effect_type || request.effect_type.trim() === "") {
170
- throw new ApiError("effect_type is required", 400, "9400");
169
+ if (!request.effectType || request.effectType.trim() === "") {
170
+ throw new ApiError("effectType is required", 400, "9400");
171
171
  }
172
172
  const token = options?.appToken ?? (await getAppToken(options));
173
173
  const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
@@ -205,24 +205,24 @@ export async function createAclRecord(request, options) {
205
205
  *
206
206
  * @example
207
207
  * ```typescript
208
- * import { batchCreateAclRecords } from '@tale/client';
208
+ * import { batchCreateAclRecords } from '@turinhub/tale-js-sdk';
209
209
  *
210
210
  * try {
211
211
  * const result = await batchCreateAclRecords([
212
212
  * {
213
- * subject_type: 'user',
214
- * subject_id: 'user1',
215
- * resource_type: 'document',
216
- * effect_type: 'allow'
213
+ * subjectType: 'user',
214
+ * subjectId: 'user1',
215
+ * resourceType: 'document',
216
+ * effectType: 'allow'
217
217
  * },
218
218
  * {
219
- * subject_type: 'user',
220
- * subject_id: 'user2',
221
- * resource_type: 'document',
222
- * effect_type: 'deny'
219
+ * subjectType: 'user',
220
+ * subjectId: 'user2',
221
+ * resourceType: 'document',
222
+ * effectType: 'deny'
223
223
  * }
224
224
  * ]);
225
- * console.log(`Created ${result.success_count}, Failed ${result.failure_count}`);
225
+ * console.log(`Created ${result.successCount}, Failed ${result.failureCount}`);
226
226
  * } catch (error) {
227
227
  * console.error('Failed to batch create ACL records:', error.message);
228
228
  * }
@@ -269,14 +269,14 @@ export async function batchCreateAclRecords(requests, options) {
269
269
  *
270
270
  * @example
271
271
  * ```typescript
272
- * import { updateAclRecord } from '@tale/client';
272
+ * import { updateAclRecord } from '@turinhub/tale-js-sdk';
273
273
  *
274
274
  * try {
275
- * const record = await updateAclRecord('record_id_here', {
276
- * effect_type: 'deny',
275
+ * const record = await updateAclRecord('recordId_here', {
276
+ * effectType: 'deny',
277
277
  * priority: 100
278
278
  * });
279
- * console.log('Record updated:', record.record_id);
279
+ * console.log('Record updated:', record.recordId);
280
280
  * } catch (error) {
281
281
  * console.error('Failed to update ACL record:', error.message);
282
282
  * }
@@ -284,7 +284,7 @@ export async function batchCreateAclRecords(requests, options) {
284
284
  */
285
285
  export async function updateAclRecord(recordId, request, options) {
286
286
  if (!recordId || recordId.trim() === "") {
287
- throw new ApiError("record_id is required", 400, "9400");
287
+ throw new ApiError("recordId is required", 400, "9400");
288
288
  }
289
289
  const token = options?.appToken ?? (await getAppToken(options));
290
290
  const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
@@ -323,10 +323,10 @@ export async function updateAclRecord(recordId, request, options) {
323
323
  *
324
324
  * @example
325
325
  * ```typescript
326
- * import { deleteAclRecord } from '@tale/client';
326
+ * import { deleteAclRecord } from '@turinhub/tale-js-sdk';
327
327
  *
328
328
  * try {
329
- * await deleteAclRecord('record_id_here');
329
+ * await deleteAclRecord('recordId_here');
330
330
  * console.log('ACL record deleted successfully');
331
331
  * } catch (error) {
332
332
  * console.error('Failed to delete ACL record:', error.message);
@@ -335,7 +335,7 @@ export async function updateAclRecord(recordId, request, options) {
335
335
  */
336
336
  export async function deleteAclRecord(recordId, options) {
337
337
  if (!recordId || recordId.trim() === "") {
338
- throw new ApiError("record_id is required", 400, "9400");
338
+ throw new ApiError("recordId is required", 400, "9400");
339
339
  }
340
340
  const token = options?.appToken ?? (await getAppToken(options));
341
341
  const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
@@ -384,11 +384,11 @@ export async function deleteAclRecord(recordId, options) {
384
384
  *
385
385
  * @example
386
386
  * ```typescript
387
- * import { getAclTemplate } from '@tale/client';
387
+ * import { getAclTemplate } from '@turinhub/tale-js-sdk';
388
388
  *
389
389
  * try {
390
- * const template = await getAclTemplate('template_code_here');
391
- * console.log('Template name:', template.template_name);
390
+ * const template = await getAclTemplate('templateCode_here');
391
+ * console.log('Template name:', template.templateName);
392
392
  * } catch (error) {
393
393
  * console.error('Failed to get ACL template:', error.message);
394
394
  * }
@@ -396,7 +396,7 @@ export async function deleteAclRecord(recordId, options) {
396
396
  */
397
397
  export async function getAclTemplate(templateId, options) {
398
398
  if (!templateId || templateId.trim() === "") {
399
- throw new ApiError("template_id is required", 400, "9400");
399
+ throw new ApiError("templateId is required", 400, "9400");
400
400
  }
401
401
  const token = options?.appToken ?? (await getAppToken(options));
402
402
  const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
@@ -405,7 +405,7 @@ export async function getAclTemplate(templateId, options) {
405
405
  throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
406
406
  }
407
407
  const url = String(base).replace(/\/+$/, "") +
408
- `/acl/v1/templates/${encodeURIComponent(templateId)}`;
408
+ `/acl/v2/templates/${encodeURIComponent(templateId)}`;
409
409
  let response;
410
410
  try {
411
411
  response = await globalThis.fetch(url, {
@@ -433,13 +433,13 @@ export async function getAclTemplate(templateId, options) {
433
433
  *
434
434
  * @example
435
435
  * ```typescript
436
- * import { listAclTemplates } from '@tale/client';
436
+ * import { listAclTemplates } from '@turinhub/tale-js-sdk';
437
437
  *
438
438
  * try {
439
439
  * const result = await listAclTemplates({
440
440
  * page: 0,
441
441
  * size: 20,
442
- * resource_type: 'document'
442
+ * resourceType: 'document'
443
443
  * });
444
444
  * console.log(`Found ${result.total} templates`);
445
445
  * } catch (error) {
@@ -496,28 +496,28 @@ export async function listAclTemplates(options) {
496
496
  *
497
497
  * @example
498
498
  * ```typescript
499
- * import { createAclTemplate } from '@tale/client';
499
+ * import { createAclTemplate } from '@turinhub/tale-js-sdk';
500
500
  *
501
501
  * try {
502
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'
503
+ * templateName: 'Document Access',
504
+ * templateCode: 'doc_access',
505
+ * subjectType: 'user',
506
+ * resourceType: 'document',
507
+ * effectType: 'allow'
508
508
  * });
509
- * console.log('Template created:', template.template_id);
509
+ * console.log('Template created:', template.templateId);
510
510
  * } catch (error) {
511
511
  * console.error('Failed to create ACL template:', error.message);
512
512
  * }
513
513
  * ```
514
514
  */
515
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");
516
+ if (!request.templateName || request.templateName.trim() === "") {
517
+ throw new ApiError("templateName is required", 400, "9400");
518
518
  }
519
- if (!request.template_code || request.template_code.trim() === "") {
520
- throw new ApiError("template_code is required", 400, "9400");
519
+ if (!request.templateCode || request.templateCode.trim() === "") {
520
+ throw new ApiError("templateCode is required", 400, "9400");
521
521
  }
522
522
  const token = options?.appToken ?? (await getAppToken(options));
523
523
  const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
@@ -525,7 +525,7 @@ export async function createAclTemplate(request, options) {
525
525
  if (!base) {
526
526
  throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
527
527
  }
528
- const url = String(base).replace(/\/+$/, "") + "/acl/v1/templates";
528
+ const url = String(base).replace(/\/+$/, "") + "/acl/v2/templates";
529
529
  let response;
530
530
  try {
531
531
  response = await globalThis.fetch(url, {
@@ -556,14 +556,14 @@ export async function createAclTemplate(request, options) {
556
556
  *
557
557
  * @example
558
558
  * ```typescript
559
- * import { updateAclTemplate } from '@tale/client';
559
+ * import { updateAclTemplate } from '@turinhub/tale-js-sdk';
560
560
  *
561
561
  * try {
562
- * const template = await updateAclTemplate('template_code_here', {
563
- * template_name: 'Updated Template Name',
564
- * effect_type: 'deny'
562
+ * const template = await updateAclTemplate('templateCode_here', {
563
+ * templateName: 'Updated Template Name',
564
+ * effectType: 'deny'
565
565
  * });
566
- * console.log('Template updated:', template.template_id);
566
+ * console.log('Template updated:', template.templateId);
567
567
  * } catch (error) {
568
568
  * console.error('Failed to update ACL template:', error.message);
569
569
  * }
@@ -571,7 +571,7 @@ export async function createAclTemplate(request, options) {
571
571
  */
572
572
  export async function updateAclTemplate(templateId, request, options) {
573
573
  if (!templateId || templateId.trim() === "") {
574
- throw new ApiError("template_id is required", 400, "9400");
574
+ throw new ApiError("templateId is required", 400, "9400");
575
575
  }
576
576
  const token = options?.appToken ?? (await getAppToken(options));
577
577
  const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
@@ -580,7 +580,7 @@ export async function updateAclTemplate(templateId, request, options) {
580
580
  throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
581
581
  }
582
582
  const url = String(base).replace(/\/+$/, "") +
583
- `/acl/v1/templates/${encodeURIComponent(templateId)}`;
583
+ `/acl/v2/templates/${encodeURIComponent(templateId)}`;
584
584
  let response;
585
585
  try {
586
586
  response = await globalThis.fetch(url, {
@@ -610,10 +610,10 @@ export async function updateAclTemplate(templateId, request, options) {
610
610
  *
611
611
  * @example
612
612
  * ```typescript
613
- * import { deleteAclTemplate } from '@tale/client';
613
+ * import { deleteAclTemplate } from '@turinhub/tale-js-sdk';
614
614
  *
615
615
  * try {
616
- * await deleteAclTemplate('template_code_here');
616
+ * await deleteAclTemplate('templateCode_here');
617
617
  * console.log('ACL template deleted successfully');
618
618
  * } catch (error) {
619
619
  * console.error('Failed to delete ACL template:', error.message);
@@ -622,7 +622,7 @@ export async function updateAclTemplate(templateId, request, options) {
622
622
  */
623
623
  export async function deleteAclTemplate(templateId, options) {
624
624
  if (!templateId || templateId.trim() === "") {
625
- throw new ApiError("template_id is required", 400, "9400");
625
+ throw new ApiError("templateId is required", 400, "9400");
626
626
  }
627
627
  const token = options?.appToken ?? (await getAppToken(options));
628
628
  const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
@@ -631,7 +631,7 @@ export async function deleteAclTemplate(templateId, options) {
631
631
  throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
632
632
  }
633
633
  const url = String(base).replace(/\/+$/, "") +
634
- `/acl/v1/templates/${encodeURIComponent(templateId)}`;
634
+ `/acl/v2/templates/${encodeURIComponent(templateId)}`;
635
635
  let response;
636
636
  try {
637
637
  response = await globalThis.fetch(url, {
@@ -651,3 +651,198 @@ export async function deleteAclTemplate(templateId, options) {
651
651
  throw new ApiError(errorMsg, response.status, json.code);
652
652
  }
653
653
  }
654
+ // ==================== ACL Record Attachment Functions ====================
655
+ /** List attachments for an ACL record */
656
+ export async function listAclRecordAttachments(recordId, options) {
657
+ if (!recordId || recordId.trim() === "") {
658
+ throw new ApiError("recordId is required", 400, "9400");
659
+ }
660
+ const token = options?.appToken ?? (await getAppToken(options));
661
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
662
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
663
+ if (!base) {
664
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
665
+ }
666
+ const url = new URL(String(base).replace(/\/+$/, "") +
667
+ `/acl/v2/records/${encodeURIComponent(recordId)}/attachments`);
668
+ const { appToken, baseUrl, ...requestParams } = options || {};
669
+ const queryParams = {
670
+ page: 0,
671
+ size: 20,
672
+ sort: "createdAt,desc",
673
+ ...requestParams,
674
+ };
675
+ Object.entries(queryParams).forEach(([key, value]) => {
676
+ if (value !== undefined) {
677
+ url.searchParams.append(key, String(value));
678
+ }
679
+ });
680
+ let response;
681
+ try {
682
+ response = await globalThis.fetch(url.toString(), {
683
+ method: "GET",
684
+ headers: {
685
+ "Content-Type": "application/json",
686
+ "x-t-token": token,
687
+ },
688
+ });
689
+ }
690
+ catch (error) {
691
+ throw new NetworkError(`Failed to list ACL record attachments: ${error instanceof Error ? error.message : "Unknown error"}`);
692
+ }
693
+ const json = await response.json();
694
+ if (typeof json !== "object" || json === null) {
695
+ throw new ApiError(`Invalid response: Failed to list ACL record attachments - not an object`, response.status);
696
+ }
697
+ const res = json;
698
+ if (res.code !== 200) {
699
+ const errorMsg = typeof res.msg === "string"
700
+ ? res.msg
701
+ : "Failed to list ACL record attachments";
702
+ throw new ApiError(errorMsg, response.status, res.code);
703
+ }
704
+ if (!res.data) {
705
+ throw new ApiError(`Invalid response: Failed to list ACL record attachments - missing data`, response.status);
706
+ }
707
+ return res.data;
708
+ }
709
+ /** Get a single attachment for an ACL record */
710
+ export async function getAclRecordAttachment(recordId, attachmentId, options) {
711
+ if (!recordId || recordId.trim() === "") {
712
+ throw new ApiError("recordId is required", 400, "9400");
713
+ }
714
+ if (!attachmentId || attachmentId.trim() === "") {
715
+ throw new ApiError("attachmentId is required", 400, "9400");
716
+ }
717
+ const token = options?.appToken ?? (await getAppToken(options));
718
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
719
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
720
+ if (!base) {
721
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
722
+ }
723
+ const url = String(base).replace(/\/+$/, "") +
724
+ `/acl/v2/records/${encodeURIComponent(recordId)}/attachments/${encodeURIComponent(attachmentId)}`;
725
+ let response;
726
+ try {
727
+ response = await globalThis.fetch(url, {
728
+ method: "GET",
729
+ headers: {
730
+ "Content-Type": "application/json",
731
+ "x-t-token": token,
732
+ },
733
+ });
734
+ }
735
+ catch (error) {
736
+ throw new NetworkError(`Failed to get ACL record attachment: ${error instanceof Error ? error.message : "Unknown error"}`);
737
+ }
738
+ const json = await response.json();
739
+ if (typeof json !== "object" || json === null) {
740
+ throw new ApiError(`Invalid response: Failed to get ACL record attachment - not an object`, response.status);
741
+ }
742
+ const res = json;
743
+ if (res.code !== 200) {
744
+ const errorMsg = typeof res.msg === "string"
745
+ ? res.msg
746
+ : "Failed to get ACL record attachment";
747
+ throw new ApiError(errorMsg, response.status, res.code);
748
+ }
749
+ if (!res.data) {
750
+ throw new ApiError(`Invalid response: Failed to get ACL record attachment - missing data`, response.status);
751
+ }
752
+ return res.data;
753
+ }
754
+ /** Upload attachment for an ACL record */
755
+ export async function uploadAclRecordAttachment(recordId, attachmentTypeId, file, remark, options) {
756
+ if (!recordId || recordId.trim() === "") {
757
+ throw new ApiError("recordId is required", 400, "9400");
758
+ }
759
+ if (!attachmentTypeId || attachmentTypeId.trim() === "") {
760
+ throw new ApiError("attachmentTypeId is required", 400, "9400");
761
+ }
762
+ if (!file) {
763
+ throw new ApiError("file is required", 400, "9400");
764
+ }
765
+ const token = options?.appToken ?? (await getAppToken(options));
766
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
767
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
768
+ if (!base) {
769
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
770
+ }
771
+ const url = String(base).replace(/\/+$/, "") +
772
+ `/acl/v2/records/${encodeURIComponent(recordId)}/attachments/${encodeURIComponent(attachmentTypeId)}`;
773
+ const formData = new FormData();
774
+ if (typeof File !== "undefined" && file instanceof File) {
775
+ formData.append("file", file, file.name);
776
+ }
777
+ else {
778
+ formData.append("file", file);
779
+ }
780
+ if (remark) {
781
+ formData.append("remark", remark);
782
+ }
783
+ let response;
784
+ try {
785
+ response = await globalThis.fetch(url, {
786
+ method: "POST",
787
+ headers: {
788
+ "x-t-token": token,
789
+ },
790
+ body: formData,
791
+ });
792
+ }
793
+ catch (error) {
794
+ throw new NetworkError(`Failed to upload ACL record attachment: ${error instanceof Error ? error.message : "Unknown error"}`);
795
+ }
796
+ const json = await response.json();
797
+ if (typeof json !== "object" || json === null) {
798
+ throw new ApiError(`Invalid response: Failed to upload ACL record attachment - not an object`, response.status);
799
+ }
800
+ const res = json;
801
+ if (res.code !== 200) {
802
+ const errorMsg = typeof res.msg === "string"
803
+ ? res.msg
804
+ : "Failed to upload ACL record attachment";
805
+ throw new ApiError(errorMsg, response.status, res.code);
806
+ }
807
+ if (!res.data) {
808
+ throw new ApiError(`Invalid response: Failed to upload ACL record attachment - missing data`, response.status);
809
+ }
810
+ return res.data;
811
+ }
812
+ /** Delete attachment from an ACL record */
813
+ export async function deleteAclRecordAttachment(recordId, attachmentId, options) {
814
+ if (!recordId || recordId.trim() === "") {
815
+ throw new ApiError("recordId is required", 400, "9400");
816
+ }
817
+ if (!attachmentId || attachmentId.trim() === "") {
818
+ throw new ApiError("attachmentId is required", 400, "9400");
819
+ }
820
+ const token = options?.appToken ?? (await getAppToken(options));
821
+ const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
822
+ const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
823
+ if (!base) {
824
+ throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
825
+ }
826
+ const url = String(base).replace(/\/+$/, "") +
827
+ `/acl/v2/records/${encodeURIComponent(recordId)}/attachments/${encodeURIComponent(attachmentId)}`;
828
+ let response;
829
+ try {
830
+ response = await globalThis.fetch(url, {
831
+ method: "DELETE",
832
+ headers: {
833
+ "Content-Type": "application/json",
834
+ "x-t-token": token,
835
+ },
836
+ });
837
+ }
838
+ catch (error) {
839
+ throw new NetworkError(`Failed to delete ACL record attachment: ${error instanceof Error ? error.message : "Unknown error"}`);
840
+ }
841
+ const json = (await response.json());
842
+ if (json.code !== 200) {
843
+ const errorMsg = typeof json.msg === "string"
844
+ ? json.msg
845
+ : "Failed to delete ACL record attachment";
846
+ throw new ApiError(errorMsg, response.status, json.code);
847
+ }
848
+ }