aiot-toolkit 1.0.20-importfile-dev.1 → 1.0.20

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.
@@ -1,2 +1,674 @@
1
- "use strict";function ownKeys(e,r){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),o.push.apply(o,t)}return o}function _objectSpread(e){for(var r=1;r<arguments.length;r++){var o=null!=arguments[r]?arguments[r]:{};r%2?ownKeys(Object(o),!0).forEach((function(r){_defineProperty(e,r,o[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(o)):ownKeys(Object(o)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(o,r))}))}return e}function _defineProperty(e,r,o){return r in e?Object.defineProperty(e,r,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[r]=o,e}const path=require("path"),fs=require("fs"),chalk=require("chalk"),inquirer=require("inquirer"),adbCommander=require("adb-commander"),{launchServer:launchServer}=require("@aiot-toolkit/server"),{compile:compile}=require("./compile"),{colorconsole:colorconsole}=require("@aiot-toolkit/shared-utils"),{downloadFile:downloadFile,getQuickappDebuggerUrl:getQuickappDebuggerUrl,getQuickappPreviewUrl:getQuickappPreviewUrl,sendReq:sendReq,getClients:getClients,checkQuickappDir:checkQuickappDir,getCardContent:getCardContent}=require("./utils"),{recordClient:recordClient,clearProjectRecord:clearProjectRecord}=require("@aiot-toolkit/shared-utils/lib/record-client"),{clientRecordPath:clientRecordPath}=require("@aiot-toolkit/shared-utils/config"),ipRegExp=/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,CLIENT_PORT=39517;async function connectDevice(e=""){try{const r="Yes, connect a new wifi device";if(!e){if((await inquirer.prompt([{name:"type",type:"list",message:"(USB devices will automatically connect) Choose whether to connect to a new wifi device, and fill in its IP address later:",choices:[r,"Skip, keep connected device"]}])).type!==r)return Promise.resolve();e=(await inquirer.prompt([{name:"ip",message:'Please enter the IP address of the device under wifi(eg:192.168.1.1),make sure that the computer and the device are under the same wifi。If you need to enter multiple IPs, please separate them with ",":',default:null}])).ip}if(0===e.length)return colorconsole.info("Since no ip address is entered, the connected device will be connected"),Promise.resolve();const o=e.trim().split(","),t=o.filter((e=>!ipRegExp.test(e)));if(!t||!t.length){const e=Array.from(o,(e=>adbCommander.exeCommand(`adb connect ${e}:5555`).then((({result:r,err:o})=>((o||r.indexOf("failed")>=0)&&(colorconsole.error(`wifi connection ip: The device with ip of "${e}" failed`),process.exit()),colorconsole.info(`wifi connection ip: The device with ip of "${e}" succeeded`),recordClient(clientRecordPath,{ip:e,port:39517}),Promise.resolve())))));return Promise.all(e).then((()=>(colorconsole.log("All new WIFI devices are connected"),Promise.resolve()))).catch((()=>{process.exit()}))}t.map((e=>{colorconsole.error(`ip: ${e} is invalid IP`)})),process.exit()}catch(e){return Promise.reject(new Error(`Error connecting to the device, error message:${e.message}`))}}async function getConnectDevices(e=!0){try{return adbCommander.deviceList().then((({deviceList:r,err:o})=>{if(o){const e="Error getting connection information of adb device";colorconsole.throw(e,o)}if(r.length>0)return e&&colorconsole.info(`Devices connected via adb: ${chalk.yellow(r.join(", "))}.`),Promise.resolve(r);{const e="No device is currently connected, please check the following preparations in turn:\n 1. Whether the device is started;\n 2. Whether in the same LAN WI-FI;\n 3. Whether the device can be connected to the computer via USB;";colorconsole.throw(e)}}))}catch(e){return Promise.reject(new Error(e.message))}}async function downloadApk(e,r){let o="";const{apkVersion:t}=e;o=r?getQuickappDebuggerUrl(t):getQuickappPreviewUrl(t);const n=path.basename(o),i=path.join(__dirname,"./apk/",n);return fs.existsSync(i)?(colorconsole.log("The installation package has been downloaded, now use the cache file to install"),i):downloadFile(o,n).then((e=>(colorconsole.info(e),i))).catch((e=>{colorconsole.error("Failed to download the installation package",e),process.exit()}))}async function installApk(e,r=[],o,t,n){const{forceInstall:i=!1}=e;try{const e=Array.from(r,(e=>adbCommander.isInstalled(e,t).then((async({isInstalled:r,err:c})=>(c&&colorconsole.error(`Failed to install application "${chalk.yellow(n)}" on "${chalk.yellow(e)}" device, error message:${JSON.stringify(c)} `),!1===r||i?(await adbCommander.uninstall(e,t),colorconsole.log(`Start to install application "${chalk.yellow(n)}" on device "${chalk.yellow(e)}" : `),adbCommander.install(e,o).then((({result:r,err:o})=>o?(colorconsole.error(`Failed to install application "${chalk.yellow(n)}" on device "${chalk.yellow(e)}", please troubleshoot and try again `),Promise.reject(new Error(`Failed to install application "${chalk.yellow(n)}" on device "${chalk.yellow(e)}", please troubleshoot and try again `))):adbCommander.isInstalled(e,t).then((({isInstalled:r,err:o})=>{if(!0===r)return colorconsole.info(`Successfully installed application "${chalk.yellow(n)}" on device "${chalk.yellow(e)}" `),Promise.resolve()}))))):(colorconsole.warn(`Application "${chalk.yellow(n)}" has been installed on device "${chalk.yellow(e)}", so the installation did not continue this time`),Promise.resolve()))))));return Promise.all(e).then((()=>(colorconsole.log("All devices installed"),Promise.resolve()))).catch((()=>{process.exit()}))}catch(e){return Promise.reject(e)}}async function startServer(e){const{address:r}=await launchServer(_objectSpread({clearRecords:!0},e));return await compile("native","dev",!0,e),r}async function installdbg(e,r=!0){try{const{ip:o}=e;r&&await connectDevice(o);const t=await getConnectDevices(r),n=await queryDevice(t,"Install Quickapp debugger"),i=await downloadApk(e,!0);return await installApk(e,n,i,"org.hapjs.debugger","Quickapp debugger"),Promise.resolve("All devices successfully installed the Quickapp debugger")}catch(e){return Promise.reject(new Error(`Failed to install debugger, error message:${e.message}`))}}async function installmkp(e,r=!0){try{const{ip:o}=e;r&&await connectDevice(o);const t=await getConnectDevices(r),n=await queryDevice(t,"Install the Quickapp preview version"),i=await downloadApk(e);return await installApk(e,n,i,"org.hapjs.mockup","Quickapp preview version"),Promise.resolve("All devices successfully installed the Quickapp preview version")}catch(e){return Promise.reject(new Error(`Failed to install the preview version of Quickapp, error message:${e.message}`))}}async function queryDevice(e,r=""){if(!e||0===e.length)return void colorconsole.error("No device is connected yet, please confirm and try again");const o="All connected devices",t=(await inquirer.prompt([{name:"device",type:"list",message:`Please select the device that needs to execute command "${r}":`,choices:[...e,o]}])).device;return t===o?e:[t]}async function startDebugger(e=[],r){colorconsole.info("Starting the debugger for the connected device...");const o=Array.from(e,(e=>adbCommander.exeCommand(`adb -s ${e} shell am start -n "org.hapjs.debugger/.MainActivity" ${r}`).then((({err:r})=>r?(colorconsole.error(`Failed to start "Quickapp Debugger" on device "${chalk.yellow(e)}", please troubleshoot and try again`),Promise.reject(new Error(JSON.stringify(r)))):(colorconsole.info(`Successfully start "Quickapp Debugger" on device "${chalk.yellow(e)}" `),Promise.resolve())))));return Promise.all(o).then((()=>(colorconsole.info("The debuggers of all devices have started up"),Promise.resolve()))).catch((()=>{process.exit()}))}async function runapp(e,r=!0,o=!0){try{e.log&&colorconsole.attach(e.log);const{debugMode:t=!1,cardMode:n=!1}=e;let i="",c="",a="";const s=process.cwd();let l=e.includeStaticResources?"":"src";if(checkQuickappDir(s,l),n){colorconsole.warn('Please enable the "self-start" and "associated start" permissions of the Quickapp debugger and preview engine in the Android system');const e=getCardContent(s);if(e){const r=Object.keys(e);if(r.length>1){const o=await inquirer.prompt([{name:"cardName",type:"list",message:"Please select a card for debugging:",choices:r}]);c=e[o.cardName].path||`/${o.cardName}`}else c=e[r[0]].path||`/${r[0]}`;a+=`-e cardMode true -e cardPath ${c}`}}clearProjectRecord(clientRecordPath),i=await startServer(e),a+=` -e path ${i}`,i||(colorconsole.error("Failed to start local Quickapp service, please troubleshoot and try again"),process.exit()),o&&await connectDevice();const d=await getConnectDevices(r);d&&0!==d.length||(colorconsole.error("No connected devices available!!"),process.exit()),await startDebugger(d,a),setTimeout((async()=>{const e=await getClients();e||(colorconsole.error("No connected devices available!!"),process.exit());for(let r of e){const{sn:e,ip:o}=r;if("127.0.0.1"===o&&e.includes(":5555"))continue;const n=e&&e.length>0?e:o,i=()=>{colorconsole.error(`Error when device "${n}" gets the list of running platforms, request again after 3s delay`),setTimeout((()=>{c()}),3e3)},c=async()=>{let e=await sendReq(r,"/availablePlatforms");e||i(),e=JSON.parse(e);const{availablePlatforms:c}=e;if(c){let e;if(0===c.length)return void colorconsole.error(`Quickapp Engine is not installed on device ${o}`);if(1===c.length)e=c[0].pkg;else if(c.length>1){const r=await inquirer.prompt([{name:"name",type:"list",message:`Multiple Quickapp engines are detected on device "${n}", please select the operating platform:`,choices:c}]);c.forEach((o=>{o.name===r.name&&(e=o.pkg)}))}"OK"===await sendReq(r,"/platform",{selectedPlatform:e})&&sendReq(r,"/update",{debug:t})}else i()};await c()}}),3e3)}catch(e){return Promise.reject(new Error(`Error running RPK on the device, error message:${e.message}`))}}async function installAndRun(e){try{const r=process.cwd();checkQuickappDir(r),await installdbg(e),await installmkp(e,!1),await runapp(Object.assign({},e,{enableServerWatch:!0}),!1,!1)}catch(e){return Promise.reject(new Error(`One-click debugging error, error message:${e.message}`))}}async function getAvailablePlatform(e){try{const{ip:r,port:o,sn:t}=e;r&&ipRegExp.test(r)||(colorconsole.error("Did not pass in the correct ip address, eg: --ip 127.0.0.1"),process.exit()),o||(colorconsole.error("Did not pass in the correct port address,eg: --port 39517"),process.exit()),t||(colorconsole.error('Did not pass in the correct device serial number,view the serial number of the connected device through the "adb devices" command \n If it is a device connected via wifi, the format is "ip address:5555"'),process.exit());let n={ip:r,port:o};const i=()=>{colorconsole.error("Error when the device gets running platforms,request again after 3s delay"),setTimeout((()=>{c()}),3e3)},c=async()=>{let e=await sendReq(n,"/availablePlatforms");if(e)if(e=JSON.parse(e),e.availablePlatforms){const r=e.availablePlatforms;colorconsole.info(`The Quickapp engine list of device "${t}" is:${r.join(", ")}`)}else i();else i()};adbCommander.exeCommand(`adb -s ${t} shell am start -n "org.hapjs.debugger/.MainActivity"`).then((({err:e})=>{e&&(colorconsole.error("The debugger does not start normally, please check if it is installed"),process.exit()),colorconsole.info(`The debugger successfully runs on device "${chalk.yellow(t)}"`),colorconsole.info(`Device "${t}" is getting the list of fast application engines...`),c()}))}catch(e){colorconsole.error(`Error getting the list of Quickapp engines on the device, error message:${e.message}`)}}async function getAllConnectedDevices(e){try{return adbCommander.deviceList().then((({deviceList:e,err:r})=>{if(!r)return Promise.resolve(e);colorconsole.throw(r)}))}catch(e){return Promise.reject(new Error(`Error getting the array of all connected devices, error message:${e.message}`))}}module.exports={installAndRun:installAndRun,installdbg:installdbg,installmkp:installmkp,runapp:runapp,getAvailablePlatform:getAvailablePlatform,getAllConnectedDevices:getAllConnectedDevices};
1
+ "use strict";
2
+
3
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
4
+
5
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
6
+
7
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
8
+
9
+ const path = require('path');
10
+
11
+ const fs = require('fs');
12
+
13
+ const chalk = require('chalk');
14
+
15
+ const inquirer = require('inquirer');
16
+
17
+ const adbCommander = require('adb-commander');
18
+
19
+ const {
20
+ launchServer
21
+ } = require('@aiot-toolkit/server');
22
+
23
+ const {
24
+ compile
25
+ } = require('./compile');
26
+
27
+ const {
28
+ colorconsole
29
+ } = require('@aiot-toolkit/shared-utils');
30
+
31
+ const {
32
+ downloadFile,
33
+ getQuickappDebuggerUrl,
34
+ getQuickappPreviewUrl,
35
+ sendReq,
36
+ getClients,
37
+ checkQuickappDir,
38
+ getCardContent
39
+ } = require('./utils');
40
+
41
+ const {
42
+ recordClient,
43
+ clearProjectRecord
44
+ } = require('@aiot-toolkit/shared-utils/lib/record-client');
45
+
46
+ const {
47
+ clientRecordPath
48
+ } = require('@aiot-toolkit/shared-utils/config');
49
+
50
+ const ipRegExp = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
51
+ const CLIENT_PORT = 39517;
52
+ /**
53
+ * 如果是TV等AIOT设备,需要通过IP连接
54
+ * @param {string} ip - ip字符串数组
55
+ */
56
+
57
+ async function connectDevice(ip = '') {
58
+ try {
59
+ const WIFI_TEXT = 'Yes, connect a new wifi device';
60
+
61
+ if (!ip) {
62
+ const connectType = await inquirer.prompt([{
63
+ name: 'type',
64
+ type: 'list',
65
+ message: '(USB devices will automatically connect) Choose whether to connect to a new wifi device, and fill in its IP address later:',
66
+ choices: [WIFI_TEXT, 'Skip, keep connected device']
67
+ }]); // 开始连接Wi-Fi
68
+
69
+ if (connectType.type === WIFI_TEXT) {
70
+ const address = await inquirer.prompt([{
71
+ name: 'ip',
72
+ message: 'Please enter the IP address of the device under wifi(eg:192.168.1.1),make sure that the computer and the device are under the same wifi。If you need to enter multiple IPs, please separate them with ",":',
73
+ default: null
74
+ }]);
75
+ ip = address.ip;
76
+ } else {
77
+ return Promise.resolve();
78
+ }
79
+ }
80
+
81
+ if (ip.length === 0) {
82
+ colorconsole.info(`Since no ip address is entered, the connected device will be connected`);
83
+ return Promise.resolve();
84
+ }
85
+
86
+ const ips = ip.trim().split(',');
87
+ const invalidIps = ips.filter(ip => !ipRegExp.test(ip));
88
+
89
+ if (invalidIps && invalidIps.length) {
90
+ invalidIps.map(ip => {
91
+ colorconsole.error(`ip: ${ip} is invalid IP`);
92
+ });
93
+ process.exit();
94
+ } else {
95
+ const newDeviceListPromiseArray = Array.from(ips, ip => {
96
+ return adbCommander.exeCommand(`adb connect ${ip}:5555`).then(({
97
+ result,
98
+ err
99
+ }) => {
100
+ if (err || result.indexOf('failed') >= 0) {
101
+ colorconsole.error(`wifi connection ip: The device with ip of "${ip}" failed`);
102
+ process.exit();
103
+ }
104
+
105
+ colorconsole.info(`wifi connection ip: The device with ip of "${ip}" succeeded`); // 记录通过adb connect连接的设备
106
+
107
+ let client = {
108
+ ip: ip,
109
+ port: CLIENT_PORT
110
+ };
111
+ recordClient(clientRecordPath, client);
112
+ return Promise.resolve();
113
+ });
114
+ });
115
+ return Promise.all(newDeviceListPromiseArray).then(() => {
116
+ colorconsole.log('All new WIFI devices are connected');
117
+ return Promise.resolve();
118
+ }).catch(() => {
119
+ // 在抛出错误前已经弹出错误日志了,故这里直接退出
120
+ process.exit();
121
+ });
122
+ }
123
+ } catch (error) {
124
+ return Promise.reject(new Error(`Error connecting to the device, error message:${error.message}`));
125
+ }
126
+ }
127
+ /**
128
+ * 获取当前环境的连接设备
129
+ * @param {Boolean} isShowLog - 是否展示连接成功的日志
130
+ * @return {Array}} - 连接的设备数组
131
+ */
132
+
133
+
134
+ async function getConnectDevices(isShowLog = true) {
135
+ try {
136
+ return adbCommander.deviceList().then(({
137
+ deviceList,
138
+ err
139
+ }) => {
140
+ if (err) {
141
+ const errorMessage = 'Error getting connection information of adb device';
142
+ colorconsole.throw(errorMessage, err);
143
+ }
144
+
145
+ if (deviceList.length > 0) {
146
+ if (isShowLog) {
147
+ colorconsole.info(`Devices connected via adb: ${chalk.yellow(deviceList.join(', '))}.`);
148
+ }
149
+
150
+ return Promise.resolve(deviceList);
151
+ } else {
152
+ const errorMessage = `No device is currently connected, please check the following preparations in turn:\n 1. Whether the device is started;\n 2. Whether in the same LAN WI-FI;\n 3. Whether the device can be connected to the computer via USB;`;
153
+ colorconsole.throw(errorMessage);
154
+ }
155
+ });
156
+ } catch (error) {
157
+ return Promise.reject(new Error(error.message));
158
+ }
159
+ }
160
+ /**
161
+ * 下载并获取apk地址
162
+ * @param {Object} options - 命令参数
163
+ * @param {Boolean} isQuickappDebugger - 是否为调试器
164
+ */
165
+
166
+
167
+ async function downloadApk(options, isQuickappDebugger) {
168
+ let url = '';
169
+ const {
170
+ apkVersion: version
171
+ } = options;
172
+
173
+ if (isQuickappDebugger) {
174
+ url = getQuickappDebuggerUrl(version);
175
+ } else {
176
+ url = getQuickappPreviewUrl(version);
177
+ }
178
+
179
+ const filename = path.basename(url);
180
+ const apkPath = path.join(__dirname, './apk/', filename);
181
+
182
+ if (fs.existsSync(apkPath)) {
183
+ colorconsole.log('The installation package has been downloaded, now use the cache file to install');
184
+ return apkPath;
185
+ } else {
186
+ return downloadFile(url, filename).then(message => {
187
+ colorconsole.info(message);
188
+ return apkPath;
189
+ }).catch(err => {
190
+ colorconsole.error('Failed to download the installation package', err);
191
+ process.exit();
192
+ });
193
+ }
194
+ }
195
+ /**
196
+ * 安装调试器或预览版
197
+ * @param {Object} options - 命令参数
198
+ * @param {Array} deviceList - 连接的设备数组
199
+ * @param {String} apkPath - apk存放的地址
200
+ * @param {String} apkName - apk的名字
201
+ * @param {String} apkName - app的应用名
202
+ */
203
+
204
+
205
+ async function installApk(options, deviceList = [], apkPath, apkName, appName) {
206
+ const {
207
+ forceInstall = false
208
+ } = options;
209
+
210
+ try {
211
+ const newDeviceListPromiseArray = Array.from(deviceList, deviceSn => {
212
+ return adbCommander.isInstalled(deviceSn, apkName).then(async ({
213
+ isInstalled,
214
+ err
215
+ }) => {
216
+ // error 非标准错误Error类,因此需要序列化输出
217
+ if (err) {
218
+ colorconsole.error(`Failed to install application "${chalk.yellow(appName)}" on "${chalk.yellow(deviceSn)}" device, error message:${JSON.stringify(err)} `);
219
+ }
220
+
221
+ if (isInstalled === false || forceInstall) {
222
+ await adbCommander.uninstall(deviceSn, apkName);
223
+ colorconsole.log(`Start to install application "${chalk.yellow(appName)}" on device "${chalk.yellow(deviceSn)}" : `);
224
+ return adbCommander.install(deviceSn, apkPath).then(({
225
+ result,
226
+ err
227
+ }) => {
228
+ if (err) {
229
+ colorconsole.error(`Failed to install application "${chalk.yellow(appName)}" on device "${chalk.yellow(deviceSn)}", please troubleshoot and try again `);
230
+ return Promise.reject(new Error(`Failed to install application "${chalk.yellow(appName)}" on device "${chalk.yellow(deviceSn)}", please troubleshoot and try again `));
231
+ }
232
+
233
+ return adbCommander.isInstalled(deviceSn, apkName).then(({
234
+ isInstalled,
235
+ err
236
+ }) => {
237
+ if (isInstalled === true) {
238
+ colorconsole.info(`Successfully installed application "${chalk.yellow(appName)}" on device "${chalk.yellow(deviceSn)}" `);
239
+ return Promise.resolve();
240
+ }
241
+ });
242
+ });
243
+ } else {
244
+ colorconsole.warn(`Application "${chalk.yellow(appName)}" has been installed on device "${chalk.yellow(deviceSn)}", so the installation did not continue this time`);
245
+ return Promise.resolve();
246
+ }
247
+ });
248
+ });
249
+ return Promise.all(newDeviceListPromiseArray).then(() => {
250
+ colorconsole.log('All devices installed');
251
+ return Promise.resolve();
252
+ }).catch(() => {
253
+ // 在抛出错误前已经弹出错误日志了,故这里直接退出
254
+ process.exit();
255
+ });
256
+ } catch (error) {
257
+ return Promise.reject(error);
258
+ }
259
+ }
260
+ /**
261
+ * 启动server
262
+ * @param {Object} options - 命令参数
263
+ */
264
+
265
+
266
+ async function startServer(options) {
267
+ const {
268
+ address
269
+ } = await launchServer(_objectSpread({
270
+ clearRecords: true
271
+ }, options));
272
+ await compile('native', 'dev', true, options);
273
+ return address;
274
+ }
275
+ /**
276
+ * 安装调试器
277
+ * @param {Object} options - 命令参数
278
+ */
279
+
280
+
281
+ async function installdbg(options, isConnectDevice = true) {
282
+ try {
283
+ const {
284
+ ip
285
+ } = options; // 1. 连接设备
286
+
287
+ if (isConnectDevice) {
288
+ await connectDevice(ip);
289
+ } // 2. 获取连接设备
290
+
291
+
292
+ const deviceList = await getConnectDevices(isConnectDevice);
293
+ const finalDeviceList = await queryDevice(deviceList, 'Install Quickapp debugger'); // 3. 下载并获取调试器地址
294
+
295
+ const apkPath = await downloadApk(options, true); // 4. 安装调试器
296
+
297
+ await installApk(options, finalDeviceList, apkPath, 'org.hapjs.debugger', 'Quickapp debugger');
298
+ return Promise.resolve('All devices successfully installed the Quickapp debugger');
299
+ } catch (error) {
300
+ return Promise.reject(new Error(`Failed to install debugger, error message:${error.message}`));
301
+ }
302
+ }
303
+ /**
304
+ * 安装预览版
305
+ * @param {Object} options - 命令参数
306
+ * @param {Boolean} isConnectDevice - 是否需要连接设备
307
+ */
308
+
309
+
310
+ async function installmkp(options, isConnectDevice = true) {
311
+ try {
312
+ const {
313
+ ip
314
+ } = options; // 1. 连接设备
315
+
316
+ if (isConnectDevice) {
317
+ await connectDevice(ip);
318
+ } // 2. 获取连接设备
319
+
320
+
321
+ const deviceList = await getConnectDevices(isConnectDevice);
322
+ const finalDeviceList = await queryDevice(deviceList, 'Install the Quickapp preview version'); // 3. 下载并获取预览版地址
323
+
324
+ const apkPath = await downloadApk(options); // 4. 安装预览版
325
+
326
+ await installApk(options, finalDeviceList, apkPath, 'org.hapjs.mockup', 'Quickapp preview version');
327
+ return Promise.resolve('All devices successfully installed the Quickapp preview version');
328
+ } catch (error) {
329
+ return Promise.reject(new Error(`Failed to install the preview version of Quickapp, error message:${error.message}`));
330
+ }
331
+ } // 选择设备
332
+
333
+
334
+ async function queryDevice(deviceList, orderText = '') {
335
+ if (!deviceList || deviceList.length === 0) {
336
+ colorconsole.error(`No device is connected yet, please confirm and try again`);
337
+ return;
338
+ }
339
+
340
+ const ALL_TEXT = 'All connected devices'; // 可以选择一台设备或全部设备
341
+
342
+ const deviceChoice = await inquirer.prompt([{
343
+ name: 'device',
344
+ type: 'list',
345
+ message: `Please select the device that needs to execute command "${orderText}":`,
346
+ choices: [...deviceList, ALL_TEXT]
347
+ }]);
348
+ const choice = deviceChoice.device;
349
+ if (choice === ALL_TEXT) return deviceList;
350
+ return [choice];
351
+ }
352
+ /**
353
+ * 批量启动设备的调试器
354
+ * @param {Array} deviceList - 配置项
355
+ * @param {String} param - 需要传给调试器的额外参数
356
+ */
357
+
358
+
359
+ async function startDebugger(deviceList = [], param) {
360
+ colorconsole.info(`Starting the debugger for the connected device...`);
361
+ const newDeviceListPromiseArray = Array.from(deviceList, deviceSn => {
362
+ return adbCommander.exeCommand(`adb -s ${deviceSn} shell am start -n "org.hapjs.debugger/.MainActivity" ${param}`).then(({
363
+ err
364
+ }) => {
365
+ if (err) {
366
+ colorconsole.error(`Failed to start "Quickapp Debugger" on device "${chalk.yellow(deviceSn)}", please troubleshoot and try again`);
367
+ return Promise.reject(new Error(JSON.stringify(err)));
368
+ }
369
+
370
+ colorconsole.info(`Successfully start "Quickapp Debugger" on device "${chalk.yellow(deviceSn)}" `);
371
+ return Promise.resolve();
372
+ });
373
+ });
374
+ return Promise.all(newDeviceListPromiseArray).then(() => {
375
+ colorconsole.info('The debuggers of all devices have started up');
376
+ return Promise.resolve();
377
+ }).catch(() => {
378
+ // 在抛出错误前已经弹出错误日志了,故这里直接退出
379
+ process.exit();
380
+ });
381
+ }
382
+ /**
383
+ * 运行rpk在设备上
384
+ * @param {Object} options - 配置项
385
+ * @param {Writable} options.log -自定义日志输出流
386
+ * @param {Boolean} isShowLog - 是否展示连接成功的日志
387
+ * @param {Boolean} isConnectDevice - 是否需要连接设备
388
+ */
389
+
390
+
391
+ async function runapp(options, isShowLog = true, isConnectDevice = true) {
392
+ try {
393
+ options.log && colorconsole.attach(options.log);
394
+ const {
395
+ debugMode = false,
396
+ cardMode = false
397
+ } = options;
398
+ let url = '';
399
+ let cardPath = '';
400
+ let param = '';
401
+ const curDir = process.cwd(); // 1. 判断是否在快应用的目录下
402
+
403
+ let srcDir = options.includeStaticResources ? '' : 'src';
404
+ checkQuickappDir(curDir, srcDir); // 2. 如果携带参数cardMode,则开启卡片模式
405
+
406
+ if (cardMode) {
407
+ // 提醒用户打开自启动的权限
408
+ colorconsole.warn('Please enable the "self-start" and "associated start" permissions of the Quickapp debugger and preview engine in the Android system');
409
+ const cardContent = getCardContent(curDir);
410
+
411
+ if (cardContent) {
412
+ const cardKeys = Object.keys(cardContent);
413
+
414
+ if (cardKeys.length > 1) {
415
+ const card = await inquirer.prompt([{
416
+ name: 'cardName',
417
+ type: 'list',
418
+ message: 'Please select a card for debugging:',
419
+ choices: cardKeys
420
+ }]);
421
+ cardPath = cardContent[card.cardName].path || `/${card.cardName}`;
422
+ } else {
423
+ cardPath = cardContent[cardKeys[0]].path || `/${cardKeys[0]}`;
424
+ }
425
+
426
+ param += `-e cardMode true -e cardPath ${cardPath}`;
427
+ }
428
+ } // 3. 如果携带参数enableServerWatch或debugMode,则启动server
429
+ // 清空调试设备记录
430
+
431
+
432
+ clearProjectRecord(clientRecordPath);
433
+ url = await startServer(options);
434
+ param += ` -e path ${url}`;
435
+
436
+ if (!url) {
437
+ colorconsole.error(`Failed to start local Quickapp service, please troubleshoot and try again`);
438
+ process.exit();
439
+ } // 尝试连接设备
440
+
441
+
442
+ if (isConnectDevice) {
443
+ await connectDevice();
444
+ } // 4. 获取所有已连接设备
445
+
446
+
447
+ const deviceList = await getConnectDevices(isShowLog);
448
+
449
+ if (!deviceList || deviceList.length === 0) {
450
+ colorconsole.error(`No connected devices available!!`);
451
+ process.exit();
452
+ } // 5. 开始启动调试器
453
+
454
+
455
+ await startDebugger(deviceList, param);
456
+ setTimeout(async () => {
457
+ // 6. 调试器启动之后开始选择调试平台
458
+ const clients = await getClients();
459
+
460
+ if (!clients) {
461
+ colorconsole.error(`No connected devices available!!`);
462
+ process.exit();
463
+ }
464
+
465
+ for (let client of clients) {
466
+ // 只有usb连接的设备会有sn,所以标识wifi设备需要用ip地址
467
+ const {
468
+ sn,
469
+ ip
470
+ } = client; // 有一个wifi设备尝试连接,但因在record.json记录其ip为127.0.0.1,所以拒绝
471
+ // 部分电视盒子可能会存在此情况
472
+
473
+ if (ip === '127.0.0.1' && sn.includes(':5555')) {
474
+ continue;
475
+ }
476
+
477
+ const deviceName = sn && sn.length > 0 ? sn : ip; // 如果查询平台列表失败,则新建一个3s的轮询,继续查询
478
+
479
+ const delayRequest = () => {
480
+ colorconsole.error(`Error when device "${deviceName}" gets the list of running platforms, request again after 3s delay`);
481
+ setTimeout(() => {
482
+ runOnPlatform();
483
+ }, 3000);
484
+ };
485
+
486
+ const runOnPlatform = async () => {
487
+ let data = await sendReq(client, '/availablePlatforms');
488
+
489
+ if (!data) {
490
+ delayRequest();
491
+ }
492
+
493
+ data = JSON.parse(data);
494
+ const {
495
+ availablePlatforms
496
+ } = data;
497
+
498
+ if (!availablePlatforms) {
499
+ delayRequest();
500
+ } else {
501
+ let availablePlatform;
502
+
503
+ if (availablePlatforms.length === 0) {
504
+ colorconsole.error(`Quickapp Engine is not installed on device ${ip}`);
505
+ return;
506
+ } else if (availablePlatforms.length === 1) {
507
+ availablePlatform = availablePlatforms[0].pkg;
508
+ } else if (availablePlatforms.length > 1) {
509
+ const platform = await inquirer.prompt([{
510
+ name: 'name',
511
+ type: 'list',
512
+ message: `Multiple Quickapp engines are detected on device "${deviceName}", please select the operating platform:`,
513
+ choices: availablePlatforms
514
+ }]);
515
+ availablePlatforms.forEach(item => {
516
+ if (item.name === platform.name) {
517
+ availablePlatform = item.pkg;
518
+ }
519
+ });
520
+ } // 选择平台
521
+
522
+
523
+ const selectPlatformData = await sendReq(client, '/platform', {
524
+ selectedPlatform: availablePlatform
525
+ });
526
+
527
+ if (selectPlatformData === 'OK') {
528
+ // 启动预览版或引擎
529
+ sendReq(client, '/update', {
530
+ debug: debugMode
531
+ });
532
+ }
533
+ }
534
+ };
535
+
536
+ await runOnPlatform();
537
+ }
538
+ }, 3000);
539
+ } catch (error) {
540
+ return Promise.reject(new Error(`Error running RPK on the device, error message:${error.message}`));
541
+ }
542
+ }
543
+ /**
544
+ * 一键调试
545
+ * @param {Object} options - 命令参数
546
+ */
547
+
548
+
549
+ async function installAndRun(options) {
550
+ try {
551
+ const curDir = process.cwd(); // 1. 判断是否在快应用的目录下
552
+
553
+ checkQuickappDir(curDir); // 2. 安装调试器
554
+
555
+ await installdbg(options); // 3. 安装预览版
556
+ // 已在安装调试器的时候选择连接过设备了,这里省略
557
+
558
+ await installmkp(options, false); // 4. 通知调试器,运行rpk
559
+
560
+ await runapp(Object.assign({}, options, {
561
+ enableServerWatch: true
562
+ }), false, false);
563
+ } catch (error) {
564
+ return Promise.reject(new Error(`One-click debugging error, error message:${error.message}`));
565
+ }
566
+ }
567
+ /**
568
+ * 获取设备上的快应用包名数组,供IDE使用(需先安装调试器)
569
+ * @param {Object} options - 命令参数
570
+ * @param {Object} openLog - 是否命令行显示日志(IDE场景可选择关闭)
571
+ */
572
+
573
+
574
+ async function getAvailablePlatform(options) {
575
+ try {
576
+ const {
577
+ ip,
578
+ port,
579
+ sn: deviceSn
580
+ } = options;
581
+
582
+ if (!ip || !ipRegExp.test(ip)) {
583
+ colorconsole.error(`Did not pass in the correct ip address, eg: --ip 127.0.0.1`);
584
+ process.exit();
585
+ }
586
+
587
+ if (!port) {
588
+ colorconsole.error(`Did not pass in the correct port address,eg: --port 39517`);
589
+ process.exit();
590
+ }
591
+
592
+ if (!deviceSn) {
593
+ colorconsole.error(`Did not pass in the correct device serial number,view the serial number of the connected device through the "adb devices" command \n If it is a device connected via wifi, the format is "ip address:5555"`);
594
+ process.exit();
595
+ }
596
+
597
+ let client = {
598
+ ip,
599
+ port
600
+ };
601
+
602
+ const delayRequest = () => {
603
+ colorconsole.error(`Error when the device gets running platforms,request again after 3s delay`);
604
+ setTimeout(() => {
605
+ requestPlatform();
606
+ }, 3000);
607
+ };
608
+
609
+ const requestPlatform = async () => {
610
+ let data = await sendReq(client, '/availablePlatforms');
611
+
612
+ if (!data) {
613
+ delayRequest();
614
+ } else {
615
+ data = JSON.parse(data);
616
+
617
+ if (!data.availablePlatforms) {
618
+ delayRequest();
619
+ } else {
620
+ const availablePlatforms = data.availablePlatforms;
621
+ colorconsole.info(`The Quickapp engine list of device "${deviceSn}" is:${availablePlatforms.join(', ')}`);
622
+ }
623
+ }
624
+ }; // 先打开调试器,才能获取运行平台
625
+
626
+
627
+ adbCommander.exeCommand(`adb -s ${deviceSn} shell am start -n "org.hapjs.debugger/.MainActivity"`).then(({
628
+ err
629
+ }) => {
630
+ if (err) {
631
+ colorconsole.error(`The debugger does not start normally, please check if it is installed`);
632
+ process.exit();
633
+ }
634
+
635
+ colorconsole.info(`The debugger successfully runs on device "${chalk.yellow(deviceSn)}"`);
636
+ colorconsole.info(`Device "${deviceSn}" is getting the list of fast application engines...`);
637
+ requestPlatform();
638
+ });
639
+ } catch (error) {
640
+ colorconsole.error(`Error getting the list of Quickapp engines on the device, error message:${error.message}`);
641
+ }
642
+ }
643
+ /**
644
+ * 获取所有连接上的设备数组,供IDE使用(需先安装调试器)
645
+ * @param {Object} options - 命令参数
646
+ */
647
+
648
+
649
+ async function getAllConnectedDevices(options) {
650
+ try {
651
+ return adbCommander.deviceList().then(({
652
+ deviceList,
653
+ err
654
+ }) => {
655
+ if (err) {
656
+ colorconsole.throw(err);
657
+ } else {
658
+ return Promise.resolve(deviceList);
659
+ }
660
+ });
661
+ } catch (error) {
662
+ return Promise.reject(new Error(`Error getting the array of all connected devices, error message:${error.message}`));
663
+ }
664
+ }
665
+
666
+ module.exports = {
667
+ installAndRun,
668
+ installdbg,
669
+ installmkp,
670
+ runapp,
671
+ getAvailablePlatform,
672
+ getAllConnectedDevices
673
+ };
2
674
  //# sourceMappingURL=debug.js.map