@arkts/image-manager 0.3.1 → 0.3.3

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/index.cjs CHANGED
@@ -30,6 +30,8 @@ let axios = require("axios");
30
30
  axios = __toESM(axios);
31
31
  let semver_functions_satisfies = require("semver/functions/satisfies");
32
32
  semver_functions_satisfies = __toESM(semver_functions_satisfies);
33
+ let ini = require("ini");
34
+ ini = __toESM(ini);
33
35
  let mitt = require("mitt");
34
36
  mitt = __toESM(mitt);
35
37
  let progress_stream = require("progress-stream");
@@ -38,7 +40,7 @@ let unzipper = require("unzipper");
38
40
  unzipper = __toESM(unzipper);
39
41
 
40
42
  //#region package.json
41
- var version = "0.3.1";
43
+ var version = "0.3.3";
42
44
 
43
45
  //#endregion
44
46
  //#region src/devices/list.ts
@@ -188,7 +190,18 @@ var DeviceImpl = class {
188
190
  getUuid() {
189
191
  return this.uuid;
190
192
  }
193
+ cachedList = null;
194
+ setCachedList(list) {
195
+ this.cachedList = list;
196
+ return this;
197
+ }
198
+ cachedIni = null;
199
+ setCachedIni(ini) {
200
+ this.cachedIni = ini;
201
+ return this;
202
+ }
191
203
  buildList() {
204
+ if (this.cachedList) return this.cachedList;
192
205
  const { path, deployedPath, imageBasePath, configPath, logPath } = this.image.getImageManager().getOptions();
193
206
  const screen = this.getScreen();
194
207
  const list = {
@@ -223,6 +236,7 @@ var DeviceImpl = class {
223
236
  return list;
224
237
  }
225
238
  buildIni(options = {}) {
239
+ if (this.cachedIni) return this.cachedIni;
226
240
  const listConfig = this.buildList();
227
241
  const screen = this.getScreen();
228
242
  const is2in1Foldable = listConfig.type === "2in1_foldable";
@@ -275,10 +289,20 @@ var DeviceImpl = class {
275
289
  }
276
290
  return ini;
277
291
  }
278
- async toIniString() {
292
+ toIniString() {
279
293
  return `${Object.entries(this.buildIni()).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}=${value}`).join("\n")}\n`;
280
294
  }
295
+ buildDeviceIni() {
296
+ return {
297
+ "hvd.ini.encoding": "UTF-8",
298
+ "path": this.buildList().path
299
+ };
300
+ }
301
+ buildDeviceIniString() {
302
+ return `${Object.entries(this.buildDeviceIni()).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}=${value}`).join("\n")}\n`;
303
+ }
281
304
  async deploy() {
305
+ if (await this.isDeployed()) return;
282
306
  const { fs, path, deployedPath } = this.image.getImageManager().getOptions();
283
307
  if (!fs.existsSync(deployedPath)) fs.mkdirSync(deployedPath, { recursive: true });
284
308
  const listsPath = path.join(deployedPath, "lists.json");
@@ -289,9 +313,10 @@ var DeviceImpl = class {
289
313
  if (!Array.isArray(lists)) throw new DeployError(DeployError.Code.LIST_JSON_NOT_AN_ARRAY, "Lists is not an array");
290
314
  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
315
  lists.push(listConfig);
292
- fs.writeFileSync(listsPath, JSON.stringify(lists, null, 2));
293
316
  fs.mkdirSync(listConfig.path, { recursive: true });
294
- fs.writeFileSync(path.join(listConfig.path, "config.ini"), await this.toIniString());
317
+ fs.writeFileSync(path.join(listConfig.path, "config.ini"), this.toIniString());
318
+ fs.writeFileSync(path.join(deployedPath, `${this.options.name}.ini`), this.buildDeviceIniString());
319
+ fs.writeFileSync(listsPath, JSON.stringify(lists, null, 2));
295
320
  }
296
321
  async delete() {
297
322
  const { fs, path, deployedPath } = this.image.getImageManager().getOptions();
@@ -303,6 +328,7 @@ var DeviceImpl = class {
303
328
  lists.splice(index, 1);
304
329
  fs.writeFileSync(listsPath, JSON.stringify(lists, null, 2));
305
330
  fs.rmSync(path.resolve(this.buildList().path), { recursive: true });
331
+ fs.rmSync(path.resolve(deployedPath, `${this.options.name}.ini`));
306
332
  }
307
333
  async isDeployed() {
308
334
  const { fs, path, deployedPath } = this.image.getImageManager().getOptions();
@@ -655,6 +681,8 @@ var LocalImageImpl = class extends ImageBase {
655
681
  const devices = [];
656
682
  for (const listsJsonItem of listsJson) {
657
683
  if (path.resolve(imageBasePath, listsJsonItem.imageDir) !== this.getFsPath()) continue;
684
+ const iniFilePath = path.resolve(listsJsonItem.path, "config.ini");
685
+ if (!fs.existsSync(iniFilePath) || !fs.statSync(iniFilePath).isFile()) continue;
658
686
  const device = this.createDevice({
659
687
  name: listsJsonItem.name,
660
688
  cpuNumber: Number(listsJsonItem.cpuNumber),
@@ -662,7 +690,8 @@ var LocalImageImpl = class extends ImageBase {
662
690
  memorySize: Number(listsJsonItem.memoryRamSize),
663
691
  screen: await this.createScreenLike(listsJsonItem)
664
692
  });
665
- if (!fs.existsSync(device.buildList().path) || !fs.statSync(device.buildList().path).isDirectory()) continue;
693
+ device.setUuid(listsJsonItem.uuid).setCachedList(listsJsonItem).setCachedIni(ini.default.parse(fs.readFileSync(iniFilePath, "utf-8")));
694
+ if (!fs.existsSync(listsJsonItem.path) || !fs.statSync(listsJsonItem.path).isDirectory()) continue;
666
695
  devices.push(device);
667
696
  }
668
697
  return devices;
package/dist/index.d.cts CHANGED
@@ -498,7 +498,7 @@ interface Device {
498
498
  getUuid(): Device.UUID;
499
499
  buildList(): FullDeployedImageOptions;
500
500
  buildIni(): Record<string, string | undefined>;
501
- toIniString(): Promise<string>;
501
+ toIniString(): string;
502
502
  deploy(): Promise<void>;
503
503
  delete(): Promise<void>;
504
504
  isDeployed(): Promise<boolean>;
package/dist/index.d.mts CHANGED
@@ -498,7 +498,7 @@ interface Device {
498
498
  getUuid(): Device.UUID;
499
499
  buildList(): FullDeployedImageOptions;
500
500
  buildIni(): Record<string, string | undefined>;
501
- toIniString(): Promise<string>;
501
+ toIniString(): string;
502
502
  deploy(): Promise<void>;
503
503
  delete(): Promise<void>;
504
504
  isDeployed(): Promise<boolean>;
package/dist/index.mjs CHANGED
@@ -1,11 +1,12 @@
1
1
  import axios, { AxiosError } from "axios";
2
2
  import satisfies from "semver/functions/satisfies";
3
+ import INI from "ini";
3
4
  import mitt from "mitt";
4
5
  import progress from "progress-stream";
5
6
  import unzipper from "unzipper";
6
7
 
7
8
  //#region package.json
8
- var version = "0.3.1";
9
+ var version = "0.3.3";
9
10
 
10
11
  //#endregion
11
12
  //#region src/devices/list.ts
@@ -155,7 +156,18 @@ var DeviceImpl = class {
155
156
  getUuid() {
156
157
  return this.uuid;
157
158
  }
159
+ cachedList = null;
160
+ setCachedList(list) {
161
+ this.cachedList = list;
162
+ return this;
163
+ }
164
+ cachedIni = null;
165
+ setCachedIni(ini) {
166
+ this.cachedIni = ini;
167
+ return this;
168
+ }
158
169
  buildList() {
170
+ if (this.cachedList) return this.cachedList;
159
171
  const { path, deployedPath, imageBasePath, configPath, logPath } = this.image.getImageManager().getOptions();
160
172
  const screen = this.getScreen();
161
173
  const list = {
@@ -190,6 +202,7 @@ var DeviceImpl = class {
190
202
  return list;
191
203
  }
192
204
  buildIni(options = {}) {
205
+ if (this.cachedIni) return this.cachedIni;
193
206
  const listConfig = this.buildList();
194
207
  const screen = this.getScreen();
195
208
  const is2in1Foldable = listConfig.type === "2in1_foldable";
@@ -242,10 +255,20 @@ var DeviceImpl = class {
242
255
  }
243
256
  return ini;
244
257
  }
245
- async toIniString() {
258
+ toIniString() {
246
259
  return `${Object.entries(this.buildIni()).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}=${value}`).join("\n")}\n`;
247
260
  }
261
+ buildDeviceIni() {
262
+ return {
263
+ "hvd.ini.encoding": "UTF-8",
264
+ "path": this.buildList().path
265
+ };
266
+ }
267
+ buildDeviceIniString() {
268
+ return `${Object.entries(this.buildDeviceIni()).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}=${value}`).join("\n")}\n`;
269
+ }
248
270
  async deploy() {
271
+ if (await this.isDeployed()) return;
249
272
  const { fs, path, deployedPath } = this.image.getImageManager().getOptions();
250
273
  if (!fs.existsSync(deployedPath)) fs.mkdirSync(deployedPath, { recursive: true });
251
274
  const listsPath = path.join(deployedPath, "lists.json");
@@ -256,9 +279,10 @@ var DeviceImpl = class {
256
279
  if (!Array.isArray(lists)) throw new DeployError(DeployError.Code.LIST_JSON_NOT_AN_ARRAY, "Lists is not an array");
257
280
  if (lists.find((item) => item.name === listConfig.name)) throw new DeployError(DeployError.Code.DEVICE_ALREADY_DEPLOYED, `Image ${listConfig.name} already deployed in lists.json`);
258
281
  lists.push(listConfig);
259
- fs.writeFileSync(listsPath, JSON.stringify(lists, null, 2));
260
282
  fs.mkdirSync(listConfig.path, { recursive: true });
261
- fs.writeFileSync(path.join(listConfig.path, "config.ini"), await this.toIniString());
283
+ fs.writeFileSync(path.join(listConfig.path, "config.ini"), this.toIniString());
284
+ fs.writeFileSync(path.join(deployedPath, `${this.options.name}.ini`), this.buildDeviceIniString());
285
+ fs.writeFileSync(listsPath, JSON.stringify(lists, null, 2));
262
286
  }
263
287
  async delete() {
264
288
  const { fs, path, deployedPath } = this.image.getImageManager().getOptions();
@@ -270,6 +294,7 @@ var DeviceImpl = class {
270
294
  lists.splice(index, 1);
271
295
  fs.writeFileSync(listsPath, JSON.stringify(lists, null, 2));
272
296
  fs.rmSync(path.resolve(this.buildList().path), { recursive: true });
297
+ fs.rmSync(path.resolve(deployedPath, `${this.options.name}.ini`));
273
298
  }
274
299
  async isDeployed() {
275
300
  const { fs, path, deployedPath } = this.image.getImageManager().getOptions();
@@ -622,6 +647,8 @@ var LocalImageImpl = class extends ImageBase {
622
647
  const devices = [];
623
648
  for (const listsJsonItem of listsJson) {
624
649
  if (path.resolve(imageBasePath, listsJsonItem.imageDir) !== this.getFsPath()) continue;
650
+ const iniFilePath = path.resolve(listsJsonItem.path, "config.ini");
651
+ if (!fs.existsSync(iniFilePath) || !fs.statSync(iniFilePath).isFile()) continue;
625
652
  const device = this.createDevice({
626
653
  name: listsJsonItem.name,
627
654
  cpuNumber: Number(listsJsonItem.cpuNumber),
@@ -629,7 +656,8 @@ var LocalImageImpl = class extends ImageBase {
629
656
  memorySize: Number(listsJsonItem.memoryRamSize),
630
657
  screen: await this.createScreenLike(listsJsonItem)
631
658
  });
632
- if (!fs.existsSync(device.buildList().path) || !fs.statSync(device.buildList().path).isDirectory()) continue;
659
+ device.setUuid(listsJsonItem.uuid).setCachedList(listsJsonItem).setCachedIni(INI.parse(fs.readFileSync(iniFilePath, "utf-8")));
660
+ if (!fs.existsSync(listsJsonItem.path) || !fs.statSync(listsJsonItem.path).isDirectory()) continue;
633
661
  devices.push(device);
634
662
  }
635
663
  return devices;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@arkts/image-manager",
3
3
  "type": "module",
4
- "version": "0.3.1",
4
+ "version": "0.3.3",
5
5
  "description": "OpenHarmony/HarmonyOS qemu image manager.",
6
6
  "author": "Naily Zero <zero@naily.cc> (https://naily.cc)",
7
7
  "license": "MIT",
@@ -43,6 +43,7 @@
43
43
  "@types/progress-stream": "^2.0.5",
44
44
  "@types/unzipper": "^0.10.11",
45
45
  "axios": "^1.13.4",
46
+ "ini": "^6.0.0",
46
47
  "mitt": "^3.0.1",
47
48
  "progress-stream": "^2.0.0",
48
49
  "semver": "^7.7.4",
@@ -51,6 +52,7 @@
51
52
  "devDependencies": {
52
53
  "@antfu/eslint-config": "^7.2.0",
53
54
  "@changesets/cli": "^2.29.8",
55
+ "@types/ini": "^4.1.1",
54
56
  "@types/node": "^25.2.0",
55
57
  "@types/semver": "^7.7.1",
56
58
  "@vitest/coverage-v8": "4.0.18",