@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.
- package/LICENSE +21 -0
- package/README.md +56 -0
- package/dist/acl/index.d.ts +295 -0
- package/dist/acl/index.js +653 -0
- package/dist/acl/types.d.ts +142 -0
- package/dist/acl/types.js +1 -0
- package/dist/auth/index.d.ts +166 -0
- package/dist/auth/index.js +522 -0
- package/dist/auth/types.d.ts +127 -0
- package/dist/auth/types.js +1 -0
- package/dist/cms/file.d.ts +398 -0
- package/dist/cms/file.js +800 -0
- package/dist/cms/folder.d.ts +128 -0
- package/dist/cms/folder.js +294 -0
- package/dist/cms/index.d.ts +3 -0
- package/dist/cms/index.js +6 -0
- package/dist/cms/types.d.ts +157 -0
- package/dist/cms/types.js +1 -0
- package/dist/common/types.d.ts +91 -0
- package/dist/common/types.js +2 -0
- package/dist/errors.d.ts +52 -0
- package/dist/errors.js +109 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +12 -0
- package/dist/rbac/acl.d.ts +152 -0
- package/dist/rbac/acl.js +723 -0
- package/dist/rbac/index.d.ts +464 -0
- package/dist/rbac/index.js +1121 -0
- package/dist/rbac/rbac.d.ts +198 -0
- package/dist/rbac/rbac.js +984 -0
- package/dist/rbac/types.d.ts +125 -0
- package/dist/rbac/types.js +1 -0
- package/dist/rbac/user-group.d.ts +122 -0
- package/dist/rbac/user-group.js +570 -0
- package/dist/status.d.ts +40 -0
- package/dist/status.js +56 -0
- package/dist/task/index.d.ts +163 -0
- package/dist/task/index.js +495 -0
- package/dist/task/types.d.ts +116 -0
- package/dist/task/types.js +1 -0
- package/dist/task-type/index.d.ts +92 -0
- package/dist/task-type/index.js +256 -0
- package/dist/task-type/types.d.ts +54 -0
- package/dist/task-type/types.js +1 -0
- package/dist/token.d.ts +21 -0
- package/dist/token.js +114 -0
- package/dist/user/index.d.ts +267 -0
- package/dist/user/index.js +786 -0
- package/dist/user/types.d.ts +145 -0
- package/dist/user/types.js +1 -0
- package/dist/user-attribute/index.d.ts +186 -0
- package/dist/user-attribute/index.js +615 -0
- package/dist/user-attribute/types.d.ts +109 -0
- package/dist/user-attribute/types.js +1 -0
- package/dist/user-group/index.d.ts +231 -0
- package/dist/user-group/index.js +566 -0
- package/dist/user-group/types.d.ts +50 -0
- package/dist/user-group/types.js +1 -0
- 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
|
+
}
|