@arkts/image-manager 0.2.3 → 0.3.1
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/default-product-config.d.cts +1 -1
- package/dist/default-product-config.d.mts +1 -1
- package/dist/index.cjs +269 -210
- package/dist/index.d.cts +266 -43
- package/dist/index.d.mts +266 -43
- package/dist/index.mjs +267 -210
- package/dist/product-config-2xNDbvax.d.cts +72 -0
- package/dist/product-config-CDvEXtfy.d.mts +72 -0
- package/package.json +3 -1
- package/dist/product-config-BwP_DEGj.d.mts +0 -263
- package/dist/product-config-C-0AD84Q.d.cts +0 -263
package/dist/index.cjs
CHANGED
|
@@ -28,6 +28,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
//#endregion
|
|
29
29
|
let axios = require("axios");
|
|
30
30
|
axios = __toESM(axios);
|
|
31
|
+
let semver_functions_satisfies = require("semver/functions/satisfies");
|
|
32
|
+
semver_functions_satisfies = __toESM(semver_functions_satisfies);
|
|
31
33
|
let mitt = require("mitt");
|
|
32
34
|
mitt = __toESM(mitt);
|
|
33
35
|
let progress_stream = require("progress-stream");
|
|
@@ -36,10 +38,10 @@ let unzipper = require("unzipper");
|
|
|
36
38
|
unzipper = __toESM(unzipper);
|
|
37
39
|
|
|
38
40
|
//#region package.json
|
|
39
|
-
var version = "0.
|
|
41
|
+
var version = "0.3.1";
|
|
40
42
|
|
|
41
43
|
//#endregion
|
|
42
|
-
//#region src/
|
|
44
|
+
//#region src/devices/list.ts
|
|
43
45
|
let DevModel = /* @__PURE__ */ function(DevModel) {
|
|
44
46
|
DevModel["MCHEMU_AL00CN"] = "MCHEMU-AL00CN";
|
|
45
47
|
DevModel["PHEMU_FD00"] = "PHEMU-FD00";
|
|
@@ -60,6 +62,9 @@ var DeployError = class extends Error {
|
|
|
60
62
|
this.message = message;
|
|
61
63
|
this.cause = cause;
|
|
62
64
|
}
|
|
65
|
+
getCode() {
|
|
66
|
+
return this.code;
|
|
67
|
+
}
|
|
63
68
|
};
|
|
64
69
|
(function(_DeployError) {
|
|
65
70
|
_DeployError.Code = /* @__PURE__ */ function(Code) {
|
|
@@ -84,221 +89,237 @@ var RequestUrlError = class extends Error {
|
|
|
84
89
|
};
|
|
85
90
|
|
|
86
91
|
//#endregion
|
|
87
|
-
//#region src/
|
|
88
|
-
var
|
|
89
|
-
options
|
|
90
|
-
|
|
91
|
-
isCustomize = false;
|
|
92
|
-
isPublic = true;
|
|
93
|
-
vendorCountry = "CN";
|
|
94
|
-
hwHdcPort = "notset";
|
|
95
|
-
constructor(image, uuid, name, config) {
|
|
96
|
-
this.image = image;
|
|
97
|
-
this.config = config;
|
|
98
|
-
this.options.uuid = uuid;
|
|
99
|
-
this.options.name = name;
|
|
100
|
-
Object.assign(this.options, config);
|
|
101
|
-
if ("productName" in this.options) delete this.options.productName;
|
|
92
|
+
//#region src/screens/screen.ts
|
|
93
|
+
var ScreenImpl = class {
|
|
94
|
+
constructor(options) {
|
|
95
|
+
this.options = options;
|
|
102
96
|
}
|
|
103
|
-
|
|
104
|
-
this.options.
|
|
105
|
-
return this;
|
|
97
|
+
getDiagonal() {
|
|
98
|
+
return this.options.diagonal;
|
|
106
99
|
}
|
|
107
|
-
|
|
108
|
-
this.options.
|
|
100
|
+
setDiagonal(diagonal) {
|
|
101
|
+
this.options.diagonal = diagonal;
|
|
109
102
|
return this;
|
|
110
103
|
}
|
|
111
|
-
|
|
112
|
-
this.options.
|
|
113
|
-
return this;
|
|
104
|
+
getDensity() {
|
|
105
|
+
return this.options.density;
|
|
114
106
|
}
|
|
115
|
-
|
|
116
|
-
this.options.
|
|
107
|
+
setDensity(density) {
|
|
108
|
+
this.options.density = density;
|
|
117
109
|
return this;
|
|
118
110
|
}
|
|
119
|
-
|
|
120
|
-
this.options.
|
|
121
|
-
return this;
|
|
111
|
+
getHeight() {
|
|
112
|
+
return this.options.height;
|
|
122
113
|
}
|
|
123
|
-
|
|
124
|
-
this.options.
|
|
114
|
+
setHeight(height) {
|
|
115
|
+
this.options.height = height;
|
|
125
116
|
return this;
|
|
126
117
|
}
|
|
127
|
-
|
|
128
|
-
this.options.
|
|
129
|
-
return this;
|
|
118
|
+
getWidth() {
|
|
119
|
+
return this.options.width;
|
|
130
120
|
}
|
|
131
|
-
|
|
132
|
-
this.options.
|
|
121
|
+
setWidth(width) {
|
|
122
|
+
this.options.width = width;
|
|
133
123
|
return this;
|
|
134
124
|
}
|
|
135
|
-
|
|
136
|
-
this.options
|
|
137
|
-
return this;
|
|
125
|
+
toJSON() {
|
|
126
|
+
return this.options;
|
|
138
127
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
128
|
+
};
|
|
129
|
+
function createScreen(options) {
|
|
130
|
+
return new ScreenImpl(options);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
//#endregion
|
|
134
|
+
//#region src/screens/product-preset.ts
|
|
135
|
+
var ProductPresetImpl = class {
|
|
136
|
+
constructor(productConfig, deviceType) {
|
|
137
|
+
this.productConfig = productConfig;
|
|
138
|
+
this.deviceType = deviceType;
|
|
142
139
|
}
|
|
143
|
-
|
|
144
|
-
this.
|
|
145
|
-
return this;
|
|
140
|
+
getProductConfig() {
|
|
141
|
+
return this.productConfig;
|
|
146
142
|
}
|
|
147
|
-
|
|
148
|
-
this.
|
|
149
|
-
|
|
143
|
+
getDeviceType() {
|
|
144
|
+
return this.deviceType;
|
|
145
|
+
}
|
|
146
|
+
toScreen() {
|
|
147
|
+
return createScreen({
|
|
148
|
+
diagonal: Number(this.productConfig.screenDiagonal),
|
|
149
|
+
density: Number(this.productConfig.screenDensity),
|
|
150
|
+
height: Number(this.productConfig.screenHeight),
|
|
151
|
+
width: Number(this.productConfig.screenWidth)
|
|
152
|
+
});
|
|
150
153
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
toJSON() {
|
|
155
|
+
return {
|
|
156
|
+
product: this.productConfig,
|
|
157
|
+
deviceType: this.deviceType
|
|
158
|
+
};
|
|
154
159
|
}
|
|
155
|
-
|
|
156
|
-
|
|
160
|
+
};
|
|
161
|
+
async function createProductPreset(productConfig, deviceType) {
|
|
162
|
+
return new ProductPresetImpl(productConfig, deviceType);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region src/devices/device.ts
|
|
167
|
+
var DeviceImpl = class {
|
|
168
|
+
uuid;
|
|
169
|
+
constructor(image, options) {
|
|
170
|
+
this.image = image;
|
|
171
|
+
this.options = options;
|
|
172
|
+
this.uuid = image.getImageManager().getOptions().crypto.randomUUID();
|
|
173
|
+
}
|
|
174
|
+
getOptions() {
|
|
175
|
+
return this.options;
|
|
176
|
+
}
|
|
177
|
+
getImage() {
|
|
178
|
+
return this.image;
|
|
179
|
+
}
|
|
180
|
+
getScreen() {
|
|
181
|
+
if (this.options.screen instanceof ProductPresetImpl) return this.options.screen.toScreen();
|
|
182
|
+
return this.options.screen;
|
|
183
|
+
}
|
|
184
|
+
setUuid(uuid) {
|
|
185
|
+
this.uuid = uuid;
|
|
157
186
|
return this;
|
|
158
187
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const productConfigItem = (await this.image.getProductConfig()).find((item) => item.name === this.config.productName);
|
|
162
|
-
if (!productConfigItem) throw new Error(`Product config item ${this.config.productName} not found`);
|
|
163
|
-
if (productConfigItem.devModel) return productConfigItem.devModel;
|
|
164
|
-
const defaultProductConfigItem = (await this.image.getProductConfig(true)).find((item) => item.name === this.config.productName);
|
|
165
|
-
if (!defaultProductConfigItem) throw new Error(`Default product config item ${this.config.productName} not found`);
|
|
166
|
-
if (defaultProductConfigItem.devModel) return defaultProductConfigItem.devModel;
|
|
188
|
+
getUuid() {
|
|
189
|
+
return this.uuid;
|
|
167
190
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
"
|
|
173
|
-
"abi": this.image.getArch(),
|
|
191
|
+
buildList() {
|
|
192
|
+
const { path, deployedPath, imageBasePath, configPath, logPath } = this.image.getImageManager().getOptions();
|
|
193
|
+
const screen = this.getScreen();
|
|
194
|
+
const list = {
|
|
195
|
+
"name": this.options.name,
|
|
174
196
|
"apiVersion": this.image.getApiVersion(),
|
|
175
|
-
"
|
|
197
|
+
"cpuNumber": this.options.cpuNumber.toFixed(),
|
|
198
|
+
"diagonalSize": screen.getDiagonal().toFixed(2),
|
|
199
|
+
"resolutionHeight": screen.getHeight().toFixed(),
|
|
200
|
+
"resolutionWidth": screen.getWidth().toFixed(),
|
|
201
|
+
"density": screen.getDensity().toFixed(),
|
|
202
|
+
"memoryRamSize": this.options.memorySize.toFixed(),
|
|
203
|
+
"dataDiskSize": this.options.diskSize.toFixed(),
|
|
204
|
+
"path": path.resolve(deployedPath, this.options.name),
|
|
205
|
+
"type": this.image.getSnakecaseDeviceType(),
|
|
206
|
+
"uuid": this.uuid,
|
|
207
|
+
"version": this.image.getVersion(),
|
|
208
|
+
"imageDir": this.image.getPath().split(",").join(path.sep) + path.sep,
|
|
176
209
|
"showVersion": `${this.image.getTargetOS()} ${this.image.getTargetVersion()}(${this.image.getApiVersion()})`,
|
|
177
|
-
"
|
|
210
|
+
"harmonyos.sdk.path": imageBasePath,
|
|
211
|
+
"harmonyos.config.path": configPath,
|
|
212
|
+
"harmonyos.log.path": logPath,
|
|
178
213
|
"hw.apiName": this.image.getTargetVersion(),
|
|
179
|
-
"
|
|
180
|
-
"
|
|
181
|
-
"
|
|
182
|
-
"type": this.image.getSnakecaseDeviceType(),
|
|
183
|
-
"devModel": await this.getDevModel()
|
|
214
|
+
"abi": this.image.getArch(),
|
|
215
|
+
"harmonyOSVersion": `${this.image.getTargetOS()}-${this.image.getTargetVersion()}`,
|
|
216
|
+
"guestVersion": `${this.image.getTargetOS()} ${this.image.getVersion()}(${this.image.getReleaseType()})`
|
|
184
217
|
};
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
return
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
"
|
|
207
|
-
"
|
|
208
|
-
"
|
|
209
|
-
"
|
|
210
|
-
"
|
|
211
|
-
"
|
|
212
|
-
"
|
|
213
|
-
"
|
|
214
|
-
"
|
|
215
|
-
"
|
|
216
|
-
"
|
|
217
|
-
"
|
|
218
|
-
"
|
|
219
|
-
"
|
|
220
|
-
"
|
|
221
|
-
"
|
|
222
|
-
"
|
|
223
|
-
"
|
|
224
|
-
"
|
|
225
|
-
"hw.
|
|
218
|
+
if (this.options.screen instanceof ProductPresetImpl) {
|
|
219
|
+
const productConfig = this.options.screen.getProductConfig();
|
|
220
|
+
if (productConfig.devModel) list.devModel = productConfig.devModel;
|
|
221
|
+
if (productConfig.name) list.model = productConfig.name;
|
|
222
|
+
}
|
|
223
|
+
return list;
|
|
224
|
+
}
|
|
225
|
+
buildIni(options = {}) {
|
|
226
|
+
const listConfig = this.buildList();
|
|
227
|
+
const screen = this.getScreen();
|
|
228
|
+
const is2in1Foldable = listConfig.type === "2in1_foldable";
|
|
229
|
+
const productPreset = this.options.screen instanceof ProductPresetImpl ? this.options.screen : null;
|
|
230
|
+
const productConfig = productPreset?.getProductConfig();
|
|
231
|
+
const useDualScreen = is2in1Foldable && productConfig?.outerScreenWidth != null && productConfig?.outerScreenHeight != null && productConfig?.outerScreenDiagonal != null;
|
|
232
|
+
const singleDiagonal = useDualScreen ? productConfig.outerScreenDiagonal : screen.getDiagonal().toString();
|
|
233
|
+
const singleHeight = useDualScreen ? productConfig.outerScreenHeight : screen.getHeight().toString();
|
|
234
|
+
const singleWidth = useDualScreen ? productConfig.outerScreenWidth : screen.getWidth().toString();
|
|
235
|
+
const doubleDiagonal = useDualScreen ? productConfig.screenDiagonal : void 0;
|
|
236
|
+
const doubleHeight = useDualScreen ? productConfig.screenHeight : void 0;
|
|
237
|
+
const doubleWidth = useDualScreen ? productConfig.screenWidth : void 0;
|
|
238
|
+
const ini = {
|
|
239
|
+
"name": listConfig.name,
|
|
240
|
+
"deviceType": listConfig.type,
|
|
241
|
+
"deviceModel": listConfig.devModel,
|
|
242
|
+
"productModel": listConfig.model,
|
|
243
|
+
"vendorCountry": options.vendorCountry ?? "CN",
|
|
244
|
+
"uuid": this.uuid,
|
|
245
|
+
"configPath": listConfig["harmonyos.config.path"],
|
|
246
|
+
"logPath": listConfig["harmonyos.log.path"],
|
|
247
|
+
"sdkPath": listConfig["harmonyos.sdk.path"],
|
|
248
|
+
"imageSubPath": listConfig.imageDir,
|
|
249
|
+
"instancePath": listConfig.path,
|
|
250
|
+
"os.osVersion": `${this.image.getTargetOS()} ${this.image.getTargetVersion()}(${this.image.getApiVersion()})`,
|
|
251
|
+
"os.apiVersion": this.image.getApiVersion(),
|
|
252
|
+
"os.softwareVersion": this.image.getVersion(),
|
|
253
|
+
"os.isPublic": options.isPublic ?? true ? "true" : "false",
|
|
254
|
+
"hw.cpu.arch": listConfig.abi,
|
|
255
|
+
"hw.cpu.ncore": listConfig.cpuNumber,
|
|
256
|
+
"hw.lcd.density": screen.getDensity().toFixed(),
|
|
257
|
+
"hw.lcd.single.diagonalSize": singleDiagonal,
|
|
258
|
+
"hw.lcd.single.height": singleHeight,
|
|
259
|
+
"hw.lcd.single.width": singleWidth,
|
|
260
|
+
"hw.lcd.number": useDualScreen ? "2" : "1",
|
|
261
|
+
"hw.ramSize": listConfig.memoryRamSize,
|
|
262
|
+
"hw.dataPartitionSize": listConfig.dataDiskSize,
|
|
263
|
+
"isCustomize": productPreset ? "false" : "true",
|
|
264
|
+
"hw.hdc.port": "notset",
|
|
265
|
+
...options.overrides
|
|
226
266
|
};
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
async writeToListWithCheck(config) {
|
|
232
|
-
const fs = this.image.getImageManager().getOptions().fs;
|
|
233
|
-
const listsPath = this.image.getImageManager().getOptions().path.resolve(this.image.getImageManager().getOptions().deployedPath, "lists.json");
|
|
234
|
-
try {
|
|
235
|
-
if (!fs.existsSync(listsPath)) fs.writeFileSync(listsPath, JSON.stringify([config], null, 2));
|
|
236
|
-
else {
|
|
237
|
-
const lists = JSON.parse(fs.readFileSync(listsPath, "utf-8")) ?? [];
|
|
238
|
-
if (!Array.isArray(lists)) return new DeployError(DeployError.Code.LIST_JSON_NOT_AN_ARRAY, "Lists is not an array");
|
|
239
|
-
if (lists.find((item) => item.name === config.name)) return;
|
|
240
|
-
lists.push(config);
|
|
241
|
-
fs.writeFileSync(listsPath, JSON.stringify(lists, null, 2));
|
|
242
|
-
}
|
|
243
|
-
} catch (err) {
|
|
244
|
-
return err instanceof Error ? new DeployError(DeployError.Code.CATCHED_ERROR, String(err)) : new DeployError(DeployError.Code.CATCHED_ERROR, String(err));
|
|
267
|
+
if (useDualScreen && doubleDiagonal != null && doubleHeight != null && doubleWidth != null) {
|
|
268
|
+
ini["hw.lcd.double.diagonalSize"] = doubleDiagonal;
|
|
269
|
+
ini["hw.lcd.double.height"] = doubleHeight;
|
|
270
|
+
ini["hw.lcd.double.width"] = doubleWidth;
|
|
245
271
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (!Array.isArray(content)) resolve(new DeployError(DeployError.Code.LIST_JSON_NOT_AN_ARRAY, "List rechecker is not an array!"));
|
|
250
|
-
else if (!content.find((item) => item.name === config.name)) resolve(new DeployError(DeployError.Code.MAYBE_OPENED_DEVICE_MANAGER_IN_DEVECO_STUDIO, `Device ${config.name} not found in lists.json! Maybe not deployed yet?`));
|
|
251
|
-
else resolve();
|
|
252
|
-
clearTimeout(timer);
|
|
253
|
-
}, 1e3);
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
async deploy(symlinkImage = true) {
|
|
257
|
-
const { fs, path, imageBasePath, sdkPath } = this.image.getImageManager().getOptions();
|
|
258
|
-
const config = await this.buildList();
|
|
259
|
-
if (fs.existsSync(config.path)) return new DeployError(DeployError.Code.DEVICE_ALREADY_DEPLOYED, `Image ${config.name} already deployed`);
|
|
260
|
-
const error = await this.writeToListWithCheck(config);
|
|
261
|
-
if (error) return error;
|
|
262
|
-
fs.mkdirSync(config.path, { recursive: true });
|
|
263
|
-
fs.writeFileSync(path.join(config.path, "config.ini"), await this.toIniString());
|
|
264
|
-
const symlinkSdkPath = path.resolve(imageBasePath, "default", "openharmony");
|
|
265
|
-
if (!fs.existsSync(path.dirname(symlinkSdkPath))) fs.mkdirSync(path.dirname(symlinkSdkPath), { recursive: true });
|
|
266
|
-
try {
|
|
267
|
-
if (fs.lstatSync(symlinkSdkPath).isSymbolicLink()) fs.unlinkSync(symlinkSdkPath);
|
|
268
|
-
else return new DeployError(DeployError.Code.SYMLINK_SDK_PATH_EXISTS, "Symlink SDK path already exists");
|
|
269
|
-
} catch {}
|
|
270
|
-
fs.symlinkSync(sdkPath, symlinkSdkPath, "dir");
|
|
271
|
-
const systemImageDir = path.join(imageBasePath, "system-image");
|
|
272
|
-
if (symlinkImage && fs.existsSync(systemImageDir)) {
|
|
273
|
-
const linkPath = path.join(config.path, "system-image");
|
|
274
|
-
try {
|
|
275
|
-
const target = path.relative(config.path, systemImageDir);
|
|
276
|
-
fs.symlinkSync(target, linkPath);
|
|
277
|
-
} catch (err) {
|
|
278
|
-
return err instanceof Error ? new DeployError(DeployError.Code.CATCHED_ERROR, String(err)) : new DeployError(DeployError.Code.CATCHED_ERROR, String(err));
|
|
279
|
-
}
|
|
272
|
+
if (productPreset && productConfig && !useDualScreen) {
|
|
273
|
+
if (productConfig.outerScreenHeight) ini["hw.phy.height"] = productConfig.outerScreenHeight;
|
|
274
|
+
if (productConfig.outerScreenWidth) ini["hw.phy.width"] = productConfig.outerScreenWidth;
|
|
280
275
|
}
|
|
276
|
+
return ini;
|
|
281
277
|
}
|
|
282
|
-
async
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
278
|
+
async toIniString() {
|
|
279
|
+
return `${Object.entries(this.buildIni()).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}=${value}`).join("\n")}\n`;
|
|
280
|
+
}
|
|
281
|
+
async deploy() {
|
|
282
|
+
const { fs, path, deployedPath } = this.image.getImageManager().getOptions();
|
|
283
|
+
if (!fs.existsSync(deployedPath)) fs.mkdirSync(deployedPath, { recursive: true });
|
|
284
|
+
const listsPath = path.join(deployedPath, "lists.json");
|
|
285
|
+
const listConfig = this.buildList();
|
|
286
|
+
if (fs.existsSync(listConfig.path)) throw new DeployError(DeployError.Code.DEVICE_ALREADY_DEPLOYED, `Image ${listConfig.name} already deployed`);
|
|
287
|
+
if (!fs.existsSync(listsPath)) return fs.writeFileSync(listsPath, JSON.stringify([listConfig], null, 2));
|
|
288
|
+
const lists = JSON.parse(fs.readFileSync(listsPath, "utf-8")) ?? [];
|
|
289
|
+
if (!Array.isArray(lists)) throw new DeployError(DeployError.Code.LIST_JSON_NOT_AN_ARRAY, "Lists is not an array");
|
|
290
|
+
if (lists.find((item) => item.name === listConfig.name)) throw new DeployError(DeployError.Code.DEVICE_ALREADY_DEPLOYED, `Image ${listConfig.name} already deployed in lists.json`);
|
|
291
|
+
lists.push(listConfig);
|
|
292
|
+
fs.writeFileSync(listsPath, JSON.stringify(lists, null, 2));
|
|
293
|
+
fs.mkdirSync(listConfig.path, { recursive: true });
|
|
294
|
+
fs.writeFileSync(path.join(listConfig.path, "config.ini"), await this.toIniString());
|
|
287
295
|
}
|
|
288
296
|
async delete() {
|
|
289
|
-
const { fs, path } = this.image.getImageManager().getOptions();
|
|
290
|
-
const listsPath = path.
|
|
291
|
-
if (!fs.existsSync(listsPath) || !fs.statSync(listsPath).isFile())
|
|
297
|
+
const { fs, path, deployedPath } = this.image.getImageManager().getOptions();
|
|
298
|
+
const listsPath = path.join(deployedPath, "lists.json");
|
|
299
|
+
if (!fs.existsSync(listsPath) || !fs.statSync(listsPath).isFile()) throw new Error("Lists file not found");
|
|
292
300
|
const lists = JSON.parse(fs.readFileSync(listsPath, "utf-8")) ?? [];
|
|
293
301
|
const index = lists.findIndex((item) => item.name === this.options.name);
|
|
294
|
-
if (index === -1)
|
|
302
|
+
if (index === -1) throw new Error(`Device ${this.options.name} not found`);
|
|
295
303
|
lists.splice(index, 1);
|
|
296
304
|
fs.writeFileSync(listsPath, JSON.stringify(lists, null, 2));
|
|
297
|
-
fs.rmSync(path.resolve(this.
|
|
305
|
+
fs.rmSync(path.resolve(this.buildList().path), { recursive: true });
|
|
306
|
+
}
|
|
307
|
+
async isDeployed() {
|
|
308
|
+
const { fs, path, deployedPath } = this.image.getImageManager().getOptions();
|
|
309
|
+
const listsPath = path.join(deployedPath, "lists.json");
|
|
310
|
+
if (!fs.existsSync(listsPath) || !fs.statSync(listsPath).isFile()) return false;
|
|
311
|
+
return (JSON.parse(fs.readFileSync(listsPath, "utf-8")) ?? []).some((item) => item.name === this.options.name && fs.existsSync(path.resolve(item.path, "config.ini")));
|
|
312
|
+
}
|
|
313
|
+
toJSON() {
|
|
314
|
+
return {
|
|
315
|
+
...this.options,
|
|
316
|
+
list: this.buildList(),
|
|
317
|
+
ini: this.buildIni()
|
|
318
|
+
};
|
|
298
319
|
}
|
|
299
320
|
};
|
|
300
|
-
function
|
|
301
|
-
return new
|
|
321
|
+
function createDevice(image, options) {
|
|
322
|
+
return new DeviceImpl(image, options);
|
|
302
323
|
}
|
|
303
324
|
|
|
304
325
|
//#endregion
|
|
@@ -465,6 +486,9 @@ var ImageBase = class {
|
|
|
465
486
|
getChecksum() {
|
|
466
487
|
return this.response?.archive?.complete?.checksum;
|
|
467
488
|
}
|
|
489
|
+
getReleaseType() {
|
|
490
|
+
return this.response?.releaseType;
|
|
491
|
+
}
|
|
468
492
|
getFsPath() {
|
|
469
493
|
return this.resolvedFsPath;
|
|
470
494
|
}
|
|
@@ -540,8 +564,25 @@ var ImageBase = class {
|
|
|
540
564
|
//#region src/images/local-image.ts
|
|
541
565
|
var LocalImageImpl = class extends ImageBase {
|
|
542
566
|
imageType = "local";
|
|
543
|
-
createDevice(
|
|
544
|
-
return
|
|
567
|
+
createDevice(options) {
|
|
568
|
+
return createDevice(this, options);
|
|
569
|
+
}
|
|
570
|
+
async getPascalCaseDeviceType() {
|
|
571
|
+
const deviceType = this.getDeviceType().toLowerCase();
|
|
572
|
+
if (!deviceType) return;
|
|
573
|
+
if (deviceType === "pc") return "2in1 Foldable";
|
|
574
|
+
const key = [
|
|
575
|
+
"phone",
|
|
576
|
+
"tablet",
|
|
577
|
+
"2in1",
|
|
578
|
+
"foldable",
|
|
579
|
+
"widefold",
|
|
580
|
+
"triplefold",
|
|
581
|
+
"2in1 foldable",
|
|
582
|
+
"tv",
|
|
583
|
+
"wearable"
|
|
584
|
+
].find((key) => key === deviceType);
|
|
585
|
+
if (key) return key;
|
|
545
586
|
}
|
|
546
587
|
async getProductConfig(usingDefaultProductConfig = false) {
|
|
547
588
|
const productConfig = usingDefaultProductConfig ? (await Promise.resolve().then(() => require("./default-product-config.cjs"))).default : await this.getImageManager().getProductConfig();
|
|
@@ -565,8 +606,8 @@ var LocalImageImpl = class extends ImageBase {
|
|
|
565
606
|
const { emulatorPath, process, path } = this.getImageManager().getOptions();
|
|
566
607
|
return process.platform === "win32" ? path.join(emulatorPath, "Emulator.exe") : path.join(emulatorPath, "Emulator");
|
|
567
608
|
}
|
|
568
|
-
async buildStartCommand(
|
|
569
|
-
const config =
|
|
609
|
+
async buildStartCommand(device) {
|
|
610
|
+
const config = device.buildList();
|
|
570
611
|
return `${this.getExecutablePath()} ${[
|
|
571
612
|
"-hvd",
|
|
572
613
|
`"${config.name.replace(/"/g, "\\\"")}"`,
|
|
@@ -580,29 +621,49 @@ var LocalImageImpl = class extends ImageBase {
|
|
|
580
621
|
const { child_process, emulatorPath } = this.getImageManager().getOptions();
|
|
581
622
|
return child_process.exec(await this.buildStartCommand(deployer), { cwd: emulatorPath });
|
|
582
623
|
}
|
|
583
|
-
async buildStopCommand(
|
|
584
|
-
const config =
|
|
624
|
+
async buildStopCommand(device) {
|
|
625
|
+
const config = device.buildList();
|
|
585
626
|
return `${this.getExecutablePath()} ${["-stop", `"${config.name.replace(/"/g, "\\\"")}"`].join(" ")}`;
|
|
586
627
|
}
|
|
587
|
-
async stop(
|
|
628
|
+
async stop(device) {
|
|
588
629
|
const { child_process, emulatorPath } = this.getImageManager().getOptions();
|
|
589
|
-
return child_process.exec(await this.buildStopCommand(
|
|
630
|
+
return child_process.exec(await this.buildStopCommand(device), { cwd: emulatorPath });
|
|
631
|
+
}
|
|
632
|
+
async createScreenLike(listsJsonItem) {
|
|
633
|
+
if (!listsJsonItem.model) return createScreen({
|
|
634
|
+
diagonal: Number(listsJsonItem.diagonalSize),
|
|
635
|
+
height: Number(listsJsonItem.resolutionHeight),
|
|
636
|
+
width: Number(listsJsonItem.resolutionWidth),
|
|
637
|
+
density: Number(listsJsonItem.density)
|
|
638
|
+
});
|
|
639
|
+
const productConfigItem = (await this.getProductConfig()).find((item) => item.name === listsJsonItem.model);
|
|
640
|
+
const pascalCaseDeviceType = await this.getPascalCaseDeviceType();
|
|
641
|
+
if (!productConfigItem || !pascalCaseDeviceType || productConfigItem.screenDiagonal !== listsJsonItem.diagonalSize || productConfigItem.screenHeight !== listsJsonItem.resolutionHeight || productConfigItem.screenWidth !== listsJsonItem.resolutionWidth || productConfigItem.screenDensity !== listsJsonItem.density) return createScreen({
|
|
642
|
+
diagonal: Number(listsJsonItem.diagonalSize),
|
|
643
|
+
height: Number(listsJsonItem.resolutionHeight),
|
|
644
|
+
width: Number(listsJsonItem.resolutionWidth),
|
|
645
|
+
density: Number(listsJsonItem.density)
|
|
646
|
+
});
|
|
647
|
+
return createProductPreset(productConfigItem, pascalCaseDeviceType);
|
|
590
648
|
}
|
|
591
|
-
typeAssert(value) {}
|
|
592
649
|
async getDevices() {
|
|
593
|
-
const { path, fs, imageBasePath } = this.getImageManager().getOptions();
|
|
594
|
-
const listsJsonPath = path.resolve(
|
|
650
|
+
const { path, fs, deployedPath, imageBasePath } = this.getImageManager().getOptions();
|
|
651
|
+
const listsJsonPath = path.resolve(deployedPath, "lists.json");
|
|
595
652
|
if (!fs.existsSync(listsJsonPath) || !fs.statSync(listsJsonPath).isFile()) return [];
|
|
596
653
|
const listsJson = JSON.parse(fs.readFileSync(listsJsonPath, "utf-8"));
|
|
597
654
|
if (!Array.isArray(listsJson) || this.imageType !== "local") return [];
|
|
598
|
-
this.typeAssert(this);
|
|
599
655
|
const devices = [];
|
|
600
656
|
for (const listsJsonItem of listsJson) {
|
|
601
|
-
if (
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
657
|
+
if (path.resolve(imageBasePath, listsJsonItem.imageDir) !== this.getFsPath()) continue;
|
|
658
|
+
const device = this.createDevice({
|
|
659
|
+
name: listsJsonItem.name,
|
|
660
|
+
cpuNumber: Number(listsJsonItem.cpuNumber),
|
|
661
|
+
diskSize: Number(listsJsonItem.dataDiskSize),
|
|
662
|
+
memorySize: Number(listsJsonItem.memoryRamSize),
|
|
663
|
+
screen: await this.createScreenLike(listsJsonItem)
|
|
664
|
+
});
|
|
665
|
+
if (!fs.existsSync(device.buildList().path) || !fs.statSync(device.buildList().path).isDirectory()) continue;
|
|
666
|
+
devices.push(device);
|
|
606
667
|
}
|
|
607
668
|
return devices;
|
|
608
669
|
}
|
|
@@ -734,23 +795,20 @@ var ImageManagerImpl = class {
|
|
|
734
795
|
if (existSkip && this.resolvedOptions.fs.existsSync(productConfigPath)) return;
|
|
735
796
|
this.resolvedOptions.fs.writeFileSync(productConfigPath, JSON.stringify((await Promise.resolve().then(() => require("./default-product-config.cjs"))).default, null, 2));
|
|
736
797
|
}
|
|
798
|
+
async isCompatible() {
|
|
799
|
+
const { fs, path, emulatorPath } = this.resolvedOptions;
|
|
800
|
+
const sdkPkgPath = path.resolve(emulatorPath, "sdk-pkg.json");
|
|
801
|
+
if (!fs.existsSync(sdkPkgPath) || !fs.statSync(sdkPkgPath).isFile()) return false;
|
|
802
|
+
const sdkPkg = JSON.parse(fs.readFileSync(sdkPkgPath, "utf-8"));
|
|
803
|
+
if (!sdkPkg?.data?.version || typeof sdkPkg.data.version !== "string") return false;
|
|
804
|
+
const [major, minor, patch] = sdkPkg.data.version.split(".").map(Number);
|
|
805
|
+
return (0, semver_functions_satisfies.default)(`${major}.${minor}.${patch}`, ">=6.0.2");
|
|
806
|
+
}
|
|
737
807
|
};
|
|
738
808
|
async function createImageManager(options = {}) {
|
|
739
809
|
return new ImageManagerImpl(await resolveImageManagerOptions(options));
|
|
740
810
|
}
|
|
741
811
|
|
|
742
|
-
//#endregion
|
|
743
|
-
//#region src/product-config.ts
|
|
744
|
-
function createDeployedImageConfig(productConfigItem) {
|
|
745
|
-
return {
|
|
746
|
-
density: productConfigItem.screenDensity,
|
|
747
|
-
resolutionHeight: productConfigItem.screenHeight,
|
|
748
|
-
resolutionWidth: productConfigItem.screenWidth,
|
|
749
|
-
diagonalSize: productConfigItem.screenDiagonal,
|
|
750
|
-
productName: productConfigItem.name
|
|
751
|
-
};
|
|
752
|
-
}
|
|
753
|
-
|
|
754
812
|
//#endregion
|
|
755
813
|
Object.defineProperty(exports, 'DeployError', {
|
|
756
814
|
enumerable: true,
|
|
@@ -760,8 +818,9 @@ Object.defineProperty(exports, 'DeployError', {
|
|
|
760
818
|
});
|
|
761
819
|
exports.DevModel = DevModel;
|
|
762
820
|
exports.RequestUrlError = RequestUrlError;
|
|
763
|
-
exports.createDeployedImageConfig = createDeployedImageConfig;
|
|
764
821
|
exports.createImageManager = createImageManager;
|
|
822
|
+
exports.createProductPreset = createProductPreset;
|
|
823
|
+
exports.createScreen = createScreen;
|
|
765
824
|
Object.defineProperty(exports, 'version', {
|
|
766
825
|
enumerable: true,
|
|
767
826
|
get: function () {
|