aiot-toolkit 2.0.3-beta.1 → 2.0.3-beta.11
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/README.md +2 -0
- package/lib/bin.js +158 -184
- package/lib/builder/AndroidUxBuilder.js +14 -15
- package/lib/builder/IBuilder.d.ts +6 -0
- package/lib/builder/IBuilder.js +1 -2
- package/lib/builder/UxBuilderBase.d.ts +8 -7
- package/lib/builder/UxBuilderBase.js +130 -111
- package/lib/builder/VelaUxBuilder.d.ts +12 -11
- package/lib/builder/VelaUxBuilder.js +65 -61
- package/lib/builder/XtsBuilder.d.ts +2 -0
- package/lib/builder/XtsBuilder.js +85 -78
- package/lib/index.js +48 -13
- package/lib/interface/CommandInterface.js +4 -1
- package/lib/interface/VelaEmulatorInterface.js +4 -1
- package/lib/starter/AndroidUxStart.js +158 -158
- package/lib/starter/IStarter.js +39 -37
- package/lib/starter/VelaUxStarter.d.ts +8 -3
- package/lib/starter/VelaUxStarter.js +158 -189
- package/lib/starter/XtsStarter.js +16 -17
- package/lib/starter/androidRouter/LinkMode.js +12 -8
- package/lib/starter/androidRouter/PackageRouter.js +144 -140
- package/lib/utils/AdbUtils.js +48 -76
- package/lib/utils/DeviceUtil.js +277 -293
- package/lib/utils/RequestUtils.js +54 -68
- package/lib/utils/VelaAvdUtils.d.ts +9 -54
- package/lib/utils/VelaAvdUtils.js +128 -436
- package/lib/waiter.js +35 -35
- package/package.json +9 -15
|
@@ -1,152 +1,156 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
var
|
|
12
|
-
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
const shared_utils_1 = require("@aiot-toolkit/shared-utils");
|
|
16
|
-
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
17
|
-
const path_1 = __importDefault(require("path"));
|
|
18
|
-
const qr_image_1 = __importDefault(require("qr-image"));
|
|
19
|
-
const LinkMode_1 = __importDefault(require("./LinkMode"));
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _sharedUtils = require("@aiot-toolkit/shared-utils");
|
|
8
|
+
var _fsExtra = _interopRequireDefault(require("fs-extra"));
|
|
9
|
+
var _path = _interopRequireDefault(require("path"));
|
|
10
|
+
var _qrImage = _interopRequireDefault(require("qr-image"));
|
|
11
|
+
var _LinkMode = _interopRequireDefault(require("./LinkMode"));
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
20
13
|
const CLIENT_PORT = 39517;
|
|
21
14
|
/**
|
|
22
15
|
* 打包相关的路由配置
|
|
23
16
|
* 用于开发机的httpServer
|
|
24
17
|
*/
|
|
25
18
|
class PackageRouter {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
path: '/bundle', // 获取 rpk 包
|
|
37
|
-
handler: (ctx, next) => {
|
|
38
|
-
this.recordDevice(ctx);
|
|
39
|
-
return this.handlerDownLoadRpk(ctx, next);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
];
|
|
43
|
-
/**
|
|
44
|
-
* 下载 rpk 包
|
|
45
|
-
* @param ctx
|
|
46
|
-
* @param next
|
|
47
|
-
*/
|
|
48
|
-
this.handlerDownLoadRpk = (ctx, next) => {
|
|
49
|
-
const { projectPath, options } = this.param;
|
|
50
|
-
const dist = path_1.default.join(projectPath, options.releasePath);
|
|
51
|
-
const files = fs_extra_1.default.readdirSync(dist).filter((item) => path_1.default.extname(item) === '.rpk');
|
|
52
|
-
const filePath = files.length ? path_1.default.join(dist, files[0]) : '';
|
|
53
|
-
this.download(filePath, ctx);
|
|
54
|
-
return next();
|
|
55
|
-
};
|
|
56
|
-
this.handlerQrCode = (ctx, next) => {
|
|
57
|
-
const qrText = ctx.origin;
|
|
58
|
-
const image = qr_image_1.default.image(qrText, {
|
|
59
|
-
size: 9
|
|
60
|
-
});
|
|
61
|
-
ctx.type = 'image/png';
|
|
62
|
-
ctx.body = image;
|
|
63
|
-
return next();
|
|
64
|
-
};
|
|
65
|
-
/**
|
|
66
|
-
* 记录设备信息
|
|
67
|
-
*
|
|
68
|
-
* 获取请求的 ip 和端口,记录到本机中,最多记录5个
|
|
69
|
-
*
|
|
70
|
-
* 文件内容的格式为:
|
|
71
|
-
* ```
|
|
72
|
-
* records: {
|
|
73
|
-
* "快应用项目路径":[
|
|
74
|
-
* {ip:"", port:""},
|
|
75
|
-
* {ip:"", port:""},
|
|
76
|
-
* {ip:"", port:""}
|
|
77
|
-
* ]
|
|
78
|
-
* }
|
|
79
|
-
* ```
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* 此记录的作用是:当重新打包后,获取已连接的设备列表
|
|
83
|
-
* @param ctx
|
|
84
|
-
* @param next
|
|
85
|
-
*/
|
|
86
|
-
this.recordDevice = (ctx) => __awaiter(this, void 0, void 0, function* () {
|
|
87
|
-
const clientInfo = this.getClientFromRequest(ctx);
|
|
88
|
-
if (!(clientInfo === null || clientInfo === void 0 ? void 0 : clientInfo.clientIp)) {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
if (clientInfo.linkMode === LinkMode_1.default.WIFI) {
|
|
92
|
-
const max = 5;
|
|
93
|
-
const filePath = this.param.options.clientRecordPath;
|
|
94
|
-
const projectPath = this.param.projectPath;
|
|
95
|
-
const data = {
|
|
96
|
-
sn: clientInfo.sn,
|
|
97
|
-
ip: clientInfo.clientIp,
|
|
98
|
-
port: CLIENT_PORT
|
|
99
|
-
};
|
|
100
|
-
const json = fs_extra_1.default.readJSONSync(filePath, { throws: false }) || {};
|
|
101
|
-
if (!json.records) {
|
|
102
|
-
json.records = {};
|
|
103
|
-
}
|
|
104
|
-
if (!json.records[projectPath]) {
|
|
105
|
-
json.records[projectPath] = [];
|
|
106
|
-
}
|
|
107
|
-
const deviceList = json.records[projectPath];
|
|
108
|
-
if (deviceList.findIndex((item) => item.ip === data.ip) < 0) {
|
|
109
|
-
deviceList.push(data);
|
|
110
|
-
if (deviceList.length > max) {
|
|
111
|
-
deviceList.splice(0, deviceList.length - max);
|
|
112
|
-
}
|
|
113
|
-
fs_extra_1.default.ensureDirSync(path_1.default.dirname(filePath));
|
|
114
|
-
fs_extra_1.default.writeJSONSync(filePath, json, { spaces: 2 });
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
});
|
|
19
|
+
constructor(param) {
|
|
20
|
+
this.param = param;
|
|
21
|
+
}
|
|
22
|
+
routeList = [{
|
|
23
|
+
path: '/qrcode',
|
|
24
|
+
// 获取二维码图片
|
|
25
|
+
handler: (ctx, next) => {
|
|
26
|
+
return this.handlerQrCode(ctx, next);
|
|
118
27
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
linkMode = LinkMode_1.default.ADB;
|
|
126
|
-
}
|
|
127
|
-
else if (clientIp !== '127.0.0.1' && clientIp !== serverIp) {
|
|
128
|
-
linkMode = LinkMode_1.default.WIFI;
|
|
129
|
-
}
|
|
130
|
-
return { clientIp, sn, linkMode };
|
|
28
|
+
}, {
|
|
29
|
+
path: '/bundle',
|
|
30
|
+
// 获取 rpk 包
|
|
31
|
+
handler: (ctx, next) => {
|
|
32
|
+
this.recordDevice(ctx);
|
|
33
|
+
return this.handlerDownLoadRpk(ctx, next);
|
|
131
34
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
35
|
+
}];
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 下载 rpk 包
|
|
39
|
+
* @param ctx
|
|
40
|
+
* @param next
|
|
41
|
+
*/
|
|
42
|
+
handlerDownLoadRpk = (ctx, next) => {
|
|
43
|
+
const {
|
|
44
|
+
projectPath,
|
|
45
|
+
options
|
|
46
|
+
} = this.param;
|
|
47
|
+
const dist = _path.default.join(projectPath, options.releasePath);
|
|
48
|
+
const files = _fsExtra.default.readdirSync(dist).filter(item => _path.default.extname(item) === '.rpk');
|
|
49
|
+
const filePath = files.length ? _path.default.join(dist, files[0]) : '';
|
|
50
|
+
this.download(filePath, ctx);
|
|
51
|
+
return next();
|
|
52
|
+
};
|
|
53
|
+
handlerQrCode = (ctx, next) => {
|
|
54
|
+
const qrText = ctx.origin;
|
|
55
|
+
const image = _qrImage.default.image(qrText, {
|
|
56
|
+
size: 9
|
|
57
|
+
});
|
|
58
|
+
ctx.type = 'image/png';
|
|
59
|
+
ctx.body = image;
|
|
60
|
+
return next();
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* 记录设备信息
|
|
65
|
+
*
|
|
66
|
+
* 获取请求的 ip 和端口,记录到本机中,最多记录5个
|
|
67
|
+
*
|
|
68
|
+
* 文件内容的格式为:
|
|
69
|
+
* ```
|
|
70
|
+
* records: {
|
|
71
|
+
* "快应用项目路径":[
|
|
72
|
+
* {ip:"", port:""},
|
|
73
|
+
* {ip:"", port:""},
|
|
74
|
+
* {ip:"", port:""}
|
|
75
|
+
* ]
|
|
76
|
+
* }
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
*
|
|
80
|
+
* 此记录的作用是:当重新打包后,获取已连接的设备列表
|
|
81
|
+
* @param ctx
|
|
82
|
+
* @param next
|
|
83
|
+
*/
|
|
84
|
+
recordDevice = async ctx => {
|
|
85
|
+
const clientInfo = this.getClientFromRequest(ctx);
|
|
86
|
+
if (!clientInfo?.clientIp) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (clientInfo.linkMode === _LinkMode.default.WIFI) {
|
|
90
|
+
const max = 5;
|
|
91
|
+
const filePath = this.param.options.clientRecordPath;
|
|
92
|
+
const projectPath = this.param.projectPath;
|
|
93
|
+
const data = {
|
|
94
|
+
sn: clientInfo.sn,
|
|
95
|
+
ip: clientInfo.clientIp,
|
|
96
|
+
port: CLIENT_PORT
|
|
97
|
+
};
|
|
98
|
+
const json = _fsExtra.default.readJSONSync(filePath, {
|
|
99
|
+
throws: false
|
|
100
|
+
}) || {};
|
|
101
|
+
if (!json.records) {
|
|
102
|
+
json.records = {};
|
|
103
|
+
}
|
|
104
|
+
if (!json.records[projectPath]) {
|
|
105
|
+
json.records[projectPath] = [];
|
|
106
|
+
}
|
|
107
|
+
const deviceList = json.records[projectPath];
|
|
108
|
+
if (deviceList.findIndex(item => item.ip === data.ip) < 0) {
|
|
109
|
+
deviceList.push(data);
|
|
110
|
+
if (deviceList.length > max) {
|
|
111
|
+
deviceList.splice(0, deviceList.length - max);
|
|
149
112
|
}
|
|
113
|
+
_fsExtra.default.ensureDirSync(_path.default.dirname(filePath));
|
|
114
|
+
_fsExtra.default.writeJSONSync(filePath, json, {
|
|
115
|
+
spaces: 2
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
getClientFromRequest(ctx) {
|
|
121
|
+
const clientIp = _sharedUtils.NetworkUtil.getClientIp(ctx);
|
|
122
|
+
const serverIp = _sharedUtils.NetworkUtil.getIPv4IPAddress();
|
|
123
|
+
const sn = ctx.request.header['device-serial-number'];
|
|
124
|
+
let linkMode = _LinkMode.default.NULL;
|
|
125
|
+
if (clientIp === '127.0.0.1' && sn) {
|
|
126
|
+
linkMode = _LinkMode.default.ADB;
|
|
127
|
+
} else if (clientIp !== '127.0.0.1' && clientIp !== serverIp) {
|
|
128
|
+
linkMode = _LinkMode.default.WIFI;
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
clientIp,
|
|
132
|
+
sn,
|
|
133
|
+
linkMode
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* http 请求中,用于返回下载文件
|
|
139
|
+
*
|
|
140
|
+
* 调用此方法后,仍需调用 next()
|
|
141
|
+
*
|
|
142
|
+
* @param filePath 文件绝对路径
|
|
143
|
+
* @param ctx 请求上下文
|
|
144
|
+
*/
|
|
145
|
+
download(filePath, ctx) {
|
|
146
|
+
if (filePath && _fsExtra.default.existsSync(filePath)) {
|
|
147
|
+
ctx.set('Content-Type', 'application/octet-stream');
|
|
148
|
+
ctx.set('Content-Transfer-Encoding', 'binary');
|
|
149
|
+
ctx.set('Content-Disposition', `attachment; filename=${_path.default.basename(filePath)}`);
|
|
150
|
+
ctx.body = _fsExtra.default.createReadStream(filePath);
|
|
151
|
+
} else {
|
|
152
|
+
ctx.throw('404', 404);
|
|
150
153
|
}
|
|
154
|
+
}
|
|
151
155
|
}
|
|
152
|
-
exports.default = PackageRouter;
|
|
156
|
+
var _default = exports.default = PackageRouter;
|
package/lib/utils/AdbUtils.js
CHANGED
|
@@ -1,83 +1,55 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
17
5
|
});
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
-
const shared_utils_1 = require("@aiot-toolkit/shared-utils");
|
|
36
|
-
const adbMiwt = __importStar(require("@miwt/adb"));
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _sharedUtils = require("@aiot-toolkit/shared-utils");
|
|
8
|
+
var adbMiwt = _interopRequireWildcard(require("@miwt/adb"));
|
|
9
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
10
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
37
11
|
/**
|
|
38
12
|
* AdbUtils
|
|
39
13
|
*/
|
|
40
14
|
class AdbUtils {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
});
|
|
81
|
-
}
|
|
15
|
+
// 连接设备
|
|
16
|
+
static async connect(ip, port) {
|
|
17
|
+
const adbConnet = await adbMiwt.execAdbCmdAsync(`adb connect ${ip}:${port}`);
|
|
18
|
+
return adbConnet.indexOf('connected to') >= 0;
|
|
19
|
+
}
|
|
20
|
+
// 获取所有已连接的设备(包含无线连接设备)
|
|
21
|
+
static async getAllConnectedDevices() {
|
|
22
|
+
const res = await adbMiwt.getAdbDevices();
|
|
23
|
+
return res.map(_ref => {
|
|
24
|
+
let {
|
|
25
|
+
sn
|
|
26
|
+
} = _ref;
|
|
27
|
+
return sn;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// 安装设备
|
|
32
|
+
static async installApk(sn, apkPath) {
|
|
33
|
+
const result = await adbMiwt.installApk(sn, apkPath);
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
// 启动调试器
|
|
37
|
+
static async startDebugger(deviceSn) {
|
|
38
|
+
const adbShell = adbMiwt.execAdbCmd(`adb -s ${deviceSn} shell am start -n "org.hapjs.debugger/.MainActivity"`);
|
|
39
|
+
adbShell.stdout.on('data', data => {
|
|
40
|
+
// 监听stderr事件,获取输出内容
|
|
41
|
+
_sharedUtils.ColorConsole.log(`### startDebugger ### ${data}`);
|
|
42
|
+
});
|
|
43
|
+
adbShell.stderr.on('data', data => {
|
|
44
|
+
// 监听stderr事件,获取输出内容
|
|
45
|
+
if (data.indexOf('Error') >= 0) {
|
|
46
|
+
_sharedUtils.ColorConsole.throw(`### startDebugger ### ${data}`);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
adbShell.on('close', () => {
|
|
50
|
+
// 处理命令正常结束
|
|
51
|
+
Promise.resolve();
|
|
52
|
+
});
|
|
53
|
+
}
|
|
82
54
|
}
|
|
83
|
-
exports.default = AdbUtils;
|
|
55
|
+
var _default = exports.default = AdbUtils;
|