@cloudbase/manager-node 4.7.4-beta.1 → 4.7.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/lib/cloudrun/index.js +103 -2
- package/lib/cloudrun/type.js +12 -1
- package/lib/function/index.js +40 -2
- package/package.json +1 -1
- package/types/cloudrun/index.d.ts +30 -1
- package/types/cloudrun/type.d.ts +78 -0
- package/types/interfaces/function.interface.d.ts +10 -0
package/lib/cloudrun/index.js
CHANGED
|
@@ -16,6 +16,7 @@ const archiver_1 = __importDefault(require("archiver"));
|
|
|
16
16
|
const fs_extra_1 = require("fs-extra");
|
|
17
17
|
const path_1 = __importDefault(require("path"));
|
|
18
18
|
const utils_1 = require("../utils");
|
|
19
|
+
const type_1 = require("./type");
|
|
19
20
|
/**
|
|
20
21
|
* 云托管服务管理类
|
|
21
22
|
* 提供云托管服务的初始化、下载、列表查询和删除等功能
|
|
@@ -105,6 +106,97 @@ class CloudRunService {
|
|
|
105
106
|
ServerType: params === null || params === void 0 ? void 0 : params.serverType
|
|
106
107
|
}));
|
|
107
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
*
|
|
111
|
+
* @param serverName 云托管服务名
|
|
112
|
+
* @param stablePercent 稳定版本流量比例
|
|
113
|
+
* @param canaryPercent 灰度版本流量比例
|
|
114
|
+
* @returns 灰度发布进度
|
|
115
|
+
*/
|
|
116
|
+
async setTraffic(serverName, stablePercent, canaryPercent) {
|
|
117
|
+
// 校验比例之和是否为100%
|
|
118
|
+
if (stablePercent + canaryPercent !== 100) {
|
|
119
|
+
throw new Error('稳定版本流量比例和灰度版本流量比例之和必须等于 100');
|
|
120
|
+
}
|
|
121
|
+
const envConfig = this.environment.lazyEnvironmentConfig;
|
|
122
|
+
const { Task } = await this.tcbrService.request('DescribeServerManageTask', {
|
|
123
|
+
EnvId: envConfig.EnvId,
|
|
124
|
+
ServerName: serverName, // 服务名
|
|
125
|
+
TaskId: 0 // 任务Id
|
|
126
|
+
});
|
|
127
|
+
// 判断是否存在灰度版本
|
|
128
|
+
const isGary = (Task === null || Task === void 0 ? void 0 : Task.ReleaseType) === type_1.ReleaseTypeEnum.GRAY && (Task === null || Task === void 0 ? void 0 : Task.Status) === 'running';
|
|
129
|
+
if (!isGary) {
|
|
130
|
+
throw new Error('不存在灰度中的版本或灰度版本部署未完成');
|
|
131
|
+
}
|
|
132
|
+
// 获取当前版本和灰度版本
|
|
133
|
+
const { ReleaseOrderInfo } = await this.tcbrService.request('DescribeReleaseOrder', {
|
|
134
|
+
EnvId: envConfig.EnvId, // 环境 Id
|
|
135
|
+
ServerName: serverName // 服务名
|
|
136
|
+
});
|
|
137
|
+
const { CurrentVersion, ReleaseVersion } = ReleaseOrderInfo;
|
|
138
|
+
// 设置版本比例
|
|
139
|
+
return await this.tcbrService.request('ReleaseGray', {
|
|
140
|
+
EnvId: envConfig.EnvId, // 环境 Id
|
|
141
|
+
ServerName: serverName, // 服务名
|
|
142
|
+
GrayType: "gray",
|
|
143
|
+
TrafficType: "FLOW",
|
|
144
|
+
GrayFlowRatio: canaryPercent,
|
|
145
|
+
VersionFlowItems: [{
|
|
146
|
+
VersionName: CurrentVersion.VersionName,
|
|
147
|
+
FlowRatio: stablePercent,
|
|
148
|
+
IsDefaultPriority: true,
|
|
149
|
+
Priority: 1,
|
|
150
|
+
}, {
|
|
151
|
+
VersionName: ReleaseVersion.VersionName,
|
|
152
|
+
FlowRatio: canaryPercent,
|
|
153
|
+
IsDefaultPriority: false,
|
|
154
|
+
Priority: 2,
|
|
155
|
+
}]
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
*
|
|
160
|
+
* @param serverName 云托管服务名
|
|
161
|
+
* @returns 发布结果
|
|
162
|
+
*/
|
|
163
|
+
async promote(serverName) {
|
|
164
|
+
const envConfig = this.environment.lazyEnvironmentConfig;
|
|
165
|
+
// 获取当前版本和灰度版本
|
|
166
|
+
const { ReleaseOrderInfo } = await this.tcbrService.request('DescribeReleaseOrder', {
|
|
167
|
+
EnvId: envConfig.EnvId, // 环境 Id
|
|
168
|
+
ServerName: serverName // 服务名
|
|
169
|
+
});
|
|
170
|
+
const { ReleaseVersion } = ReleaseOrderInfo;
|
|
171
|
+
return await this.tcbrService.request('ReleaseGray', {
|
|
172
|
+
EnvId: envConfig.EnvId, // 环境 Id
|
|
173
|
+
ServerName: serverName, // 服务名
|
|
174
|
+
GrayType: "gray",
|
|
175
|
+
TrafficType: "FLOW",
|
|
176
|
+
GrayFlowRatio: 100,
|
|
177
|
+
VersionFlowItems: [{ VersionName: ReleaseVersion.VersionName, FlowRatio: 100, Priority: 0, IsDefaultPriority: true }],
|
|
178
|
+
CloseGrayRelease: true,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
*
|
|
183
|
+
* @param serverName 云托管服务名
|
|
184
|
+
* @returns 回滚结果
|
|
185
|
+
*/
|
|
186
|
+
async rollback(serverName) {
|
|
187
|
+
const envConfig = this.environment.lazyEnvironmentConfig;
|
|
188
|
+
const { Task } = await this.tcbrService.request('DescribeServerManageTask', {
|
|
189
|
+
EnvId: envConfig.EnvId,
|
|
190
|
+
ServerName: serverName, // 服务名
|
|
191
|
+
TaskId: 0 // 任务Id
|
|
192
|
+
});
|
|
193
|
+
return await this.tcbrService.request('OperateServerManage', {
|
|
194
|
+
EnvId: envConfig.EnvId, // 环境 Id
|
|
195
|
+
ServerName: serverName,
|
|
196
|
+
TaskId: Task.Id,
|
|
197
|
+
OperateType: 'go_back',
|
|
198
|
+
});
|
|
199
|
+
}
|
|
108
200
|
/**
|
|
109
201
|
*查询云托管服务详情
|
|
110
202
|
* @param {Object} params 查询参数
|
|
@@ -156,7 +248,7 @@ class CloudRunService {
|
|
|
156
248
|
* @returns {Promise<IResponseInfo>} 返回部署操作的响应信息
|
|
157
249
|
*/
|
|
158
250
|
async deploy(params) {
|
|
159
|
-
const { serverName, targetPath = process.cwd(), serverConfig } = params;
|
|
251
|
+
const { serverName, targetPath = process.cwd(), serverConfig, deployInfo: { ReleaseType = "FULL" } } = params;
|
|
160
252
|
/**
|
|
161
253
|
* 参数校验和默认值设置
|
|
162
254
|
*/
|
|
@@ -204,7 +296,7 @@ class CloudRunService {
|
|
|
204
296
|
RepoLanguage: 'Node.js'
|
|
205
297
|
};
|
|
206
298
|
}
|
|
207
|
-
deployInfo.ReleaseType =
|
|
299
|
+
deployInfo.ReleaseType = ReleaseType;
|
|
208
300
|
return this._upsertFunction(false, {
|
|
209
301
|
name: serverName,
|
|
210
302
|
deployInfo,
|
|
@@ -291,6 +383,15 @@ __decorate([
|
|
|
291
383
|
__decorate([
|
|
292
384
|
(0, utils_1.preLazy)()
|
|
293
385
|
], CloudRunService.prototype, "list", null);
|
|
386
|
+
__decorate([
|
|
387
|
+
(0, utils_1.preLazy)()
|
|
388
|
+
], CloudRunService.prototype, "setTraffic", null);
|
|
389
|
+
__decorate([
|
|
390
|
+
(0, utils_1.preLazy)()
|
|
391
|
+
], CloudRunService.prototype, "promote", null);
|
|
392
|
+
__decorate([
|
|
393
|
+
(0, utils_1.preLazy)()
|
|
394
|
+
], CloudRunService.prototype, "rollback", null);
|
|
294
395
|
__decorate([
|
|
295
396
|
(0, utils_1.preLazy)()
|
|
296
397
|
], CloudRunService.prototype, "detail", null);
|
package/lib/cloudrun/type.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CloudrunServerType = void 0;
|
|
3
|
+
exports.ReleaseTypeEnum = exports.CloudrunServerType = void 0;
|
|
4
4
|
var CloudrunServerType;
|
|
5
5
|
(function (CloudrunServerType) {
|
|
6
6
|
/**
|
|
@@ -12,3 +12,14 @@ var CloudrunServerType;
|
|
|
12
12
|
*/
|
|
13
13
|
CloudrunServerType["Container"] = "container";
|
|
14
14
|
})(CloudrunServerType || (exports.CloudrunServerType = CloudrunServerType = {}));
|
|
15
|
+
var ReleaseTypeEnum;
|
|
16
|
+
(function (ReleaseTypeEnum) {
|
|
17
|
+
/**
|
|
18
|
+
* 灰度发布
|
|
19
|
+
*/
|
|
20
|
+
ReleaseTypeEnum["GRAY"] = "GRAY";
|
|
21
|
+
/**
|
|
22
|
+
* 全量发布
|
|
23
|
+
*/
|
|
24
|
+
ReleaseTypeEnum["FULL"] = "FULL";
|
|
25
|
+
})(ReleaseTypeEnum || (exports.ReleaseTypeEnum = ReleaseTypeEnum = {}));
|
package/lib/function/index.js
CHANGED
|
@@ -25,7 +25,7 @@ function isNodeFunction(runtime) {
|
|
|
25
25
|
}
|
|
26
26
|
// 解析函数配置,换成请求参数
|
|
27
27
|
function configToParams(options) {
|
|
28
|
-
var _a, _b, _c, _d, _e;
|
|
28
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
29
29
|
const { func, codeSecret, baseParams } = options;
|
|
30
30
|
let installDependency;
|
|
31
31
|
// Node 函数默认安装依赖
|
|
@@ -81,6 +81,26 @@ function configToParams(options) {
|
|
|
81
81
|
// HTTP 云函数类型
|
|
82
82
|
if ((func === null || func === void 0 ? void 0 : func.type) === 'HTTP') {
|
|
83
83
|
params.Type = 'HTTP';
|
|
84
|
+
// WebSocket 协议支持
|
|
85
|
+
if ((func === null || func === void 0 ? void 0 : func.protocolType) === 'WS') {
|
|
86
|
+
params.ProtocolType = 'WS';
|
|
87
|
+
// 协议参数,直接透传或使用默认值
|
|
88
|
+
// 参考文档:https://cloud.tencent.com/document/api/583/17244#ProtocolParams
|
|
89
|
+
const idleTimeOut = (_g = (_f = func === null || func === void 0 ? void 0 : func.protocolParams) === null || _f === void 0 ? void 0 : _f.wsParams) === null || _g === void 0 ? void 0 : _g.idleTimeOut;
|
|
90
|
+
params.ProtocolParams = {
|
|
91
|
+
WSParams: {
|
|
92
|
+
IdleTimeOut: typeof idleTimeOut === 'number' ? idleTimeOut : 15
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// 多并发配置
|
|
97
|
+
// 参考文档:https://cloud.tencent.com/document/api/583/17244#InstanceConcurrencyConfig
|
|
98
|
+
if (func === null || func === void 0 ? void 0 : func.instanceConcurrencyConfig) {
|
|
99
|
+
params.InstanceConcurrencyConfig = {
|
|
100
|
+
DynamicEnabled: func.instanceConcurrencyConfig.dynamicEnabled || 'FALSE',
|
|
101
|
+
MaxConcurrency: func.instanceConcurrencyConfig.maxConcurrency || 10
|
|
102
|
+
};
|
|
103
|
+
}
|
|
84
104
|
}
|
|
85
105
|
// 云函数描述
|
|
86
106
|
if (func === null || func === void 0 ? void 0 : func.description) {
|
|
@@ -554,7 +574,7 @@ class FunctionService {
|
|
|
554
574
|
* @returns {Promise<IResponseInfo>}
|
|
555
575
|
*/
|
|
556
576
|
async updateFunctionConfig(func) {
|
|
557
|
-
var _a, _b, _c, _d, _e;
|
|
577
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
558
578
|
const { namespace } = this.getFunctionConfig();
|
|
559
579
|
const envVariables = Object.keys(func.envVariables || {}).map(key => ({
|
|
560
580
|
Key: key,
|
|
@@ -600,6 +620,22 @@ class FunctionService {
|
|
|
600
620
|
}));
|
|
601
621
|
params.Layers = transformLayers;
|
|
602
622
|
}
|
|
623
|
+
// WebSocket 协议支持(仅 HTTP 函数)
|
|
624
|
+
if (func === null || func === void 0 ? void 0 : func.protocolParams) {
|
|
625
|
+
const idleTimeOut = (_g = (_f = func === null || func === void 0 ? void 0 : func.protocolParams) === null || _f === void 0 ? void 0 : _f.wsParams) === null || _g === void 0 ? void 0 : _g.idleTimeOut;
|
|
626
|
+
params.ProtocolParams = {
|
|
627
|
+
WSParams: {
|
|
628
|
+
IdleTimeOut: typeof idleTimeOut === 'number' ? idleTimeOut : 15
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
// 多并发配置(仅 HTTP 函数)
|
|
633
|
+
if (func === null || func === void 0 ? void 0 : func.instanceConcurrencyConfig) {
|
|
634
|
+
params.InstanceConcurrencyConfig = {
|
|
635
|
+
DynamicEnabled: func.instanceConcurrencyConfig.dynamicEnabled || 'FALSE',
|
|
636
|
+
MaxConcurrency: func.instanceConcurrencyConfig.maxConcurrency || 10
|
|
637
|
+
};
|
|
638
|
+
}
|
|
603
639
|
try {
|
|
604
640
|
// 如果函数配置中包含触发器,则更新触发器
|
|
605
641
|
if (func.triggers && func.triggers.length > 0) {
|
|
@@ -1341,11 +1377,13 @@ class FunctionService {
|
|
|
1341
1377
|
if (!(base64 === null || base64 === void 0 ? void 0 : base64.length)) {
|
|
1342
1378
|
throw new error_1.CloudBaseError('文件不能为空');
|
|
1343
1379
|
}
|
|
1380
|
+
console.log(`[${func.name}] 部署方式: ZIP base64 上传`);
|
|
1344
1381
|
return {
|
|
1345
1382
|
ZipFile: base64
|
|
1346
1383
|
};
|
|
1347
1384
|
}
|
|
1348
1385
|
// 默认走 COS 上传
|
|
1386
|
+
console.log(`[${func.name}] 部署方式: COS 上传`);
|
|
1349
1387
|
const legacyResult = await this.uploadFunctionZipToCosLegacy(options, installDependency);
|
|
1350
1388
|
return {
|
|
1351
1389
|
CosBucketRegion: constant_1.SCF_TEMP_COS.REGION,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Environment } from '../environment';
|
|
2
2
|
import { IResponseInfo } from '../interfaces';
|
|
3
|
-
import { CloudrunServerType, ICloudrunDetailResponse, ICloudrunListResponse, ICloudrunServerBaseConfig, ICloudrunServerBaseInfo, IDiffConfigItem, ITemplate } from './type';
|
|
3
|
+
import { CloudrunServerType, ICloudrunDetailResponse, ICloudrunListResponse, ICloudrunServerBaseConfig, ICloudrunServerBaseInfo, IDiffConfigItem, ITemplate, ReleaseTypeEnum } from './type';
|
|
4
4
|
/**
|
|
5
5
|
* 云托管服务管理类
|
|
6
6
|
* 提供云托管服务的初始化、下载、列表查询和删除等功能
|
|
@@ -56,6 +56,32 @@ export declare class CloudRunService {
|
|
|
56
56
|
serverName?: string;
|
|
57
57
|
serverType?: CloudrunServerType;
|
|
58
58
|
}): Promise<ICloudrunListResponse>;
|
|
59
|
+
/**
|
|
60
|
+
*
|
|
61
|
+
* @param serverName 云托管服务名
|
|
62
|
+
* @param stablePercent 稳定版本流量比例
|
|
63
|
+
* @param canaryPercent 灰度版本流量比例
|
|
64
|
+
* @returns 灰度发布进度
|
|
65
|
+
*/
|
|
66
|
+
setTraffic(serverName: string, stablePercent: number, canaryPercent: number): Promise<{
|
|
67
|
+
RequestId?: string;
|
|
68
|
+
}>;
|
|
69
|
+
/**
|
|
70
|
+
*
|
|
71
|
+
* @param serverName 云托管服务名
|
|
72
|
+
* @returns 发布结果
|
|
73
|
+
*/
|
|
74
|
+
promote(serverName: string): Promise<{
|
|
75
|
+
RequestId?: string;
|
|
76
|
+
}>;
|
|
77
|
+
/**
|
|
78
|
+
*
|
|
79
|
+
* @param serverName 云托管服务名
|
|
80
|
+
* @returns 回滚结果
|
|
81
|
+
*/
|
|
82
|
+
rollback(serverName: string): Promise<{
|
|
83
|
+
RequestId?: string;
|
|
84
|
+
}>;
|
|
59
85
|
/**
|
|
60
86
|
*查询云托管服务详情
|
|
61
87
|
* @param {Object} params 查询参数
|
|
@@ -99,6 +125,9 @@ export declare class CloudRunService {
|
|
|
99
125
|
deploy(params: {
|
|
100
126
|
serverName: string;
|
|
101
127
|
targetPath: string;
|
|
128
|
+
deployInfo: {
|
|
129
|
+
ReleaseType: ReleaseTypeEnum;
|
|
130
|
+
};
|
|
102
131
|
serverConfig?: Partial<Pick<ICloudrunServerBaseConfig, 'OpenAccessTypes' | 'Cpu' | 'Mem' | 'MinNum' | 'MaxNum' | 'PolicyDetails' | 'CustomLogs' | 'EnvParams' | 'Port' | 'Dockerfile' | 'BuildDir' | 'InternalAccess' | 'InternalDomain' | 'EntryPoint' | 'Cmd' | 'InstallDependency'>>;
|
|
103
132
|
}): Promise<IResponseInfo>;
|
|
104
133
|
/**
|
package/types/cloudrun/type.d.ts
CHANGED
|
@@ -8,6 +8,16 @@ export declare enum CloudrunServerType {
|
|
|
8
8
|
*/
|
|
9
9
|
Container = "container"
|
|
10
10
|
}
|
|
11
|
+
export declare enum ReleaseTypeEnum {
|
|
12
|
+
/**
|
|
13
|
+
* 灰度发布
|
|
14
|
+
*/
|
|
15
|
+
GRAY = "GRAY",
|
|
16
|
+
/**
|
|
17
|
+
* 全量发布
|
|
18
|
+
*/
|
|
19
|
+
FULL = "FULL"
|
|
20
|
+
}
|
|
11
21
|
/**
|
|
12
22
|
* 服务基础信息接口
|
|
13
23
|
*/
|
|
@@ -327,3 +337,71 @@ export interface ITemplate {
|
|
|
327
337
|
language: string;
|
|
328
338
|
zipFileStore: string;
|
|
329
339
|
}
|
|
340
|
+
export interface ITaskStepInfo {
|
|
341
|
+
Name?: string;
|
|
342
|
+
Status?: string;
|
|
343
|
+
StartTime?: string;
|
|
344
|
+
EndTime?: string;
|
|
345
|
+
CostTime?: number;
|
|
346
|
+
FailReason?: string;
|
|
347
|
+
}
|
|
348
|
+
export interface IServerManageTaskInfo {
|
|
349
|
+
Id?: number;
|
|
350
|
+
EnvId?: string;
|
|
351
|
+
ServerName?: string;
|
|
352
|
+
CreateTime?: string;
|
|
353
|
+
ChangeType?: string;
|
|
354
|
+
ReleaseType?: string;
|
|
355
|
+
DeployType?: string;
|
|
356
|
+
PreVersionName?: string;
|
|
357
|
+
VersionName?: string;
|
|
358
|
+
PipelineId?: number;
|
|
359
|
+
PipelineTaskId?: number;
|
|
360
|
+
ReleaseId?: number;
|
|
361
|
+
Status?: string;
|
|
362
|
+
Steps?: ITaskStepInfo[];
|
|
363
|
+
FailReason?: string;
|
|
364
|
+
OperatorRemark?: string;
|
|
365
|
+
}
|
|
366
|
+
export interface IObjectKVPriority {
|
|
367
|
+
Key?: string;
|
|
368
|
+
Value?: string;
|
|
369
|
+
Priority?: number;
|
|
370
|
+
}
|
|
371
|
+
export interface IVersionInfo {
|
|
372
|
+
VersionName?: string;
|
|
373
|
+
FlowRatio?: number;
|
|
374
|
+
Status?: string;
|
|
375
|
+
CreatedTime?: string;
|
|
376
|
+
UpdatedTime?: string;
|
|
377
|
+
BuildId?: number;
|
|
378
|
+
UploadType?: string;
|
|
379
|
+
Remark?: string;
|
|
380
|
+
UrlParam?: IObjectKV;
|
|
381
|
+
Priority?: number;
|
|
382
|
+
IsDefaultPriority?: boolean;
|
|
383
|
+
FlowParams?: IObjectKVPriority[];
|
|
384
|
+
MinReplicas?: number;
|
|
385
|
+
MaxReplicas?: number;
|
|
386
|
+
RunId?: string;
|
|
387
|
+
Percent?: number;
|
|
388
|
+
CurrentReplicas?: number;
|
|
389
|
+
Architecture?: string;
|
|
390
|
+
}
|
|
391
|
+
export interface IObjectKV {
|
|
392
|
+
Key: string;
|
|
393
|
+
Value: string;
|
|
394
|
+
}
|
|
395
|
+
export interface IReleaseOrderInfo {
|
|
396
|
+
Id?: number;
|
|
397
|
+
ServerName?: string;
|
|
398
|
+
CurrentVersion?: IVersionInfo;
|
|
399
|
+
ReleaseVersion?: IVersionInfo;
|
|
400
|
+
GrayStatus?: string;
|
|
401
|
+
ReleaseStatus?: string;
|
|
402
|
+
TrafficTypeValues?: IObjectKV[];
|
|
403
|
+
TrafficType?: string;
|
|
404
|
+
FlowRatio?: number;
|
|
405
|
+
CreateTime?: string;
|
|
406
|
+
IsReleasing?: boolean;
|
|
407
|
+
}
|
|
@@ -25,6 +25,16 @@ export interface ICloudFunction extends ICloudFunctionConfig {
|
|
|
25
25
|
name: string;
|
|
26
26
|
description?: string;
|
|
27
27
|
type?: 'Event' | 'HTTP';
|
|
28
|
+
protocolType?: 'WS';
|
|
29
|
+
protocolParams?: {
|
|
30
|
+
wsParams?: {
|
|
31
|
+
idleTimeOut?: number;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
instanceConcurrencyConfig?: {
|
|
35
|
+
dynamicEnabled?: 'FALSE';
|
|
36
|
+
maxConcurrency?: number;
|
|
37
|
+
};
|
|
28
38
|
handler?: string;
|
|
29
39
|
codeSecret?: string;
|
|
30
40
|
isWaitInstall?: boolean;
|