@arkts/image-manager 0.2.3 → 0.3.0

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,4 +1,4 @@
1
- import { t as ProductConfig } from "./product-config-C-0AD84Q.cjs";
1
+ import { t as ProductConfig } from "./product-config-2xNDbvax.cjs";
2
2
 
3
3
  //#region src/default-product-config.d.ts
4
4
  declare const _default: ProductConfig;
@@ -1,4 +1,4 @@
1
- import { t as ProductConfig } from "./product-config-BwP_DEGj.mjs";
1
+ import { t as ProductConfig } from "./product-config-CDvEXtfy.mjs";
2
2
 
3
3
  //#region src/default-product-config.d.ts
4
4
  declare const _default: ProductConfig;
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.2.3";
41
+ var version = "0.3.0";
40
42
 
41
43
  //#endregion
42
- //#region src/deployer/list.ts
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/deployer/image-deployer.ts
88
- var ImageDeployerImpl = class {
89
- options = {};
90
- isDefault = true;
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
- setUuid(uuid) {
104
- this.options.uuid = uuid;
105
- return this;
97
+ getDiagonal() {
98
+ return this.options.diagonal;
106
99
  }
107
- setModel(model) {
108
- this.options.model = model;
100
+ setDiagonal(diagonal) {
101
+ this.options.diagonal = diagonal;
109
102
  return this;
110
103
  }
111
- setDevModel(devModel) {
112
- this.options.devModel = devModel;
113
- return this;
104
+ getDensity() {
105
+ return this.options.density;
114
106
  }
115
- setCpuNumber(cpuNumber) {
116
- this.options.cpuNumber = cpuNumber.toString();
107
+ setDensity(density) {
108
+ this.options.density = density;
117
109
  return this;
118
110
  }
119
- setMemoryRamSize(memoryRamSize) {
120
- this.options.memoryRamSize = memoryRamSize.toString();
121
- return this;
111
+ getHeight() {
112
+ return this.options.height;
122
113
  }
123
- setDataDiskSize(dataDiskSize) {
124
- this.options.dataDiskSize = dataDiskSize.toString();
114
+ setHeight(height) {
115
+ this.options.height = height;
125
116
  return this;
126
117
  }
127
- setCoverResolutionWidth(coverResolutionWidth) {
128
- this.options.coverResolutionWidth = coverResolutionWidth.toString();
129
- return this;
118
+ getWidth() {
119
+ return this.options.width;
130
120
  }
131
- setCoverResolutionHeight(coverResolutionHeight) {
132
- this.options.coverResolutionHeight = coverResolutionHeight.toString();
121
+ setWidth(width) {
122
+ this.options.width = width;
133
123
  return this;
134
124
  }
135
- setCoverDiagonalSize(coverDiagonalSize) {
136
- this.options.coverDiagonalSize = coverDiagonalSize.toString();
137
- return this;
125
+ toJSON() {
126
+ return this.options;
138
127
  }
139
- setIsDefault(isDefault) {
140
- this.isDefault = isDefault;
141
- return this;
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
- setIsCustomize(isCustomize) {
144
- this.isCustomize = isCustomize;
145
- return this;
140
+ getProductConfig() {
141
+ return this.productConfig;
146
142
  }
147
- setIsPublic(isPublic) {
148
- this.isPublic = isPublic;
149
- return this;
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
- setHwHdcPort(hwHdcPort) {
152
- this.hwHdcPort = hwHdcPort.toString();
153
- return this;
154
+ toJSON() {
155
+ return {
156
+ product: this.productConfig,
157
+ deviceType: this.deviceType
158
+ };
154
159
  }
155
- setVendorCountry(vendorCountry) {
156
- this.vendorCountry = vendorCountry;
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
- async getDevModel() {
160
- if (this.options.devModel) return this.options.devModel;
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
- async buildList() {
169
- return {
170
- ...this.options,
171
- "imageDir": this.image.getPath().split(",").join(this.image.getImageManager().getOptions().path.sep) + this.image.getImageManager().getOptions().path.sep,
172
- "version": this.image.getVersion(),
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
- "path": this.image.getImageManager().getOptions().path.resolve(this.image.getImageManager().getOptions().deployedPath, this.options.name ?? ""),
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
- "harmonyOSVersion": `${this.image.getTargetOS()}-${this.image.getTargetVersion()}`,
210
+ "harmonyos.sdk.path": imageBasePath,
211
+ "harmonyos.config.path": configPath,
212
+ "harmonyos.log.path": logPath,
178
213
  "hw.apiName": this.image.getTargetVersion(),
179
- "harmonyos.sdk.path": this.image.getImageManager().getOptions().imageBasePath,
180
- "harmonyos.config.path": this.image.getImageManager().getOptions().configPath,
181
- "harmonyos.log.path": this.image.getImageManager().getOptions().logPath,
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
- async buildIni() {
187
- const config = await this.buildList();
188
- const productConfigItem = (await this.image.getProductConfig()).find((item) => item.name === this.config.productName);
189
- if (!productConfigItem) throw new Error(`Product config item ${this.config.productName} not found`);
190
- return {
191
- "name": config.name,
192
- "hw.lcd.density": config.density,
193
- "hw.lcd.height": productConfigItem.screenHeight,
194
- "hw.lcd.width": productConfigItem.screenWidth,
195
- "hw.cpu.ncore": config.cpuNumber,
196
- "hw.phy.height": productConfigItem.outerScreenHeight,
197
- "hw.phy.width": productConfigItem.outerScreenWidth,
198
- "hw.cover.height": productConfigItem.outerScreenHeight,
199
- "hw.cover.width": productConfigItem.outerScreenWidth,
200
- "coverDiagonalSize": config.coverDiagonalSize ?? productConfigItem.outerScreenDiagonal,
201
- "diagonalSize": config.diagonalSize,
202
- "hw.ramSize": config.memoryRamSize,
203
- "deviceType": config.type,
204
- "uuid": config.uuid,
205
- "hmApiVersion": config.apiVersion,
206
- "hmAbi": config.abi,
207
- "hmVersion": config.version,
208
- "hw.cpu.arch": config.abi,
209
- "hw.apiName": config["hw.apiName"],
210
- "image.sysdir.1": config.imageDir,
211
- "hvd.path": config.path,
212
- "disk.dataPartition.size": `${config.dataDiskSize}M`,
213
- "hmShowVersion": config.showVersion,
214
- "harmonyOSVersion": config.harmonyOSVersion,
215
- "harmonyos.sdk.path": config["harmonyos.sdk.path"],
216
- "harmonyos.config.path": config["harmonyos.config.path"],
217
- "harmonyos.log.path": config["harmonyos.log.path"],
218
- "guest.version": config.version,
219
- "devModel": config.devModel,
220
- "model": config.model,
221
- "isDefault": this.isDefault ? "true" : "false",
222
- "isCustomize": this.isCustomize ? "true" : "false",
223
- "isPublic": this.isPublic ? "true" : "false",
224
- "vendorCountry": this.vendorCountry,
225
- "hw.hdc.port": this.hwHdcPort.toString()
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
- async toIniString() {
229
- return `${Object.entries(await this.buildIni()).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}=${value}`).join("\n")}\n`;
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
- return new Promise((resolve) => {
247
- const timer = setTimeout(() => {
248
- const content = JSON.parse(fs.readFileSync(listsPath, "utf-8")) ?? [];
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 isDeployed() {
283
- const { fs, path } = this.image.getImageManager().getOptions();
284
- const listsPath = path.resolve(this.image.getImageManager().getOptions().deployedPath, "lists.json");
285
- if (!fs.existsSync(listsPath) || !fs.statSync(listsPath).isFile()) return false;
286
- return (JSON.parse(fs.readFileSync(listsPath, "utf-8")) ?? []).find((item) => item.name === this.options.name) !== void 0;
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.resolve(this.image.getImageManager().getOptions().deployedPath, "lists.json");
291
- if (!fs.existsSync(listsPath) || !fs.statSync(listsPath).isFile()) return /* @__PURE__ */ new Error("Lists file not found");
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) return /* @__PURE__ */ new Error(`Device ${this.options.name} not found`);
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.options.path ?? ""), { recursive: true });
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 createImageDeployer(image, uuid, name, config) {
301
- return new ImageDeployerImpl(image, uuid, name, config);
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(name, config) {
544
- return createImageDeployer(this, this.getImageManager().getOptions().crypto.randomUUID(), name, config);
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(deployer) {
569
- const config = await deployer.buildList();
609
+ async buildStartCommand(device) {
610
+ const config = device.buildList();
570
611
  return `${this.getExecutablePath()} ${[
571
612
  "-hvd",
572
613
  `"${config.name.replace(/"/g, "\\\"")}"`,
@@ -580,30 +621,45 @@ 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(deployer) {
584
- const config = await deployer.buildList();
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(deployer) {
628
+ async stop(device) {
588
629
  const { child_process, emulatorPath } = this.getImageManager().getOptions();
589
- return child_process.exec(await this.buildStopCommand(deployer), { cwd: emulatorPath });
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(this.getImageManager().getOptions().deployedPath, "lists.json");
650
+ const { path, fs, deployedPath } = 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
- for (const listsJsonItem of listsJson) {
601
- if (typeof listsJsonItem !== "object" || listsJsonItem === null) continue;
602
- if (!("imageDir" in listsJsonItem) || typeof listsJsonItem.imageDir !== "string") continue;
603
- if (!("name" in listsJsonItem) || typeof listsJsonItem.name !== "string") continue;
604
- if (path.resolve(this.getFsPath()) !== path.resolve(imageBasePath, listsJsonItem.imageDir)) continue;
605
- devices.push(this.createDevice(listsJsonItem.name, listsJsonItem));
606
- }
656
+ for (const listsJsonItem of listsJson) devices.push(this.createDevice({
657
+ name: listsJsonItem.name,
658
+ cpuNumber: Number(listsJsonItem.cpuNumber),
659
+ diskSize: Number(listsJsonItem.dataDiskSize),
660
+ memorySize: Number(listsJsonItem.memoryRamSize),
661
+ screen: await this.createScreenLike(listsJsonItem)
662
+ }));
607
663
  return devices;
608
664
  }
609
665
  toJSON() {
@@ -734,23 +790,20 @@ var ImageManagerImpl = class {
734
790
  if (existSkip && this.resolvedOptions.fs.existsSync(productConfigPath)) return;
735
791
  this.resolvedOptions.fs.writeFileSync(productConfigPath, JSON.stringify((await Promise.resolve().then(() => require("./default-product-config.cjs"))).default, null, 2));
736
792
  }
793
+ async isCompatible() {
794
+ const { fs, path, emulatorPath } = this.resolvedOptions;
795
+ const sdkPkgPath = path.resolve(emulatorPath, "sdk-pkg.json");
796
+ if (!fs.existsSync(sdkPkgPath) || !fs.statSync(sdkPkgPath).isFile()) return false;
797
+ const sdkPkg = JSON.parse(fs.readFileSync(sdkPkgPath, "utf-8"));
798
+ if (!sdkPkg?.data?.version || typeof sdkPkg.data.version !== "string") return false;
799
+ const [major, minor, patch] = sdkPkg.data.version.split(".").map(Number);
800
+ return (0, semver_functions_satisfies.default)(`${major}.${minor}.${patch}`, ">=6.0.2");
801
+ }
737
802
  };
738
803
  async function createImageManager(options = {}) {
739
804
  return new ImageManagerImpl(await resolveImageManagerOptions(options));
740
805
  }
741
806
 
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
807
  //#endregion
755
808
  Object.defineProperty(exports, 'DeployError', {
756
809
  enumerable: true,
@@ -760,8 +813,9 @@ Object.defineProperty(exports, 'DeployError', {
760
813
  });
761
814
  exports.DevModel = DevModel;
762
815
  exports.RequestUrlError = RequestUrlError;
763
- exports.createDeployedImageConfig = createDeployedImageConfig;
764
816
  exports.createImageManager = createImageManager;
817
+ exports.createProductPreset = createProductPreset;
818
+ exports.createScreen = createScreen;
765
819
  Object.defineProperty(exports, 'version', {
766
820
  enumerable: true,
767
821
  get: function () {