@cloudbase/manager-node 4.11.0-alpha.4 → 4.11.0-alpha.6

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.
@@ -488,22 +488,25 @@ class FunctionService {
488
488
  * @param {string} qualifier 需要删除的版本号,不填默认删除函数下全部版本。
489
489
  * @returns {Promise<IResponseInfo>}
490
490
  */
491
- async deleteFunction({ name }) {
491
+ async deleteFunction(name) {
492
492
  var _a;
493
+ const funcName = typeof name === 'string'
494
+ ? name
495
+ : name === null || name === void 0 ? void 0 : name.name;
493
496
  const { namespace } = this.getFunctionConfig();
494
497
  // 检测是否绑定了 API 网关
495
498
  const accessService = this.environment.getAccessService();
496
499
  const res = await accessService.getAccessList({
497
- name
500
+ name: funcName
498
501
  });
499
502
  // 删除绑定的 API 网关
500
503
  if (((_a = res === null || res === void 0 ? void 0 : res.APISet) === null || _a === void 0 ? void 0 : _a.length) > 0) {
501
504
  await accessService.deleteAccess({
502
- name
505
+ name: funcName
503
506
  });
504
507
  }
505
- await this.scfService.request('DeleteFunction', {
506
- FunctionName: name,
508
+ return await this.scfService.request('DeleteFunction', {
509
+ FunctionName: funcName,
507
510
  Namespace: namespace
508
511
  });
509
512
  }
@@ -741,10 +744,13 @@ class FunctionService {
741
744
  // 注意:dnsCache 需要 'TRUE'/'FALSE' 字符串,在特殊处理阶段处理
742
745
  'intranetconfig': 'IntranetConfig',
743
746
  };
747
+ const { TopicId, LogsetId } = this.getClsServiceConfig();
744
748
  // 构建参数
745
749
  const params = {
746
750
  Namespace: namespace,
747
- FunctionName: func.name
751
+ FunctionName: func.name,
752
+ ClsTopicId: TopicId,
753
+ ClsLogsetId: LogsetId
748
754
  };
749
755
  // 白名单字段自动转换(大小写不敏感,统一输出 PascalCase)
750
756
  for (const key of Object.keys(func)) {
@@ -1047,13 +1053,12 @@ class FunctionService {
1047
1053
  async deleteFunctionTrigger(name, triggerName) {
1048
1054
  const { namespace } = this.getFunctionConfig();
1049
1055
  try {
1050
- await this.scfService.request('DeleteTrigger', {
1056
+ return await this.scfService.request('DeleteTrigger', {
1051
1057
  FunctionName: name,
1052
1058
  Namespace: namespace,
1053
1059
  TriggerName: triggerName,
1054
1060
  Type: 'timer'
1055
1061
  });
1056
- (0, utils_1.successLog)(`[${name}] 删除云函数触发器 ${triggerName} 成功!`);
1057
1062
  }
1058
1063
  catch (e) {
1059
1064
  throw new error_1.CloudBaseError(`[${name}] 删除触发器失败:${e.message}`);
package/lib/user/index.js CHANGED
@@ -114,6 +114,194 @@ class UserService {
114
114
  async getTcbAccountInfo() {
115
115
  return this.tcbService.request('DescribeTcbAccountInfo');
116
116
  }
117
+ async createUser(options) {
118
+ const { EnvId } = this.environment.lazyEnvironmentConfig;
119
+ const { name, uid, type, password, userStatus, nickName, phone, email, avatarUrl, description } = options;
120
+ // name 校验:1-64,字母/数字开头,仅字母数字._-
121
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(name)) {
122
+ throw new Error('Invalid name');
123
+ }
124
+ // uid 校验:<=64
125
+ if (uid && uid.length > 64) {
126
+ throw new Error('Invalid uid');
127
+ }
128
+ // type / status 白名单
129
+ if (type && !['internalUser', 'externalUser'].includes(type)) {
130
+ throw new Error('Invalid type');
131
+ }
132
+ if (userStatus && !['ACTIVE', 'BLOCKED'].includes(userStatus)) {
133
+ throw new Error('Invalid userStatus');
134
+ }
135
+ if (password) {
136
+ if (password.length < 8 || password.length > 32) {
137
+ throw new Error('Invalid password length');
138
+ }
139
+ if (!/^[A-Za-z0-9]/.test(password)) {
140
+ throw new Error('Password cannot start with special character');
141
+ }
142
+ const kinds = [
143
+ /[a-z]/.test(password),
144
+ /[A-Z]/.test(password),
145
+ /[0-9]/.test(password),
146
+ /[()!@#$%^&*|?><_-]/.test(password)
147
+ ].filter(Boolean).length;
148
+ if (kinds < 3) {
149
+ throw new Error('Password must include at least 3 character categories');
150
+ }
151
+ }
152
+ // 其他字段校验
153
+ if (nickName && (nickName.length < 2 || nickName.length > 64)) {
154
+ throw new Error('Invalid nickName');
155
+ }
156
+ if (description && description.length > 200) {
157
+ throw new Error('Invalid description');
158
+ }
159
+ if (phone && !/^1\d{10}$/.test(phone)) {
160
+ throw new Error('Invalid phone');
161
+ }
162
+ if (email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
163
+ throw new Error('Invalid email');
164
+ }
165
+ const reqData = {
166
+ EnvId,
167
+ Name: name
168
+ };
169
+ if (uid)
170
+ reqData.Uid = uid;
171
+ if (type)
172
+ reqData.Type = type;
173
+ if (password)
174
+ reqData.Password = password;
175
+ if (userStatus)
176
+ reqData.UserStatus = userStatus;
177
+ if (nickName)
178
+ reqData.NickName = nickName;
179
+ if (phone)
180
+ reqData.Phone = phone;
181
+ if (email)
182
+ reqData.Email = email;
183
+ if (avatarUrl)
184
+ reqData.AvatarUrl = avatarUrl;
185
+ if (description)
186
+ reqData.Description = description;
187
+ return this.tcbService.request('CreateUser', reqData);
188
+ }
189
+ async describeUserList(options = {}) {
190
+ const { EnvId } = this.environment.lazyEnvironmentConfig;
191
+ const { pageNo = 1, pageSize = 20, name, nickName, phone, email } = options;
192
+ if (!Number.isInteger(pageNo) || pageNo < 1) {
193
+ throw new Error('Invalid pageNo');
194
+ }
195
+ if (!Number.isInteger(pageSize) || pageSize < 1 || pageSize > 100) {
196
+ throw new Error('Invalid pageSize');
197
+ }
198
+ const reqData = {
199
+ EnvId,
200
+ PageNo: pageNo,
201
+ PageSize: pageSize
202
+ };
203
+ if (this.isValidStr(name))
204
+ reqData.Name = name;
205
+ if (this.isValidStr(nickName))
206
+ reqData.NickName = nickName;
207
+ if (this.isValidStr(phone))
208
+ reqData.Phone = phone;
209
+ if (this.isValidStr(email))
210
+ reqData.Email = email;
211
+ return this.tcbService.request('DescribeUserList', reqData);
212
+ }
213
+ async modifyUser(options) {
214
+ const { EnvId } = this.environment.lazyEnvironmentConfig;
215
+ const { uid, name, type, password, userStatus, nickName, phone, email, avatarUrl, description } = options;
216
+ if (!this.isValidStr(uid) || uid.length > 64) {
217
+ throw new Error('Invalid uid');
218
+ }
219
+ // Name: 不传或空字符串 => 不修改;传了非空则校验
220
+ if (name !== undefined && name !== '' && !/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(name)) {
221
+ throw new Error('Invalid name');
222
+ }
223
+ // Type / UserStatus: 不传或空字符串 => 不修改;非空时白名单校验
224
+ if (type !== undefined && !['internalUser', 'externalUser'].includes(type)) {
225
+ throw new Error('Invalid type');
226
+ }
227
+ if (userStatus !== undefined && !['ACTIVE', 'BLOCKED'].includes(userStatus)) {
228
+ throw new Error('Invalid userStatus');
229
+ }
230
+ // Password: 不传或空字符串 => 不修改;非空时校验复杂度
231
+ if (password !== undefined && password !== '') {
232
+ if (password.length < 8 || password.length > 32) {
233
+ throw new Error('Invalid password length');
234
+ }
235
+ if (!/^[A-Za-z0-9]/.test(password)) {
236
+ throw new Error('Password cannot start with special character');
237
+ }
238
+ const kinds = [
239
+ /[a-z]/.test(password),
240
+ /[A-Z]/.test(password),
241
+ /[0-9]/.test(password),
242
+ /[()!@#$%^&*|?><_-]/.test(password)
243
+ ].filter(Boolean).length;
244
+ if (kinds < 3) {
245
+ throw new Error('Password must include at least 3 character categories');
246
+ }
247
+ }
248
+ // 这些字段:不传 => 不修改;传空字符串 => 清空(允许)
249
+ if (nickName !== undefined && nickName !== '' && (nickName.length < 2 || nickName.length > 64)) {
250
+ throw new Error('Invalid nickName');
251
+ }
252
+ if (phone !== undefined && phone !== '' && !/^1\d{10}$/.test(phone)) {
253
+ throw new Error('Invalid phone');
254
+ }
255
+ if (email !== undefined && email !== '' && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
256
+ throw new Error('Invalid email');
257
+ }
258
+ if (description !== undefined && description !== '' && description.length > 200) {
259
+ throw new Error('Invalid description');
260
+ }
261
+ const reqData = {
262
+ EnvId,
263
+ Uid: uid
264
+ };
265
+ // Name/Type/Password/UserStatus:空字符串视为不修改
266
+ if (name !== undefined && name !== '')
267
+ reqData.Name = name;
268
+ if (type !== undefined)
269
+ reqData.Type = type;
270
+ if (password !== undefined && password !== '')
271
+ reqData.Password = password;
272
+ if (userStatus !== undefined)
273
+ reqData.UserStatus = userStatus;
274
+ // 这些字段支持传空字符串清空:只要“传了”就下发
275
+ if (Object.prototype.hasOwnProperty.call(options, 'nickName'))
276
+ reqData.NickName = nickName;
277
+ if (Object.prototype.hasOwnProperty.call(options, 'phone'))
278
+ reqData.Phone = phone;
279
+ if (Object.prototype.hasOwnProperty.call(options, 'email'))
280
+ reqData.Email = email;
281
+ if (Object.prototype.hasOwnProperty.call(options, 'avatarUrl'))
282
+ reqData.AvatarUrl = avatarUrl;
283
+ if (Object.prototype.hasOwnProperty.call(options, 'description'))
284
+ reqData.Description = description;
285
+ return this.tcbService.request('ModifyUser', reqData);
286
+ }
287
+ async deleteUsers(options) {
288
+ const { EnvId } = this.environment.lazyEnvironmentConfig;
289
+ const { uids } = options;
290
+ if (!Array.isArray(uids) || uids.length === 0) {
291
+ throw new Error('uids is required');
292
+ }
293
+ if (uids.length > 100) {
294
+ throw new Error('uids length must be <= 100');
295
+ }
296
+ const invalidUid = uids.find(uid => !this.isValidStr(uid));
297
+ if (invalidUid) {
298
+ throw new Error('Invalid uid in uids');
299
+ }
300
+ return this.tcbService.request('DeleteUsers', {
301
+ EnvId,
302
+ Uids: uids
303
+ });
304
+ }
117
305
  isValidStr(obj) {
118
306
  return typeof obj === 'string' && obj.trim().length > 0;
119
307
  }
@@ -137,3 +325,15 @@ __decorate([
137
325
  __decorate([
138
326
  (0, utils_1.preLazy)()
139
327
  ], UserService.prototype, "updateEndUser", null);
328
+ __decorate([
329
+ (0, utils_1.preLazy)()
330
+ ], UserService.prototype, "createUser", null);
331
+ __decorate([
332
+ (0, utils_1.preLazy)()
333
+ ], UserService.prototype, "describeUserList", null);
334
+ __decorate([
335
+ (0, utils_1.preLazy)()
336
+ ], UserService.prototype, "modifyUser", null);
337
+ __decorate([
338
+ (0, utils_1.preLazy)()
339
+ ], UserService.prototype, "deleteUsers", null);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/manager-node",
3
- "version": "4.11.0-alpha.4",
3
+ "version": "4.11.0-alpha.6",
4
4
  "description": "The node manage service api for cloudbase.",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -277,9 +277,9 @@ export declare class FunctionService {
277
277
  * @param {string} qualifier 需要删除的版本号,不填默认删除函数下全部版本。
278
278
  * @returns {Promise<IResponseInfo>}
279
279
  */
280
- deleteFunction({ name }: {
281
- name: any;
282
- }): Promise<void>;
280
+ deleteFunction(name: string | {
281
+ name: string;
282
+ }): Promise<IResponseInfo>;
283
283
  /**
284
284
  * 批量删除云函数
285
285
  * @param {Object} options
@@ -404,7 +404,7 @@ export declare class FunctionService {
404
404
  * @param {string} triggerName 云函数触发器名称
405
405
  * @returns {Promise<IResponseInfo>}
406
406
  */
407
- deleteFunctionTrigger(name: string, triggerName: string): Promise<void>;
407
+ deleteFunctionTrigger(name: string, triggerName: string): Promise<IResponseInfo>;
408
408
  batchDeleteTriggers(options: IFunctionBatchOptions): Promise<void>;
409
409
  /**
410
410
  * 下载云函数代码
@@ -1,5 +1,5 @@
1
1
  import { Environment } from '../environment';
2
- import { EndUserInfo, EndUserStatus } from './types';
2
+ import { EndUserInfo, EndUserStatus, CreateUserOptions, CreateUserResp, DescribeUserListOptions, DescribeUserListResp, ModifyUserOptions, ModifyUserResp, DeleteUsersOptions, DeleteUsersResp } from './types';
3
3
  export declare class UserService {
4
4
  private environment;
5
5
  private tcbService;
@@ -54,5 +54,21 @@ export declare class UserService {
54
54
  WxAppId: string;
55
55
  Channel: "ide" | "low_code";
56
56
  }>;
57
+ createUser(options: CreateUserOptions): Promise<{
58
+ Data: CreateUserResp;
59
+ RequestId: string;
60
+ }>;
61
+ describeUserList(options?: DescribeUserListOptions): Promise<{
62
+ Data: DescribeUserListResp;
63
+ RequestId: string;
64
+ }>;
65
+ modifyUser(options: ModifyUserOptions): Promise<{
66
+ Data: ModifyUserResp | null;
67
+ RequestId: string;
68
+ }>;
69
+ deleteUsers(options: DeleteUsersOptions): Promise<{
70
+ Data: DeleteUsersResp;
71
+ RequestId: string;
72
+ }>;
57
73
  private isValidStr;
58
74
  }
@@ -18,3 +18,65 @@ export interface EndUserInfo {
18
18
  UserName: string;
19
19
  }
20
20
  export type EndUserStatus = 'ENABLE' | 'DISABLE';
21
+ export type TcbUserType = 'internalUser' | 'externalUser';
22
+ export type TcbUserStatus = 'ACTIVE' | 'BLOCKED';
23
+ export interface CreateUserOptions {
24
+ name: string;
25
+ uid?: string;
26
+ type?: TcbUserType;
27
+ password?: string;
28
+ userStatus?: TcbUserStatus;
29
+ nickName?: string;
30
+ phone?: string;
31
+ email?: string;
32
+ avatarUrl?: string;
33
+ description?: string;
34
+ }
35
+ export interface CreateUserResp {
36
+ Uid: string;
37
+ }
38
+ export interface DescribeUserListOptions {
39
+ pageNo?: number;
40
+ pageSize?: number;
41
+ name?: string;
42
+ nickName?: string;
43
+ phone?: string;
44
+ email?: string;
45
+ }
46
+ export interface TcbUserItem {
47
+ Uid?: string;
48
+ Name?: string;
49
+ Type?: 'internalUser' | 'externalUser';
50
+ UserStatus?: 'ACTIVE' | 'BLOCKED';
51
+ NickName?: string;
52
+ Phone?: string;
53
+ Email?: string;
54
+ AvatarUrl?: string;
55
+ Description?: string;
56
+ }
57
+ export interface DescribeUserListResp {
58
+ Total: number;
59
+ UserList: TcbUserItem[];
60
+ }
61
+ export interface ModifyUserOptions {
62
+ uid: string;
63
+ name?: string;
64
+ type?: TcbUserType;
65
+ password?: string;
66
+ userStatus?: TcbUserStatus;
67
+ nickName?: string;
68
+ phone?: string;
69
+ email?: string;
70
+ avatarUrl?: string;
71
+ description?: string;
72
+ }
73
+ export interface ModifyUserResp {
74
+ Success: boolean;
75
+ }
76
+ export interface DeleteUsersOptions {
77
+ uids: string[];
78
+ }
79
+ export interface DeleteUsersResp {
80
+ SuccessCount: number;
81
+ FailedCount: number;
82
+ }