tale-js-sdk 0.1.2 → 0.1.4
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/dist/acl/index.d.ts +170 -0
- package/dist/acl/index.js +747 -0
- package/dist/acl/types.d.ts +208 -0
- package/dist/acl/types.js +1 -0
- package/dist/auth/index.d.ts +2 -134
- package/dist/auth/index.js +120 -96
- package/dist/auth/types.d.ts +122 -0
- package/dist/auth/types.js +1 -0
- package/dist/common/types.d.ts +82 -0
- package/dist/common/types.js +2 -0
- package/dist/errors.js +18 -18
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/rbac/acl.d.ts +152 -0
- package/dist/rbac/acl.js +723 -0
- package/dist/rbac/index.d.ts +2 -0
- package/dist/rbac/index.js +2 -0
- package/dist/rbac/rbac.d.ts +198 -0
- package/dist/rbac/rbac.js +984 -0
- package/dist/rbac/types.d.ts +356 -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.js +3 -3
- package/dist/token.d.ts +1 -1
- package/dist/token.js +5 -4
- package/dist/user/index.d.ts +165 -142
- package/dist/user/index.js +511 -59
- package/dist/user/types.d.ts +149 -0
- package/dist/user/types.js +1 -0
- package/dist/user-group/index.d.ts +230 -0
- package/dist/user-group/index.js +560 -0
- package/dist/user-group/types.d.ts +64 -0
- package/dist/user-group/types.js +1 -0
- package/package.json +4 -3
- package/dist/auth.d.ts +0 -271
- package/dist/auth.js +0 -461
- package/dist/client.d.ts +0 -20
- package/dist/client.js +0 -62
- package/dist/info.d.ts +0 -9
- package/dist/info.js +0 -18
- package/dist/package.json +0 -36
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.js +0 -1
- package/dist/src/info.d.ts +0 -6
- package/dist/src/info.js +0 -4
- package/dist/user.d.ts +0 -242
- package/dist/user.js +0 -331
package/dist/user/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getAppToken } from
|
|
2
|
-
import { ApiError, ConfigurationError, NetworkError } from
|
|
1
|
+
import { getAppToken } from "../token.js";
|
|
2
|
+
import { ApiError, ConfigurationError, NetworkError } from "../errors.js";
|
|
3
3
|
/**
|
|
4
4
|
* Creates a new user in the Tale application.
|
|
5
5
|
*
|
|
@@ -28,31 +28,31 @@ import { ApiError, ConfigurationError, NetworkError } from '../errors.js';
|
|
|
28
28
|
*/
|
|
29
29
|
export async function createUser(userData, options) {
|
|
30
30
|
// Validate required fields
|
|
31
|
-
if (!userData.username || userData.username.trim() ===
|
|
32
|
-
throw new ApiError(
|
|
31
|
+
if (!userData.username || userData.username.trim() === "") {
|
|
32
|
+
throw new ApiError("username is required", 400, "9400");
|
|
33
33
|
}
|
|
34
34
|
// Use provided app token or get one from token service
|
|
35
|
-
const token = options?.appToken ?? await getAppToken(options);
|
|
35
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
36
36
|
// Determine base URL
|
|
37
37
|
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
38
38
|
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
39
39
|
if (!base) {
|
|
40
|
-
throw new ConfigurationError(
|
|
40
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
41
41
|
}
|
|
42
|
-
const url = String(base).replace(/\/+$/,
|
|
42
|
+
const url = String(base).replace(/\/+$/, "") + "/account/v1/user";
|
|
43
43
|
let response;
|
|
44
44
|
try {
|
|
45
45
|
response = await globalThis.fetch(url, {
|
|
46
|
-
method:
|
|
46
|
+
method: "POST",
|
|
47
47
|
headers: {
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
"Content-Type": "application/json",
|
|
49
|
+
"x-t-token": token,
|
|
50
50
|
},
|
|
51
51
|
body: JSON.stringify(userData),
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
54
|
catch (error) {
|
|
55
|
-
throw new NetworkError(`Failed to create user: ${error instanceof Error ? error.message :
|
|
55
|
+
throw new NetworkError(`Failed to create user: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
56
56
|
}
|
|
57
57
|
let json;
|
|
58
58
|
try {
|
|
@@ -60,16 +60,16 @@ export async function createUser(userData, options) {
|
|
|
60
60
|
json = responseJson;
|
|
61
61
|
}
|
|
62
62
|
catch (error) {
|
|
63
|
-
throw new ApiError(`Failed to parse user creation response: ${error instanceof Error ? error.message :
|
|
63
|
+
throw new ApiError(`Failed to parse user creation response: ${error instanceof Error ? error.message : "Invalid JSON"}`, response.status);
|
|
64
64
|
}
|
|
65
65
|
// Handle API errors
|
|
66
66
|
if (json.code !== 200) {
|
|
67
|
-
const errorMsg = typeof json.msg ===
|
|
67
|
+
const errorMsg = typeof json.msg === "string" ? json.msg : "User creation failed";
|
|
68
68
|
throw new ApiError(errorMsg, response.status, json.code);
|
|
69
69
|
}
|
|
70
70
|
// Validate response structure
|
|
71
71
|
if (!json.data || !json.data.user || !json.data.app) {
|
|
72
|
-
throw new ApiError(
|
|
72
|
+
throw new ApiError("Invalid user creation response: missing required data", response.status);
|
|
73
73
|
}
|
|
74
74
|
return json.data;
|
|
75
75
|
}
|
|
@@ -97,15 +97,15 @@ export async function createUser(userData, options) {
|
|
|
97
97
|
*/
|
|
98
98
|
export async function getUserById(userId, options) {
|
|
99
99
|
// Use provided app token or get one from token service
|
|
100
|
-
const token = options?.appToken ?? await getAppToken(options);
|
|
100
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
101
101
|
// Determine base URL
|
|
102
102
|
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
103
103
|
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
104
104
|
if (!base) {
|
|
105
|
-
throw new ConfigurationError(
|
|
105
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
106
106
|
}
|
|
107
107
|
// Build URL with query parameters
|
|
108
|
-
const url = new URL(String(base).replace(/\/+$/,
|
|
108
|
+
const url = new URL(String(base).replace(/\/+$/, "") + "/account/v1/user");
|
|
109
109
|
// Add query parameters
|
|
110
110
|
const queryParams = {
|
|
111
111
|
user_id: userId,
|
|
@@ -113,7 +113,7 @@ export async function getUserById(userId, options) {
|
|
|
113
113
|
include_login_methods: true,
|
|
114
114
|
include_user_groups: true,
|
|
115
115
|
include_acl: false,
|
|
116
|
-
...options
|
|
116
|
+
...options,
|
|
117
117
|
};
|
|
118
118
|
Object.entries(queryParams).forEach(([key, value]) => {
|
|
119
119
|
if (value !== undefined) {
|
|
@@ -123,15 +123,15 @@ export async function getUserById(userId, options) {
|
|
|
123
123
|
let response;
|
|
124
124
|
try {
|
|
125
125
|
response = await globalThis.fetch(url.toString(), {
|
|
126
|
-
method:
|
|
126
|
+
method: "GET",
|
|
127
127
|
headers: {
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
"Content-Type": "application/json",
|
|
129
|
+
"x-t-token": token,
|
|
130
130
|
},
|
|
131
131
|
});
|
|
132
132
|
}
|
|
133
133
|
catch (error) {
|
|
134
|
-
throw new NetworkError(`Failed to get user: ${error instanceof Error ? error.message :
|
|
134
|
+
throw new NetworkError(`Failed to get user: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
135
135
|
}
|
|
136
136
|
let json;
|
|
137
137
|
try {
|
|
@@ -139,16 +139,16 @@ export async function getUserById(userId, options) {
|
|
|
139
139
|
json = responseJson;
|
|
140
140
|
}
|
|
141
141
|
catch (error) {
|
|
142
|
-
throw new ApiError(`Failed to parse user response: ${error instanceof Error ? error.message :
|
|
142
|
+
throw new ApiError(`Failed to parse user response: ${error instanceof Error ? error.message : "Invalid JSON"}`, response.status);
|
|
143
143
|
}
|
|
144
144
|
// Handle API errors
|
|
145
145
|
if (json.code !== 200) {
|
|
146
|
-
const errorMsg = typeof json.msg ===
|
|
146
|
+
const errorMsg = typeof json.msg === "string" ? json.msg : "User retrieval failed";
|
|
147
147
|
throw new ApiError(errorMsg, response.status, json.code);
|
|
148
148
|
}
|
|
149
149
|
// Validate response structure
|
|
150
150
|
if (!json.data || !json.data.user || !json.data.app) {
|
|
151
|
-
throw new ApiError(
|
|
151
|
+
throw new ApiError("Invalid user response: missing required data", response.status);
|
|
152
152
|
}
|
|
153
153
|
return json.data;
|
|
154
154
|
}
|
|
@@ -176,30 +176,31 @@ export async function getUserById(userId, options) {
|
|
|
176
176
|
*/
|
|
177
177
|
export async function deleteUser(userId, options) {
|
|
178
178
|
// Validate required fields
|
|
179
|
-
if (!userId || userId.trim() ===
|
|
180
|
-
throw new ApiError(
|
|
179
|
+
if (!userId || userId.trim() === "") {
|
|
180
|
+
throw new ApiError("user_id is required for deletion", 400, "9400");
|
|
181
181
|
}
|
|
182
182
|
// Use provided app token or get one from token service
|
|
183
|
-
const token = options?.appToken ?? await getAppToken(options);
|
|
183
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
184
184
|
// Determine base URL
|
|
185
185
|
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
186
186
|
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
187
187
|
if (!base) {
|
|
188
|
-
throw new ConfigurationError(
|
|
188
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
189
189
|
}
|
|
190
|
-
const url = String(base).replace(/\/+$/,
|
|
190
|
+
const url = String(base).replace(/\/+$/, "") +
|
|
191
|
+
`/account/v1/users/${encodeURIComponent(userId)}`;
|
|
191
192
|
let response;
|
|
192
193
|
try {
|
|
193
194
|
response = await globalThis.fetch(url, {
|
|
194
|
-
method:
|
|
195
|
+
method: "DELETE",
|
|
195
196
|
headers: {
|
|
196
|
-
|
|
197
|
-
|
|
197
|
+
"Content-Type": "application/json",
|
|
198
|
+
"x-t-token": token,
|
|
198
199
|
},
|
|
199
200
|
});
|
|
200
201
|
}
|
|
201
202
|
catch (error) {
|
|
202
|
-
throw new NetworkError(`Failed to delete user: ${error instanceof Error ? error.message :
|
|
203
|
+
throw new NetworkError(`Failed to delete user: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
203
204
|
}
|
|
204
205
|
let json;
|
|
205
206
|
try {
|
|
@@ -207,16 +208,16 @@ export async function deleteUser(userId, options) {
|
|
|
207
208
|
json = responseJson;
|
|
208
209
|
}
|
|
209
210
|
catch (error) {
|
|
210
|
-
throw new ApiError(`Failed to parse user deletion response: ${error instanceof Error ? error.message :
|
|
211
|
+
throw new ApiError(`Failed to parse user deletion response: ${error instanceof Error ? error.message : "Invalid JSON"}`, response.status);
|
|
211
212
|
}
|
|
212
213
|
// Handle API errors
|
|
213
214
|
if (json.code !== 200) {
|
|
214
|
-
const errorMsg = typeof json.msg ===
|
|
215
|
+
const errorMsg = typeof json.msg === "string" ? json.msg : "User deletion failed";
|
|
215
216
|
throw new ApiError(errorMsg, response.status, json.code);
|
|
216
217
|
}
|
|
217
218
|
// Validate response structure
|
|
218
219
|
if (!json.data || json.data.deleted !== true) {
|
|
219
|
-
throw new ApiError(
|
|
220
|
+
throw new ApiError("Invalid user deletion response: deletion not confirmed", response.status);
|
|
220
221
|
}
|
|
221
222
|
return json.data;
|
|
222
223
|
}
|
|
@@ -250,65 +251,65 @@ export async function deleteUser(userId, options) {
|
|
|
250
251
|
*/
|
|
251
252
|
export async function listUsers(options) {
|
|
252
253
|
// Use provided app token or get one from token service
|
|
253
|
-
const token = options?.appToken ?? await getAppToken(options);
|
|
254
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
254
255
|
// Determine base URL
|
|
255
256
|
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
256
257
|
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
257
258
|
if (!base) {
|
|
258
|
-
throw new ConfigurationError(
|
|
259
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
259
260
|
}
|
|
260
261
|
// Build URL with query parameters
|
|
261
|
-
const url = new URL(String(base).replace(/\/+$/,
|
|
262
|
+
const url = new URL(String(base).replace(/\/+$/, "") + "/account/v1/users");
|
|
262
263
|
// Add query parameters with defaults
|
|
263
264
|
const queryParams = {
|
|
264
265
|
page: 0,
|
|
265
266
|
size: 20,
|
|
266
|
-
sort_by:
|
|
267
|
-
sort_direction:
|
|
267
|
+
sort_by: "createdAt",
|
|
268
|
+
sort_direction: "desc",
|
|
268
269
|
include_attributes: false,
|
|
269
|
-
...options
|
|
270
|
+
...options,
|
|
270
271
|
};
|
|
271
272
|
// Handle array parameters (need to be comma-separated)
|
|
272
273
|
if (queryParams.user_groups && queryParams.user_groups.length > 0) {
|
|
273
|
-
url.searchParams.append(
|
|
274
|
+
url.searchParams.append("user_groups", queryParams.user_groups.join(","));
|
|
274
275
|
}
|
|
275
276
|
if (queryParams.user_roles && queryParams.user_roles.length > 0) {
|
|
276
|
-
url.searchParams.append(
|
|
277
|
+
url.searchParams.append("user_roles", queryParams.user_roles.join(","));
|
|
277
278
|
}
|
|
278
279
|
if (queryParams.user_ids && queryParams.user_ids.length > 0) {
|
|
279
|
-
url.searchParams.append(
|
|
280
|
+
url.searchParams.append("user_ids", queryParams.user_ids.join(","));
|
|
280
281
|
}
|
|
281
282
|
// Add other parameters
|
|
282
283
|
if (queryParams.page !== undefined) {
|
|
283
|
-
url.searchParams.append(
|
|
284
|
+
url.searchParams.append("page", String(queryParams.page));
|
|
284
285
|
}
|
|
285
286
|
if (queryParams.size !== undefined) {
|
|
286
|
-
url.searchParams.append(
|
|
287
|
+
url.searchParams.append("size", String(queryParams.size));
|
|
287
288
|
}
|
|
288
289
|
if (queryParams.sort_by) {
|
|
289
|
-
url.searchParams.append(
|
|
290
|
+
url.searchParams.append("sort_by", queryParams.sort_by);
|
|
290
291
|
}
|
|
291
292
|
if (queryParams.sort_direction) {
|
|
292
|
-
url.searchParams.append(
|
|
293
|
+
url.searchParams.append("sort_direction", queryParams.sort_direction);
|
|
293
294
|
}
|
|
294
295
|
if (queryParams.keyword) {
|
|
295
|
-
url.searchParams.append(
|
|
296
|
+
url.searchParams.append("keyword", queryParams.keyword);
|
|
296
297
|
}
|
|
297
298
|
if (queryParams.include_attributes !== undefined) {
|
|
298
|
-
url.searchParams.append(
|
|
299
|
+
url.searchParams.append("include_attributes", String(queryParams.include_attributes));
|
|
299
300
|
}
|
|
300
301
|
let response;
|
|
301
302
|
try {
|
|
302
303
|
response = await globalThis.fetch(url.toString(), {
|
|
303
|
-
method:
|
|
304
|
+
method: "GET",
|
|
304
305
|
headers: {
|
|
305
|
-
|
|
306
|
-
|
|
306
|
+
"Content-Type": "application/json",
|
|
307
|
+
"x-t-token": token,
|
|
307
308
|
},
|
|
308
309
|
});
|
|
309
310
|
}
|
|
310
311
|
catch (error) {
|
|
311
|
-
throw new NetworkError(`Failed to list users: ${error instanceof Error ? error.message :
|
|
312
|
+
throw new NetworkError(`Failed to list users: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
312
313
|
}
|
|
313
314
|
let json;
|
|
314
315
|
try {
|
|
@@ -316,16 +317,467 @@ export async function listUsers(options) {
|
|
|
316
317
|
json = responseJson;
|
|
317
318
|
}
|
|
318
319
|
catch (error) {
|
|
319
|
-
throw new ApiError(`Failed to parse users list response: ${error instanceof Error ? error.message :
|
|
320
|
+
throw new ApiError(`Failed to parse users list response: ${error instanceof Error ? error.message : "Invalid JSON"}`, response.status);
|
|
320
321
|
}
|
|
321
322
|
// Handle API errors
|
|
322
323
|
if (json.code !== 200) {
|
|
323
|
-
const errorMsg = typeof json.msg ===
|
|
324
|
+
const errorMsg = typeof json.msg === "string" ? json.msg : "Users list retrieval failed";
|
|
324
325
|
throw new ApiError(errorMsg, response.status, json.code);
|
|
325
326
|
}
|
|
326
327
|
// Validate response structure
|
|
327
328
|
if (!json.data || !Array.isArray(json.data.content)) {
|
|
328
|
-
throw new ApiError(
|
|
329
|
+
throw new ApiError("Invalid users list response: missing required data", response.status);
|
|
330
|
+
}
|
|
331
|
+
return json.data;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Updates user information by user ID or open ID.
|
|
335
|
+
*
|
|
336
|
+
* @param userId - User ID (open_id) to update
|
|
337
|
+
* @param userData - User data to update
|
|
338
|
+
* @param options - Optional configuration for the request
|
|
339
|
+
* @returns Promise resolving to the update result
|
|
340
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
341
|
+
* @throws {ApiError} When API request fails or returns invalid response
|
|
342
|
+
* @throws {NetworkError} When network request fails
|
|
343
|
+
*
|
|
344
|
+
* @example
|
|
345
|
+
* ```typescript
|
|
346
|
+
* import { updateUser } from '@tale/client';
|
|
347
|
+
*
|
|
348
|
+
* try {
|
|
349
|
+
* const result = await updateUser('user_open_id_here', {
|
|
350
|
+
* nick_name: 'John Doe',
|
|
351
|
+
* email: 'john@example.com'
|
|
352
|
+
* });
|
|
353
|
+
* console.log('User updated:', result.success);
|
|
354
|
+
* } catch (error) {
|
|
355
|
+
* console.error('Failed to update user:', error.message);
|
|
356
|
+
* }
|
|
357
|
+
* ```
|
|
358
|
+
*/
|
|
359
|
+
export async function updateUser(userId, userData, options) {
|
|
360
|
+
// Validate required fields
|
|
361
|
+
if (!userId || userId.trim() === "") {
|
|
362
|
+
throw new ApiError("userId is required for update", 400, "9400");
|
|
363
|
+
}
|
|
364
|
+
// Use provided app token or get one from token service
|
|
365
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
366
|
+
// Determine base URL
|
|
367
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
368
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
369
|
+
if (!base) {
|
|
370
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
371
|
+
}
|
|
372
|
+
const url = String(base).replace(/\/+$/, "") +
|
|
373
|
+
`/account/v1/user/${encodeURIComponent(userId)}`;
|
|
374
|
+
let response;
|
|
375
|
+
try {
|
|
376
|
+
response = await globalThis.fetch(url, {
|
|
377
|
+
method: "PUT",
|
|
378
|
+
headers: {
|
|
379
|
+
"Content-Type": "application/json",
|
|
380
|
+
"x-t-token": token,
|
|
381
|
+
},
|
|
382
|
+
body: JSON.stringify(userData),
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
catch (error) {
|
|
386
|
+
throw new NetworkError(`Failed to update user: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
387
|
+
}
|
|
388
|
+
let json;
|
|
389
|
+
try {
|
|
390
|
+
const responseJson = await response.json();
|
|
391
|
+
json = responseJson;
|
|
392
|
+
}
|
|
393
|
+
catch (error) {
|
|
394
|
+
throw new ApiError(`Failed to parse user update response: ${error instanceof Error ? error.message : "Invalid JSON"}`, response.status);
|
|
395
|
+
}
|
|
396
|
+
// Handle API errors
|
|
397
|
+
if (json.code !== 200) {
|
|
398
|
+
const errorMsg = typeof json.msg === "string" ? json.msg : "User update failed";
|
|
399
|
+
throw new ApiError(errorMsg, response.status, json.code);
|
|
400
|
+
}
|
|
401
|
+
return {
|
|
402
|
+
success: true,
|
|
403
|
+
user_id: userId,
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Updates user password.
|
|
408
|
+
*
|
|
409
|
+
* @param passwordData - Password data including user_id and encrypted password
|
|
410
|
+
* @param options - Optional configuration for the request
|
|
411
|
+
* @returns Promise resolving to the update result
|
|
412
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
413
|
+
* @throws {ApiError} When API request fails or returns invalid response
|
|
414
|
+
* @throws {NetworkError} When network request fails
|
|
415
|
+
*
|
|
416
|
+
* @example
|
|
417
|
+
* ```typescript
|
|
418
|
+
* import { updateUserPassword } from '@tale/client';
|
|
419
|
+
*
|
|
420
|
+
* try {
|
|
421
|
+
* const result = await updateUserPassword({
|
|
422
|
+
* user_id: 'user_open_id_here',
|
|
423
|
+
* password_encrypted: 'encrypted_password_here'
|
|
424
|
+
* });
|
|
425
|
+
* console.log('Password updated:', result.success);
|
|
426
|
+
* } catch (error) {
|
|
427
|
+
* console.error('Failed to update password:', error.message);
|
|
428
|
+
* }
|
|
429
|
+
* ```
|
|
430
|
+
*/
|
|
431
|
+
export async function updateUserPassword(passwordData, options) {
|
|
432
|
+
// Validate required fields
|
|
433
|
+
if (!passwordData.user_id || passwordData.user_id.trim() === "") {
|
|
434
|
+
throw new ApiError("user_id is required for password update", 400, "9400");
|
|
435
|
+
}
|
|
436
|
+
if (!passwordData.password_encrypted || passwordData.password_encrypted.trim() === "") {
|
|
437
|
+
throw new ApiError("password_encrypted is required", 400, "9400");
|
|
438
|
+
}
|
|
439
|
+
// Use provided app token or get one from token service
|
|
440
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
441
|
+
// Determine base URL
|
|
442
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
443
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
444
|
+
if (!base) {
|
|
445
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
446
|
+
}
|
|
447
|
+
const url = String(base).replace(/\/+$/, "") + "/account/v1/user/password";
|
|
448
|
+
let response;
|
|
449
|
+
try {
|
|
450
|
+
response = await globalThis.fetch(url, {
|
|
451
|
+
method: "POST",
|
|
452
|
+
headers: {
|
|
453
|
+
"Content-Type": "application/json",
|
|
454
|
+
"x-t-token": token,
|
|
455
|
+
},
|
|
456
|
+
body: JSON.stringify(passwordData),
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
catch (error) {
|
|
460
|
+
throw new NetworkError(`Failed to update user password: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
461
|
+
}
|
|
462
|
+
let json;
|
|
463
|
+
try {
|
|
464
|
+
const responseJson = await response.json();
|
|
465
|
+
json = responseJson;
|
|
466
|
+
}
|
|
467
|
+
catch (error) {
|
|
468
|
+
throw new ApiError(`Failed to parse password update response: ${error instanceof Error ? error.message : "Invalid JSON"}`, response.status);
|
|
469
|
+
}
|
|
470
|
+
// Handle API errors
|
|
471
|
+
if (json.code !== 200) {
|
|
472
|
+
const errorMsg = typeof json.msg === "string" ? json.msg : "Password update failed";
|
|
473
|
+
throw new ApiError(errorMsg, response.status, json.code);
|
|
474
|
+
}
|
|
475
|
+
return {
|
|
476
|
+
success: true,
|
|
477
|
+
user_id: passwordData.user_id,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Uploads user avatar image.
|
|
482
|
+
*
|
|
483
|
+
* @param file - File object to upload as avatar
|
|
484
|
+
* @param userId - User ID (open_id) of the user
|
|
485
|
+
* @param options - Optional configuration for the request
|
|
486
|
+
* @returns Promise resolving to the upload result with avatar OSS key
|
|
487
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
488
|
+
* @throws {ApiError} When API request fails or returns invalid response
|
|
489
|
+
* @throws {NetworkError} When network request fails
|
|
490
|
+
*
|
|
491
|
+
* @example
|
|
492
|
+
* ```typescript
|
|
493
|
+
* import { uploadAvatar } from '@tale/client';
|
|
494
|
+
*
|
|
495
|
+
* try {
|
|
496
|
+
* const fileInput = document.querySelector('input[type="file"]');
|
|
497
|
+
* const file = fileInput.files[0];
|
|
498
|
+
* const result = await uploadAvatar(file, 'user_open_id_here');
|
|
499
|
+
* console.log('Avatar uploaded:', result.avatar_oss_key);
|
|
500
|
+
* } catch (error) {
|
|
501
|
+
* console.error('Failed to upload avatar:', error.message);
|
|
502
|
+
* }
|
|
503
|
+
* ```
|
|
504
|
+
*/
|
|
505
|
+
export async function uploadAvatar(file, userId, options) {
|
|
506
|
+
// Validate required fields
|
|
507
|
+
if (!file) {
|
|
508
|
+
throw new ApiError("file is required for avatar upload", 400, "9400");
|
|
509
|
+
}
|
|
510
|
+
if (!userId || userId.trim() === "") {
|
|
511
|
+
throw new ApiError("userId is required for avatar upload", 400, "9400");
|
|
512
|
+
}
|
|
513
|
+
// Use provided app token or get one from token service
|
|
514
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
515
|
+
// Determine base URL
|
|
516
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
517
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
518
|
+
if (!base) {
|
|
519
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
520
|
+
}
|
|
521
|
+
const url = String(base).replace(/\/+$/, "") + "/account/v1/user/avatar/upload";
|
|
522
|
+
// Create FormData
|
|
523
|
+
const formData = new FormData();
|
|
524
|
+
formData.append("file", file);
|
|
525
|
+
formData.append("user_open_id", userId);
|
|
526
|
+
let response;
|
|
527
|
+
try {
|
|
528
|
+
response = await globalThis.fetch(url, {
|
|
529
|
+
method: "POST",
|
|
530
|
+
headers: {
|
|
531
|
+
"x-t-token": token,
|
|
532
|
+
},
|
|
533
|
+
body: formData,
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
catch (error) {
|
|
537
|
+
throw new NetworkError(`Failed to upload avatar: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
538
|
+
}
|
|
539
|
+
let json;
|
|
540
|
+
try {
|
|
541
|
+
const responseJson = await response.json();
|
|
542
|
+
json = responseJson;
|
|
543
|
+
}
|
|
544
|
+
catch (error) {
|
|
545
|
+
throw new ApiError(`Failed to parse avatar upload response: ${error instanceof Error ? error.message : "Invalid JSON"}`, response.status);
|
|
546
|
+
}
|
|
547
|
+
// Handle API errors
|
|
548
|
+
if (json.code !== 200) {
|
|
549
|
+
const errorMsg = typeof json.msg === "string" ? json.msg : "Avatar upload failed";
|
|
550
|
+
throw new ApiError(errorMsg, response.status, json.code);
|
|
551
|
+
}
|
|
552
|
+
// Validate response structure
|
|
553
|
+
if (!json.data || !json.data.avatar_oss_key) {
|
|
554
|
+
throw new ApiError("Invalid avatar upload response: missing avatar_oss_key", response.status);
|
|
555
|
+
}
|
|
556
|
+
return json.data;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Gets presigned URL for avatar access.
|
|
560
|
+
*
|
|
561
|
+
* @param ossKey - OSS key of the avatar
|
|
562
|
+
* @param options - Optional configuration for the request
|
|
563
|
+
* @returns Promise resolving to presigned URL information
|
|
564
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
565
|
+
* @throws {ApiError} When API request fails or returns invalid response
|
|
566
|
+
* @throws {NetworkError} When network request fails
|
|
567
|
+
*
|
|
568
|
+
* @example
|
|
569
|
+
* ```typescript
|
|
570
|
+
* import { getAvatarPresignedUrl } from '@tale/client';
|
|
571
|
+
*
|
|
572
|
+
* try {
|
|
573
|
+
* const result = await getAvatarPresignedUrl('avatars/user123.jpg');
|
|
574
|
+
* console.log('Presigned URL:', result.presignedUrl);
|
|
575
|
+
* console.log('Expires in:', result.expireTimeInSeconds, 'seconds');
|
|
576
|
+
* } catch (error) {
|
|
577
|
+
* console.error('Failed to get presigned URL:', error.message);
|
|
578
|
+
* }
|
|
579
|
+
* ```
|
|
580
|
+
*/
|
|
581
|
+
export async function getAvatarPresignedUrl(ossKey, options) {
|
|
582
|
+
// Validate required fields
|
|
583
|
+
if (!ossKey || ossKey.trim() === "") {
|
|
584
|
+
throw new ApiError("ossKey is required", 400, "9400");
|
|
585
|
+
}
|
|
586
|
+
// Use provided app token or get one from token service
|
|
587
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
588
|
+
// Determine base URL
|
|
589
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
590
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
591
|
+
if (!base) {
|
|
592
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
593
|
+
}
|
|
594
|
+
const url = new URL(String(base).replace(/\/+$/, "") + "/cms/file/getPresignedUrl");
|
|
595
|
+
url.searchParams.append("ossKey", ossKey);
|
|
596
|
+
let response;
|
|
597
|
+
try {
|
|
598
|
+
response = await globalThis.fetch(url.toString(), {
|
|
599
|
+
method: "GET",
|
|
600
|
+
headers: {
|
|
601
|
+
"Content-Type": "application/json",
|
|
602
|
+
"x-t-token": token,
|
|
603
|
+
},
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
catch (error) {
|
|
607
|
+
throw new NetworkError(`Failed to get avatar presigned URL: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
608
|
+
}
|
|
609
|
+
let json;
|
|
610
|
+
try {
|
|
611
|
+
const responseJson = await response.json();
|
|
612
|
+
json = responseJson;
|
|
613
|
+
}
|
|
614
|
+
catch (error) {
|
|
615
|
+
throw new ApiError(`Failed to parse presigned URL response: ${error instanceof Error ? error.message : "Invalid JSON"}`, response.status);
|
|
616
|
+
}
|
|
617
|
+
// Handle API errors
|
|
618
|
+
if (json.code !== 200) {
|
|
619
|
+
const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to get presigned URL";
|
|
620
|
+
throw new ApiError(errorMsg, response.status, json.code);
|
|
621
|
+
}
|
|
622
|
+
// Validate response structure
|
|
623
|
+
if (!json.data || !json.data.presignedUrl) {
|
|
624
|
+
throw new ApiError("Invalid presigned URL response: missing presignedUrl", response.status);
|
|
625
|
+
}
|
|
626
|
+
return json.data;
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* Updates user frozen status (freeze or unfreeze a user account).
|
|
630
|
+
*
|
|
631
|
+
* @param userId - User ID (open_id) to update frozen status
|
|
632
|
+
* @param frozenData - Frozen status data including is_frozen flag and optional remark
|
|
633
|
+
* @param options - Optional configuration for the request
|
|
634
|
+
* @returns Promise resolving to the updated frozen status information
|
|
635
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
636
|
+
* @throws {ApiError} When API request fails or returns invalid response
|
|
637
|
+
* @throws {NetworkError} When network request fails
|
|
638
|
+
*
|
|
639
|
+
* @example
|
|
640
|
+
* ```typescript
|
|
641
|
+
* import { updateUserFrozenStatus } from '@tale/client';
|
|
642
|
+
*
|
|
643
|
+
* try {
|
|
644
|
+
* // Freeze a user account
|
|
645
|
+
* const result = await updateUserFrozenStatus('user_open_id_here', {
|
|
646
|
+
* is_frozen: true,
|
|
647
|
+
* remark: 'Violated community guidelines'
|
|
648
|
+
* });
|
|
649
|
+
* console.log('User frozen:', result.is_frozen);
|
|
650
|
+
*
|
|
651
|
+
* // Unfreeze a user account
|
|
652
|
+
* const unfrozenResult = await updateUserFrozenStatus('user_open_id_here', {
|
|
653
|
+
* is_frozen: false,
|
|
654
|
+
* remark: 'Account reactivated'
|
|
655
|
+
* });
|
|
656
|
+
* console.log('User unfrozen:', !unfrozenResult.is_frozen);
|
|
657
|
+
* } catch (error) {
|
|
658
|
+
* console.error('Failed to update frozen status:', error.message);
|
|
659
|
+
* }
|
|
660
|
+
* ```
|
|
661
|
+
*/
|
|
662
|
+
export async function updateUserFrozenStatus(userId, frozenData, options) {
|
|
663
|
+
// Validate required fields
|
|
664
|
+
if (!userId || userId.trim() === "") {
|
|
665
|
+
throw new ApiError("userId is required for updating frozen status", 400, "9400");
|
|
666
|
+
}
|
|
667
|
+
if (frozenData.is_frozen === undefined || frozenData.is_frozen === null) {
|
|
668
|
+
throw new ApiError("is_frozen is required", 400, "9400");
|
|
669
|
+
}
|
|
670
|
+
// Use provided app token or get one from token service
|
|
671
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
672
|
+
// Determine base URL
|
|
673
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
674
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
675
|
+
if (!base) {
|
|
676
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
677
|
+
}
|
|
678
|
+
const url = String(base).replace(/\/+$/, "") +
|
|
679
|
+
`/account/v1/user/${encodeURIComponent(userId)}/frozen-status`;
|
|
680
|
+
let response;
|
|
681
|
+
try {
|
|
682
|
+
response = await globalThis.fetch(url, {
|
|
683
|
+
method: "PUT",
|
|
684
|
+
headers: {
|
|
685
|
+
"Content-Type": "application/json",
|
|
686
|
+
"x-t-token": token,
|
|
687
|
+
},
|
|
688
|
+
body: JSON.stringify(frozenData),
|
|
689
|
+
});
|
|
690
|
+
}
|
|
691
|
+
catch (error) {
|
|
692
|
+
throw new NetworkError(`Failed to update user frozen status: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
693
|
+
}
|
|
694
|
+
let json;
|
|
695
|
+
try {
|
|
696
|
+
const responseJson = await response.json();
|
|
697
|
+
json = responseJson;
|
|
698
|
+
}
|
|
699
|
+
catch (error) {
|
|
700
|
+
throw new ApiError(`Failed to parse frozen status update response: ${error instanceof Error ? error.message : "Invalid JSON"}`, response.status);
|
|
701
|
+
}
|
|
702
|
+
// Handle API errors
|
|
703
|
+
if (json.code !== 200) {
|
|
704
|
+
const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to update frozen status";
|
|
705
|
+
throw new ApiError(errorMsg, response.status, json.code);
|
|
706
|
+
}
|
|
707
|
+
// Validate response structure
|
|
708
|
+
if (!json.data || json.data.user_id === undefined) {
|
|
709
|
+
throw new ApiError("Invalid frozen status update response: missing required data", response.status);
|
|
710
|
+
}
|
|
711
|
+
return json.data;
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Gets user frozen status by user ID.
|
|
715
|
+
*
|
|
716
|
+
* @param userId - User ID (open_id) to query frozen status
|
|
717
|
+
* @param options - Optional configuration for the request
|
|
718
|
+
* @returns Promise resolving to the user frozen status information
|
|
719
|
+
* @throws {ConfigurationError} When required environment variables are missing
|
|
720
|
+
* @throws {ApiError} When API request fails or returns invalid response
|
|
721
|
+
* @throws {NetworkError} When network request fails
|
|
722
|
+
*
|
|
723
|
+
* @example
|
|
724
|
+
* ```typescript
|
|
725
|
+
* import { getUserFrozenStatus } from '@tale/client';
|
|
726
|
+
*
|
|
727
|
+
* try {
|
|
728
|
+
* const status = await getUserFrozenStatus('user_open_id_here');
|
|
729
|
+
* console.log('User is frozen:', status.is_frozen);
|
|
730
|
+
* console.log('Remark:', status.remark);
|
|
731
|
+
* console.log('Last updated:', status.updated_at);
|
|
732
|
+
* } catch (error) {
|
|
733
|
+
* console.error('Failed to get frozen status:', error.message);
|
|
734
|
+
* }
|
|
735
|
+
* ```
|
|
736
|
+
*/
|
|
737
|
+
export async function getUserFrozenStatus(userId, options) {
|
|
738
|
+
// Validate required fields
|
|
739
|
+
if (!userId || userId.trim() === "") {
|
|
740
|
+
throw new ApiError("userId is required for getting frozen status", 400, "9400");
|
|
741
|
+
}
|
|
742
|
+
// Use provided app token or get one from token service
|
|
743
|
+
const token = options?.appToken ?? (await getAppToken(options));
|
|
744
|
+
// Determine base URL
|
|
745
|
+
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
746
|
+
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
747
|
+
if (!base) {
|
|
748
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
749
|
+
}
|
|
750
|
+
const url = String(base).replace(/\/+$/, "") +
|
|
751
|
+
`/account/v1/user/${encodeURIComponent(userId)}/frozen-status`;
|
|
752
|
+
let response;
|
|
753
|
+
try {
|
|
754
|
+
response = await globalThis.fetch(url, {
|
|
755
|
+
method: "GET",
|
|
756
|
+
headers: {
|
|
757
|
+
"Content-Type": "application/json",
|
|
758
|
+
"x-t-token": token,
|
|
759
|
+
},
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
catch (error) {
|
|
763
|
+
throw new NetworkError(`Failed to get user frozen status: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
764
|
+
}
|
|
765
|
+
let json;
|
|
766
|
+
try {
|
|
767
|
+
const responseJson = await response.json();
|
|
768
|
+
json = responseJson;
|
|
769
|
+
}
|
|
770
|
+
catch (error) {
|
|
771
|
+
throw new ApiError(`Failed to parse frozen status response: ${error instanceof Error ? error.message : "Invalid JSON"}`, response.status);
|
|
772
|
+
}
|
|
773
|
+
// Handle API errors
|
|
774
|
+
if (json.code !== 200) {
|
|
775
|
+
const errorMsg = typeof json.msg === "string" ? json.msg : "Failed to get frozen status";
|
|
776
|
+
throw new ApiError(errorMsg, response.status, json.code);
|
|
777
|
+
}
|
|
778
|
+
// Validate response structure
|
|
779
|
+
if (!json.data || json.data.user_id === undefined) {
|
|
780
|
+
throw new ApiError("Invalid frozen status response: missing required data", response.status);
|
|
329
781
|
}
|
|
330
782
|
return json.data;
|
|
331
783
|
}
|