@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
package/dist/cms/file.js
ADDED
|
@@ -0,0 +1,800 @@
|
|
|
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
|
+
// ==================== File API Functions ====================
|
|
22
|
+
/**
|
|
23
|
+
* Gets a file by ID.
|
|
24
|
+
*
|
|
25
|
+
* @param fileId - File ID (UUID)
|
|
26
|
+
* @param options - Optional configuration
|
|
27
|
+
* @returns Promise resolving to file 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 { getFile } from '@tale/client';
|
|
35
|
+
*
|
|
36
|
+
* try {
|
|
37
|
+
* const file = await getFile('file_id_here');
|
|
38
|
+
* console.log('File name:', file.file_name);
|
|
39
|
+
* console.log('File type:', file.file_type);
|
|
40
|
+
* } catch (error) {
|
|
41
|
+
* console.error('Failed to get file:', error.message);
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export async function getFile(fileId, options) {
|
|
46
|
+
if (!fileId || fileId.trim() === "") {
|
|
47
|
+
throw new ApiError("fileId is required", 400, "9400");
|
|
48
|
+
}
|
|
49
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
50
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
51
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
52
|
+
if (!base) {
|
|
53
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
54
|
+
}
|
|
55
|
+
const url = String(base).replace(/\/+$/, "") +
|
|
56
|
+
`/cms/v1/files/${encodeURIComponent(fileId)}`;
|
|
57
|
+
let response;
|
|
58
|
+
try {
|
|
59
|
+
response = await globalThis.fetch(url, {
|
|
60
|
+
method: "GET",
|
|
61
|
+
headers: {
|
|
62
|
+
"Content-Type": "application/json",
|
|
63
|
+
"x-t-token": token,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
throw new NetworkError(`Failed to get file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
69
|
+
}
|
|
70
|
+
const json = await response.json();
|
|
71
|
+
return parseApiResponse(json, "Failed to get file", response.status);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Lists files with pagination.
|
|
75
|
+
*
|
|
76
|
+
* @param options - Optional parameters for pagination and filtering
|
|
77
|
+
* @returns Promise resolving to paginated file list
|
|
78
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
79
|
+
* @throws {ApiError} When API request fails
|
|
80
|
+
* @throws {NetworkError} When network request fails
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* import { listFiles } from '@tale/client';
|
|
85
|
+
*
|
|
86
|
+
* try {
|
|
87
|
+
* const result = await listFiles({
|
|
88
|
+
* folder_id: 'folder_id_here',
|
|
89
|
+
* page: 0,
|
|
90
|
+
* size: 20,
|
|
91
|
+
* sort_by: 'createdAt'
|
|
92
|
+
* });
|
|
93
|
+
* console.log(`Found ${result.total} files`);
|
|
94
|
+
* } catch (error) {
|
|
95
|
+
* console.error('Failed to list files:', error.message);
|
|
96
|
+
* }
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
export async function listFiles(options) {
|
|
100
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
101
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
102
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
103
|
+
if (!base) {
|
|
104
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
105
|
+
}
|
|
106
|
+
const { appToken, baseUrl, folder_id, ...requestParams } = options || {};
|
|
107
|
+
// If folder_id is provided, use folder-based endpoint
|
|
108
|
+
let url;
|
|
109
|
+
if (folder_id) {
|
|
110
|
+
url =
|
|
111
|
+
String(base).replace(/\/+$/, "") +
|
|
112
|
+
`/cms/v1/folders/${encodeURIComponent(folder_id)}/files`;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
url = String(base).replace(/\/+$/, "") + "/cms/v1/files";
|
|
116
|
+
}
|
|
117
|
+
const urlObj = new URL(url);
|
|
118
|
+
const queryParams = {
|
|
119
|
+
page: 0,
|
|
120
|
+
size: 10,
|
|
121
|
+
sort_by: "createdAt",
|
|
122
|
+
include_attachments: false,
|
|
123
|
+
...requestParams,
|
|
124
|
+
};
|
|
125
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
126
|
+
if (value !== undefined) {
|
|
127
|
+
urlObj.searchParams.append(key, String(value));
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
let response;
|
|
131
|
+
try {
|
|
132
|
+
response = await globalThis.fetch(urlObj.toString(), {
|
|
133
|
+
method: "GET",
|
|
134
|
+
headers: {
|
|
135
|
+
"Content-Type": "application/json",
|
|
136
|
+
"x-t-token": token,
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
throw new NetworkError(`Failed to list files: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
142
|
+
}
|
|
143
|
+
const json = await response.json();
|
|
144
|
+
return parseApiResponse(json, "Failed to list files", response.status);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Creates a new file.
|
|
148
|
+
*
|
|
149
|
+
* @param request - File creation request
|
|
150
|
+
* @param options - Optional configuration
|
|
151
|
+
* @returns Promise resolving to created file
|
|
152
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
153
|
+
* @throws {ApiError} When API request fails
|
|
154
|
+
* @throws {NetworkError} When network request fails
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* import { createFile } from '@tale/client';
|
|
159
|
+
*
|
|
160
|
+
* try {
|
|
161
|
+
* const file = await createFile({
|
|
162
|
+
* folder_id: 'folder_id_here',
|
|
163
|
+
* file_name: 'My Document',
|
|
164
|
+
* file_type: 'markdown',
|
|
165
|
+
* content: '# Hello World'
|
|
166
|
+
* });
|
|
167
|
+
* console.log('File created:', file.id);
|
|
168
|
+
* } catch (error) {
|
|
169
|
+
* console.error('Failed to create file:', error.message);
|
|
170
|
+
* }
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
export async function createFile(request, options) {
|
|
174
|
+
if (!request.folder_id || request.folder_id.trim() === "") {
|
|
175
|
+
throw new ApiError("folder_id is required", 400, "9400");
|
|
176
|
+
}
|
|
177
|
+
if (!request.file_name || request.file_name.trim() === "") {
|
|
178
|
+
throw new ApiError("file_name is required", 400, "9400");
|
|
179
|
+
}
|
|
180
|
+
if (!request.file_type || request.file_type.trim() === "") {
|
|
181
|
+
throw new ApiError("file_type is required", 400, "9400");
|
|
182
|
+
}
|
|
183
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
184
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
185
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
186
|
+
if (!base) {
|
|
187
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
188
|
+
}
|
|
189
|
+
const url = String(base).replace(/\/+$/, "") + "/cms/v1/files";
|
|
190
|
+
let response;
|
|
191
|
+
try {
|
|
192
|
+
response = await globalThis.fetch(url, {
|
|
193
|
+
method: "POST",
|
|
194
|
+
headers: {
|
|
195
|
+
"Content-Type": "application/json",
|
|
196
|
+
"x-t-token": token,
|
|
197
|
+
},
|
|
198
|
+
body: JSON.stringify(request),
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
throw new NetworkError(`Failed to create file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
203
|
+
}
|
|
204
|
+
const json = await response.json();
|
|
205
|
+
return parseApiResponse(json, "Failed to create file", response.status);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Updates an existing file.
|
|
209
|
+
*
|
|
210
|
+
* @param fileId - File ID to update
|
|
211
|
+
* @param request - Update request with fields to modify
|
|
212
|
+
* @param options - Optional configuration
|
|
213
|
+
* @returns Promise resolving to updated file
|
|
214
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
215
|
+
* @throws {ApiError} When API request fails
|
|
216
|
+
* @throws {NetworkError} When network request fails
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```typescript
|
|
220
|
+
* import { updateFile } from '@tale/client';
|
|
221
|
+
*
|
|
222
|
+
* try {
|
|
223
|
+
* const file = await updateFile('file_id_here', {
|
|
224
|
+
* file_name: 'Updated Name',
|
|
225
|
+
* remark: 'Updated remark'
|
|
226
|
+
* });
|
|
227
|
+
* console.log('File updated:', file.file_name);
|
|
228
|
+
* } catch (error) {
|
|
229
|
+
* console.error('Failed to update file:', error.message);
|
|
230
|
+
* }
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
export async function updateFile(fileId, request, options) {
|
|
234
|
+
if (!fileId || fileId.trim() === "") {
|
|
235
|
+
throw new ApiError("fileId is required", 400, "9400");
|
|
236
|
+
}
|
|
237
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
238
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
239
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
240
|
+
if (!base) {
|
|
241
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
242
|
+
}
|
|
243
|
+
const url = String(base).replace(/\/+$/, "") +
|
|
244
|
+
`/cms/v1/files/${encodeURIComponent(fileId)}`;
|
|
245
|
+
let response;
|
|
246
|
+
try {
|
|
247
|
+
response = await globalThis.fetch(url, {
|
|
248
|
+
method: "PUT",
|
|
249
|
+
headers: {
|
|
250
|
+
"Content-Type": "application/json",
|
|
251
|
+
"x-t-token": token,
|
|
252
|
+
},
|
|
253
|
+
body: JSON.stringify(request),
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
throw new NetworkError(`Failed to update file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
258
|
+
}
|
|
259
|
+
const json = await response.json();
|
|
260
|
+
return parseApiResponse(json, "Failed to update file", response.status);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Updates the Markdown content of a file.
|
|
264
|
+
*
|
|
265
|
+
* @param fileId - File ID to update
|
|
266
|
+
* @param content - New Markdown content
|
|
267
|
+
* @param options - Optional configuration
|
|
268
|
+
* @returns Promise resolving to updated file
|
|
269
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
270
|
+
* @throws {ApiError} When API request fails
|
|
271
|
+
* @throws {NetworkError} When network request fails
|
|
272
|
+
*
|
|
273
|
+
* @example
|
|
274
|
+
* ```typescript
|
|
275
|
+
* import { updateFileContent } from '@tale/client';
|
|
276
|
+
*
|
|
277
|
+
* try {
|
|
278
|
+
* const file = await updateFileContent('file_id_here', '# New Content');
|
|
279
|
+
* console.log('Content updated:', file.content);
|
|
280
|
+
* } catch (error) {
|
|
281
|
+
* console.error('Failed to update content:', error.message);
|
|
282
|
+
* }
|
|
283
|
+
* ```
|
|
284
|
+
*/
|
|
285
|
+
export async function updateFileContent(fileId, content, options) {
|
|
286
|
+
if (!fileId || fileId.trim() === "") {
|
|
287
|
+
throw new ApiError("fileId is required", 400, "9400");
|
|
288
|
+
}
|
|
289
|
+
if (content === undefined || content === null) {
|
|
290
|
+
throw new ApiError("content is required", 400, "9400");
|
|
291
|
+
}
|
|
292
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
293
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
294
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
295
|
+
if (!base) {
|
|
296
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
297
|
+
}
|
|
298
|
+
const url = String(base).replace(/\/+$/, "") +
|
|
299
|
+
`/cms/v1/files/${encodeURIComponent(fileId)}/content`;
|
|
300
|
+
let response;
|
|
301
|
+
try {
|
|
302
|
+
response = await globalThis.fetch(url, {
|
|
303
|
+
method: "PUT",
|
|
304
|
+
headers: {
|
|
305
|
+
"Content-Type": "application/json",
|
|
306
|
+
"x-t-token": token,
|
|
307
|
+
},
|
|
308
|
+
body: JSON.stringify({ content }),
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
throw new NetworkError(`Failed to update file content: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
313
|
+
}
|
|
314
|
+
const json = await response.json();
|
|
315
|
+
return parseApiResponse(json, "Failed to update file content", response.status);
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Deletes a file.
|
|
319
|
+
*
|
|
320
|
+
* @param fileId - File ID to delete
|
|
321
|
+
* @param options - Optional configuration
|
|
322
|
+
* @returns Promise that resolves when deletion is successful
|
|
323
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
324
|
+
* @throws {ApiError} When API request fails
|
|
325
|
+
* @throws {NetworkError} When network request fails
|
|
326
|
+
*
|
|
327
|
+
* @example
|
|
328
|
+
* ```typescript
|
|
329
|
+
* import { deleteFile } from '@tale/client';
|
|
330
|
+
*
|
|
331
|
+
* try {
|
|
332
|
+
* await deleteFile('file_id_here');
|
|
333
|
+
* console.log('File deleted successfully');
|
|
334
|
+
* } catch (error) {
|
|
335
|
+
* console.error('Failed to delete file:', error.message);
|
|
336
|
+
* }
|
|
337
|
+
* ```
|
|
338
|
+
*/
|
|
339
|
+
export async function deleteFile(fileId, options) {
|
|
340
|
+
if (!fileId || fileId.trim() === "") {
|
|
341
|
+
throw new ApiError("fileId is required", 400, "9400");
|
|
342
|
+
}
|
|
343
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
344
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
345
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
346
|
+
if (!base) {
|
|
347
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
348
|
+
}
|
|
349
|
+
const url = String(base).replace(/\/+$/, "") +
|
|
350
|
+
`/cms/v1/files/${encodeURIComponent(fileId)}`;
|
|
351
|
+
let response;
|
|
352
|
+
try {
|
|
353
|
+
response = await globalThis.fetch(url, {
|
|
354
|
+
method: "DELETE",
|
|
355
|
+
headers: {
|
|
356
|
+
"Content-Type": "application/json",
|
|
357
|
+
"x-t-token": token,
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
catch (error) {
|
|
362
|
+
throw new NetworkError(`Failed to delete file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
363
|
+
}
|
|
364
|
+
const json = (await response.json());
|
|
365
|
+
if (json.code !== 200) {
|
|
366
|
+
const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to delete file";
|
|
367
|
+
throw new ApiError(errorMsg, response.status, json.code);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Gets a presigned URL for file download.
|
|
372
|
+
*
|
|
373
|
+
* @param fileId - File ID
|
|
374
|
+
* @param expireTimeInSeconds - Expiration time in seconds (default: 3600)
|
|
375
|
+
* @param options - Optional configuration
|
|
376
|
+
* @returns Promise resolving to presigned URL information
|
|
377
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
378
|
+
* @throws {ApiError} When API request fails
|
|
379
|
+
* @throws {NetworkError} When network request fails
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
* ```typescript
|
|
383
|
+
* import { getFilePresignedUrl } from '@tale/client';
|
|
384
|
+
*
|
|
385
|
+
* try {
|
|
386
|
+
* const result = await getFilePresignedUrl('file_id_here', 3600);
|
|
387
|
+
* console.log('Presigned URL:', result.presigned_url);
|
|
388
|
+
* // Now you can download the file directly
|
|
389
|
+
* } catch (error) {
|
|
390
|
+
* console.error('Failed to get presigned URL:', error.message);
|
|
391
|
+
* }
|
|
392
|
+
* ```
|
|
393
|
+
*/
|
|
394
|
+
export async function getFilePresignedUrl(fileId, expireTimeInSeconds = 3600, options) {
|
|
395
|
+
if (!fileId || fileId.trim() === "") {
|
|
396
|
+
throw new ApiError("fileId is required", 400, "9400");
|
|
397
|
+
}
|
|
398
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
399
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
400
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
401
|
+
if (!base) {
|
|
402
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
403
|
+
}
|
|
404
|
+
const url = String(base).replace(/\/+$/, "") +
|
|
405
|
+
`/cms/v1/files/${encodeURIComponent(fileId)}/presigned-url`;
|
|
406
|
+
const urlObj = new URL(url);
|
|
407
|
+
if (expireTimeInSeconds !== undefined) {
|
|
408
|
+
urlObj.searchParams.append("expireTimeInSeconds", String(expireTimeInSeconds));
|
|
409
|
+
}
|
|
410
|
+
let response;
|
|
411
|
+
try {
|
|
412
|
+
response = await globalThis.fetch(urlObj.toString(), {
|
|
413
|
+
method: "GET",
|
|
414
|
+
headers: {
|
|
415
|
+
"Content-Type": "application/json",
|
|
416
|
+
"x-t-token": token,
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
catch (error) {
|
|
421
|
+
throw new NetworkError(`Failed to get presigned URL: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
422
|
+
}
|
|
423
|
+
const json = await response.json();
|
|
424
|
+
return parseApiResponse(json, "Failed to get presigned URL", response.status);
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Batch gets presigned URLs for multiple files.
|
|
428
|
+
*
|
|
429
|
+
* @param fileIds - Array of file IDs (max 10)
|
|
430
|
+
* @param expireTimeInSeconds - Expiration time in seconds (default: 3600)
|
|
431
|
+
* @param options - Optional configuration
|
|
432
|
+
* @returns Promise resolving to array of presigned URL information or errors
|
|
433
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
434
|
+
* @throws {ApiError} When API request fails
|
|
435
|
+
* @throws {NetworkError} When network request fails
|
|
436
|
+
*
|
|
437
|
+
* @example
|
|
438
|
+
* ```typescript
|
|
439
|
+
* import { batchGetFilePresignedUrl } from '@tale/client';
|
|
440
|
+
*
|
|
441
|
+
* try {
|
|
442
|
+
* const results = await batchGetFilePresignedUrl(
|
|
443
|
+
* ['file_id_1', 'file_id_2'],
|
|
444
|
+
* 3600
|
|
445
|
+
* );
|
|
446
|
+
* results.forEach(result => {
|
|
447
|
+
* if (result.error) {
|
|
448
|
+
* console.error('Error for file:', result.file_id, result.error);
|
|
449
|
+
* } else {
|
|
450
|
+
* console.log('URL:', result.presigned_url);
|
|
451
|
+
* }
|
|
452
|
+
* });
|
|
453
|
+
* } catch (error) {
|
|
454
|
+
* console.error('Failed to batch get presigned URLs:', error.message);
|
|
455
|
+
* }
|
|
456
|
+
* ```
|
|
457
|
+
*/
|
|
458
|
+
export async function batchGetFilePresignedUrl(fileIds, expireTimeInSeconds = 3600, options) {
|
|
459
|
+
if (!fileIds || fileIds.length === 0) {
|
|
460
|
+
throw new ApiError("fileIds is required", 400, "9400");
|
|
461
|
+
}
|
|
462
|
+
if (fileIds.length > 10) {
|
|
463
|
+
throw new ApiError("Too many file IDs, max 10 allowed", 400, "9400");
|
|
464
|
+
}
|
|
465
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
466
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
467
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
468
|
+
if (!base) {
|
|
469
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
470
|
+
}
|
|
471
|
+
const url = String(base).replace(/\/+$/, "") + "/cms/v1/files/batch-presigned-url";
|
|
472
|
+
let response;
|
|
473
|
+
try {
|
|
474
|
+
response = await globalThis.fetch(url, {
|
|
475
|
+
method: "POST",
|
|
476
|
+
headers: {
|
|
477
|
+
"Content-Type": "application/json",
|
|
478
|
+
"x-t-token": token,
|
|
479
|
+
},
|
|
480
|
+
body: JSON.stringify({
|
|
481
|
+
file_ids: fileIds,
|
|
482
|
+
expire_time_in_seconds: expireTimeInSeconds,
|
|
483
|
+
}),
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
catch (error) {
|
|
487
|
+
throw new NetworkError(`Failed to batch get presigned URLs: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
488
|
+
}
|
|
489
|
+
const json = await response.json();
|
|
490
|
+
return parseApiResponse(json, "Failed to batch get presigned URLs", response.status);
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Gets OSS object metadata.
|
|
494
|
+
*
|
|
495
|
+
* @param ossKey - OSS key
|
|
496
|
+
* @param options - Optional configuration
|
|
497
|
+
* @returns Promise resolving to OSS metadata
|
|
498
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
499
|
+
* @throws {ApiError} When API request fails
|
|
500
|
+
* @throws {NetworkError} When network request fails
|
|
501
|
+
*
|
|
502
|
+
* @example
|
|
503
|
+
* ```typescript
|
|
504
|
+
* import { getOssMetadata } from '@tale/client';
|
|
505
|
+
*
|
|
506
|
+
* try {
|
|
507
|
+
* const metadata = await getOssMetadata('cms/appkey/folder/fileid.pdf');
|
|
508
|
+
* console.log('File size:', metadata.content_length);
|
|
509
|
+
* console.log('Content type:', metadata.content_type);
|
|
510
|
+
* } catch (error) {
|
|
511
|
+
* console.error('Failed to get OSS metadata:', error.message);
|
|
512
|
+
* }
|
|
513
|
+
* ```
|
|
514
|
+
*/
|
|
515
|
+
export async function getOssMetadata(ossKey, options) {
|
|
516
|
+
if (!ossKey || ossKey.trim() === "") {
|
|
517
|
+
throw new ApiError("ossKey is required", 400, "9400");
|
|
518
|
+
}
|
|
519
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
520
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
521
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
522
|
+
if (!base) {
|
|
523
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
524
|
+
}
|
|
525
|
+
const url = new URL(String(base).replace(/\/+$/, "") + "/cms/v1/oss/metadata");
|
|
526
|
+
url.searchParams.append("key", ossKey);
|
|
527
|
+
let response;
|
|
528
|
+
try {
|
|
529
|
+
response = await globalThis.fetch(url.toString(), {
|
|
530
|
+
method: "GET",
|
|
531
|
+
headers: {
|
|
532
|
+
"Content-Type": "application/json",
|
|
533
|
+
"x-t-token": token,
|
|
534
|
+
},
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
catch (error) {
|
|
538
|
+
throw new NetworkError(`Failed to get OSS metadata: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
539
|
+
}
|
|
540
|
+
const json = await response.json();
|
|
541
|
+
return parseApiResponse(json, "Failed to get OSS metadata", response.status);
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Gets upload authorization for a new file (presets OSS key + presigned upload URL).
|
|
545
|
+
*
|
|
546
|
+
* @param request - Upload authorization request
|
|
547
|
+
* @param options - Optional configuration
|
|
548
|
+
* @returns Promise resolving to upload authorization response
|
|
549
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
550
|
+
* @throws {ApiError} When API request fails
|
|
551
|
+
* @throws {NetworkError} When network request fails
|
|
552
|
+
*
|
|
553
|
+
* @example
|
|
554
|
+
* ```typescript
|
|
555
|
+
* import { getUploadAuthorization } from '@tale/client';
|
|
556
|
+
*
|
|
557
|
+
* try {
|
|
558
|
+
* const auth = await getUploadAuthorization({
|
|
559
|
+
* folder_id: 'folder_id_here',
|
|
560
|
+
* file_name: 'document.pdf',
|
|
561
|
+
* file_type: 'pdf'
|
|
562
|
+
* });
|
|
563
|
+
* console.log('OSS Key:', auth.oss_key);
|
|
564
|
+
* console.log('Upload URL:', auth.presigned_url);
|
|
565
|
+
* console.log('File ID:', auth.file_id);
|
|
566
|
+
* // Use presigned_url to upload the file directly to OSS
|
|
567
|
+
* } catch (error) {
|
|
568
|
+
* console.error('Failed to get upload authorization:', error.message);
|
|
569
|
+
* }
|
|
570
|
+
* ```
|
|
571
|
+
*/
|
|
572
|
+
export async function getUploadAuthorization(request, options) {
|
|
573
|
+
if (!request.folder_id || request.folder_id.trim() === "") {
|
|
574
|
+
throw new ApiError("folder_id is required", 400, "9400");
|
|
575
|
+
}
|
|
576
|
+
if (!request.file_name || request.file_name.trim() === "") {
|
|
577
|
+
throw new ApiError("file_name is required", 400, "9400");
|
|
578
|
+
}
|
|
579
|
+
if (!request.file_type || request.file_type.trim() === "") {
|
|
580
|
+
throw new ApiError("file_type is required", 400, "9400");
|
|
581
|
+
}
|
|
582
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
583
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
584
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
585
|
+
if (!base) {
|
|
586
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
587
|
+
}
|
|
588
|
+
const url = String(base).replace(/\/+$/, "") + "/cms/v1/files/upload-authorization";
|
|
589
|
+
let response;
|
|
590
|
+
try {
|
|
591
|
+
response = await globalThis.fetch(url, {
|
|
592
|
+
method: "POST",
|
|
593
|
+
headers: {
|
|
594
|
+
"Content-Type": "application/json",
|
|
595
|
+
"x-t-token": token,
|
|
596
|
+
},
|
|
597
|
+
body: JSON.stringify(request),
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
catch (error) {
|
|
601
|
+
throw new NetworkError(`Failed to get upload authorization: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
602
|
+
}
|
|
603
|
+
const json = await response.json();
|
|
604
|
+
return parseApiResponse(json, "Failed to get upload authorization", response.status);
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Gets STS credentials for uploading to an existing file.
|
|
608
|
+
*
|
|
609
|
+
* @param fileId - File ID
|
|
610
|
+
* @param fileExtension - File extension (e.g., ".pdf")
|
|
611
|
+
* @param durationSeconds - Credential duration in seconds (default: 1800)
|
|
612
|
+
* @param options - Optional configuration
|
|
613
|
+
* @returns Promise resolving to STS credentials
|
|
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 { getFileStsCredentials } from '@tale/client';
|
|
621
|
+
*
|
|
622
|
+
* try {
|
|
623
|
+
* const credentials = await getFileStsCredentials('file_id_here', '.pdf', 1800);
|
|
624
|
+
* console.log('Access Key ID:', credentials.access_key_id);
|
|
625
|
+
* console.log('Secret Access Key:', credentials.secret_access_key);
|
|
626
|
+
* console.log('Session Token:', credentials.session_token);
|
|
627
|
+
* console.log('Upload Path:', credentials.upload_path);
|
|
628
|
+
* // Use these credentials to upload with OSS SDK
|
|
629
|
+
* } catch (error) {
|
|
630
|
+
* console.error('Failed to get STS credentials:', error.message);
|
|
631
|
+
* }
|
|
632
|
+
* ```
|
|
633
|
+
*/
|
|
634
|
+
export async function getFileStsCredentials(fileId, fileExtension, durationSeconds = 1800, options) {
|
|
635
|
+
if (!fileId || fileId.trim() === "") {
|
|
636
|
+
throw new ApiError("fileId is required", 400, "9400");
|
|
637
|
+
}
|
|
638
|
+
if (!fileExtension || fileExtension.trim() === "") {
|
|
639
|
+
throw new ApiError("fileExtension is required", 400, "9400");
|
|
640
|
+
}
|
|
641
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
642
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
643
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
644
|
+
if (!base) {
|
|
645
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
646
|
+
}
|
|
647
|
+
const url = String(base).replace(/\/+$/, "") +
|
|
648
|
+
`/cms/v1/files/${encodeURIComponent(fileId)}/sts-credentials`;
|
|
649
|
+
let response;
|
|
650
|
+
try {
|
|
651
|
+
response = await globalThis.fetch(url, {
|
|
652
|
+
method: "POST",
|
|
653
|
+
headers: {
|
|
654
|
+
"Content-Type": "application/json",
|
|
655
|
+
"x-t-token": token,
|
|
656
|
+
},
|
|
657
|
+
body: JSON.stringify({
|
|
658
|
+
file_extension: fileExtension,
|
|
659
|
+
duration_seconds: durationSeconds,
|
|
660
|
+
}),
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
catch (error) {
|
|
664
|
+
throw new NetworkError(`Failed to get STS credentials: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
665
|
+
}
|
|
666
|
+
const json = await response.json();
|
|
667
|
+
return parseApiResponse(json, "Failed to get STS credentials", response.status);
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* Marks file upload as complete and updates OSS information.
|
|
671
|
+
*
|
|
672
|
+
* @param fileId - File ID
|
|
673
|
+
* @param request - Upload completion information
|
|
674
|
+
* @param options - Optional configuration
|
|
675
|
+
* @returns Promise resolving to success message
|
|
676
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
677
|
+
* @throws {ApiError} When API request fails
|
|
678
|
+
* @throws {NetworkError} When network request fails
|
|
679
|
+
*
|
|
680
|
+
* @example
|
|
681
|
+
* ```typescript
|
|
682
|
+
* import { fileUploadComplete } from '@tale/client';
|
|
683
|
+
*
|
|
684
|
+
* try {
|
|
685
|
+
* const result = await fileUploadComplete('file_id_here', {
|
|
686
|
+
* oss_key: 'cms/appkey/folder/fileid.pdf',
|
|
687
|
+
* file_size: 12345,
|
|
688
|
+
* etag: 'abc123'
|
|
689
|
+
* });
|
|
690
|
+
* console.log('Upload complete:', result.message);
|
|
691
|
+
* } catch (error) {
|
|
692
|
+
* console.error('Failed to mark upload complete:', error.message);
|
|
693
|
+
* }
|
|
694
|
+
* ```
|
|
695
|
+
*/
|
|
696
|
+
export async function fileUploadComplete(fileId, request, options) {
|
|
697
|
+
if (!fileId || fileId.trim() === "") {
|
|
698
|
+
throw new ApiError("fileId is required", 400, "9400");
|
|
699
|
+
}
|
|
700
|
+
if (!request.oss_key || request.oss_key.trim() === "") {
|
|
701
|
+
throw new ApiError("oss_key is required", 400, "9400");
|
|
702
|
+
}
|
|
703
|
+
if (!request.file_size && request.file_size !== 0) {
|
|
704
|
+
throw new ApiError("file_size is required", 400, "9400");
|
|
705
|
+
}
|
|
706
|
+
if (!request.etag || request.etag.trim() === "") {
|
|
707
|
+
throw new ApiError("etag is required", 400, "9400");
|
|
708
|
+
}
|
|
709
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
710
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
711
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
712
|
+
if (!base) {
|
|
713
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
714
|
+
}
|
|
715
|
+
const url = String(base).replace(/\/+$/, "") +
|
|
716
|
+
`/cms/v1/files/${encodeURIComponent(fileId)}/upload-complete`;
|
|
717
|
+
let response;
|
|
718
|
+
try {
|
|
719
|
+
response = await globalThis.fetch(url, {
|
|
720
|
+
method: "POST",
|
|
721
|
+
headers: {
|
|
722
|
+
"Content-Type": "application/json",
|
|
723
|
+
"x-t-token": token,
|
|
724
|
+
},
|
|
725
|
+
body: JSON.stringify(request),
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
catch (error) {
|
|
729
|
+
throw new NetworkError(`Failed to mark upload complete: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
730
|
+
}
|
|
731
|
+
const json = await response.json();
|
|
732
|
+
return parseApiResponse(json, "Failed to mark upload complete", response.status);
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Sets a preview image for a file.
|
|
736
|
+
*
|
|
737
|
+
* @param fileId - File ID
|
|
738
|
+
* @param imageFile - Image file to upload (File or Blob)
|
|
739
|
+
* @param options - Optional configuration
|
|
740
|
+
* @returns Promise resolving to updated file
|
|
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 { setFilePreviewImage } from '@tale/client';
|
|
748
|
+
*
|
|
749
|
+
* try {
|
|
750
|
+
* // Get file from input element
|
|
751
|
+
* const input = document.getElementById('previewInput');
|
|
752
|
+
* const file = input.files[0];
|
|
753
|
+
*
|
|
754
|
+
* const updatedFile = await setFilePreviewImage('file_id_here', file);
|
|
755
|
+
* console.log('Preview image set:', updatedFile.preview_image_url);
|
|
756
|
+
* } catch (error) {
|
|
757
|
+
* console.error('Failed to set preview image:', error.message);
|
|
758
|
+
* }
|
|
759
|
+
* ```
|
|
760
|
+
*/
|
|
761
|
+
export async function setFilePreviewImage(fileId, imageFile, options) {
|
|
762
|
+
if (!fileId || fileId.trim() === "") {
|
|
763
|
+
throw new ApiError("fileId is required", 400, "9400");
|
|
764
|
+
}
|
|
765
|
+
if (!imageFile) {
|
|
766
|
+
throw new ApiError("imageFile is required", 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
|
+
`/cms/v1/files/${encodeURIComponent(fileId)}/preview-image`;
|
|
776
|
+
// Create FormData
|
|
777
|
+
const formData = new FormData();
|
|
778
|
+
// Handle File type which extends Blob
|
|
779
|
+
if (typeof File !== "undefined" && imageFile instanceof File) {
|
|
780
|
+
formData.append("file", imageFile, imageFile.name);
|
|
781
|
+
}
|
|
782
|
+
else {
|
|
783
|
+
formData.append("file", imageFile);
|
|
784
|
+
}
|
|
785
|
+
let response;
|
|
786
|
+
try {
|
|
787
|
+
response = await globalThis.fetch(url, {
|
|
788
|
+
method: "POST",
|
|
789
|
+
headers: {
|
|
790
|
+
"x-t-token": token,
|
|
791
|
+
},
|
|
792
|
+
body: formData,
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
catch (error) {
|
|
796
|
+
throw new NetworkError(`Failed to set preview image: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
797
|
+
}
|
|
798
|
+
const json = await response.json();
|
|
799
|
+
return parseApiResponse(json, "Failed to set preview image", response.status);
|
|
800
|
+
}
|