hot-updater 0.20.0 → 0.20.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/config.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  require('./picocolors-y8lGs7d-.cjs');
2
- const require_fingerprint = require('./fingerprint-3QU5apyj.cjs');
2
+ const require_fingerprint = require('./fingerprint-CNuaoV3R.cjs');
3
3
 
4
4
  //#region src/config.ts
5
5
  const defineConfig = (config) => {
package/dist/config.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "./picocolors-BnzanxXs.js";
2
- import { createAndInjectFingerprintFiles, generateFingerprint, generateFingerprints, readLocalFingerprint } from "./fingerprint-DLeoZ3u_.js";
2
+ import { createAndInjectFingerprintFiles, generateFingerprint, generateFingerprints, readLocalFingerprint } from "./fingerprint-CyVxz4OY.js";
3
3
 
4
4
  //#region src/config.ts
5
5
  const defineConfig = (config) => {
@@ -1464,11 +1464,11 @@ function isAttribute(name) {
1464
1464
  //#endregion
1465
1465
  //#region src/utils/configParser/androidParser.ts
1466
1466
  var AndroidConfigParser = class {
1467
- stringsXmlPath;
1467
+ stringsXmlPaths;
1468
1468
  parser;
1469
1469
  builder;
1470
- constructor() {
1471
- this.stringsXmlPath = path.default.join((0, __hot_updater_plugin_core.getCwd)(), "android", "app", "src", "main", "res", "values", "strings.xml");
1470
+ constructor(customPaths) {
1471
+ this.stringsXmlPaths = customPaths || [path.default.join((0, __hot_updater_plugin_core.getCwd)(), "android", "app", "src", "main", "res", "values", "strings.xml")];
1472
1472
  const options = {
1473
1473
  ignoreAttributes: false,
1474
1474
  attributeNamePrefix: "@_",
@@ -1487,40 +1487,44 @@ var AndroidConfigParser = class {
1487
1487
  });
1488
1488
  }
1489
1489
  async exists() {
1490
- return fs.default.existsSync(this.stringsXmlPath);
1490
+ return this.stringsXmlPaths.some((path$14) => fs.default.existsSync(path$14));
1491
+ }
1492
+ getExistingPaths() {
1493
+ return this.stringsXmlPaths.filter((path$14) => fs.default.existsSync(path$14));
1491
1494
  }
1492
1495
  async get(key) {
1493
- if (!await this.exists()) return {
1496
+ const existingPaths = this.getExistingPaths();
1497
+ if (existingPaths.length === 0) return {
1494
1498
  value: null,
1495
- path: path.default.relative((0, __hot_updater_plugin_core.getCwd)(), this.stringsXmlPath)
1499
+ path: path.default.relative((0, __hot_updater_plugin_core.getCwd)(), this.stringsXmlPaths[0] || "")
1496
1500
  };
1497
- try {
1498
- const content = await fs.default.promises.readFile(this.stringsXmlPath, "utf-8");
1501
+ for (const stringsXmlPath of existingPaths) try {
1502
+ const content = await fs.default.promises.readFile(stringsXmlPath, "utf-8");
1499
1503
  const result = this.parser.parse(content);
1500
- if (!result.resources.string) return {
1501
- value: null,
1502
- path: path.default.relative((0, __hot_updater_plugin_core.getCwd)(), this.stringsXmlPath)
1503
- };
1504
+ if (!result.resources.string) continue;
1504
1505
  const strings = Array.isArray(result.resources.string) ? result.resources.string : [result.resources.string];
1505
1506
  const stringElement = strings.find((str) => str["@_name"] === key && str["@_moduleConfig"] === "true");
1506
- return {
1507
- value: stringElement?.["#text"]?.trim() ?? null,
1508
- path: path.default.relative((0, __hot_updater_plugin_core.getCwd)(), this.stringsXmlPath)
1507
+ if (stringElement?.["#text"]) return {
1508
+ value: stringElement["#text"].trim(),
1509
+ path: path.default.relative((0, __hot_updater_plugin_core.getCwd)(), stringsXmlPath)
1509
1510
  };
1510
1511
  } catch (error) {
1511
- return {
1512
- value: null,
1513
- path: path.default.relative((0, __hot_updater_plugin_core.getCwd)(), this.stringsXmlPath)
1514
- };
1512
+ throw new Error(`Failed to get ${stringsXmlPath}: ${error}`);
1515
1513
  }
1514
+ return {
1515
+ value: null,
1516
+ path: path.default.relative((0, __hot_updater_plugin_core.getCwd)(), existingPaths[0] || "")
1517
+ };
1516
1518
  }
1517
1519
  async set(key, value) {
1518
- if (!await this.exists()) {
1519
- console.warn("hot-updater: strings.xml not found. Skipping Android-specific config modifications.");
1520
+ const existingPaths = this.getExistingPaths();
1521
+ if (existingPaths.length === 0) {
1522
+ console.warn("hot-updater: No strings.xml files found. Skipping Android-specific config modifications.");
1520
1523
  return { path: null };
1521
1524
  }
1522
- const content = await fs.default.promises.readFile(this.stringsXmlPath, "utf-8");
1523
- try {
1525
+ const updatedPaths = [];
1526
+ for (const stringsXmlPath of existingPaths) try {
1527
+ const content = await fs.default.promises.readFile(stringsXmlPath, "utf-8");
1524
1528
  const result = this.parser.parse(content);
1525
1529
  if (!result.resources.string) result.resources.string = [];
1526
1530
  const strings = Array.isArray(result.resources.string) ? result.resources.string : [result.resources.string];
@@ -1534,11 +1538,12 @@ var AndroidConfigParser = class {
1534
1538
  else strings.push(stringElement);
1535
1539
  result.resources.string = strings.length === 1 ? strings[0] : strings;
1536
1540
  const newContent = this.builder.build(result);
1537
- await fs.default.promises.writeFile(this.stringsXmlPath, newContent, "utf-8");
1538
- return { path: path.default.relative((0, __hot_updater_plugin_core.getCwd)(), this.stringsXmlPath) };
1541
+ await fs.default.promises.writeFile(stringsXmlPath, newContent, "utf-8");
1542
+ updatedPaths.push(path.default.relative((0, __hot_updater_plugin_core.getCwd)(), stringsXmlPath));
1539
1543
  } catch (error) {
1540
1544
  throw new Error(`Failed to parse or update strings.xml: ${error}`);
1541
1545
  }
1546
+ return { path: updatedPaths.length > 0 ? updatedPaths.join(", ") : null };
1542
1547
  }
1543
1548
  };
1544
1549
 
@@ -14757,84 +14762,83 @@ var require_plist = /* @__PURE__ */ require_picocolors$1.__commonJS({ "../../nod
14757
14762
  var import_out$1 = /* @__PURE__ */ require_picocolors$1.__toESM(require_out(), 1);
14758
14763
  var import_plist = /* @__PURE__ */ require_picocolors$1.__toESM(require_plist(), 1);
14759
14764
  var IosConfigParser = class {
14760
- async getPlistPath() {
14761
- const [plistFile] = await import_out$1.default.glob("*/Info.plist", {
14765
+ customPaths;
14766
+ constructor(customPaths) {
14767
+ this.customPaths = customPaths;
14768
+ }
14769
+ async getPlistPaths() {
14770
+ if (this.customPaths) return this.customPaths.map((p) => path.default.isAbsolute(p) ? p : path.default.join((0, __hot_updater_plugin_core.getCwd)(), p)).filter((p) => fs.default.existsSync(p));
14771
+ const plistFiles = await import_out$1.default.glob("*/Info.plist", {
14762
14772
  cwd: path.default.join((0, __hot_updater_plugin_core.getCwd)(), "ios"),
14763
14773
  absolute: true,
14764
14774
  onlyFiles: true
14765
14775
  });
14766
- if (!plistFile) return null;
14767
- return plistFile;
14776
+ return plistFiles;
14768
14777
  }
14769
14778
  async exists() {
14770
- try {
14771
- await this.getPlistPath();
14772
- return true;
14773
- } catch {
14774
- return false;
14775
- }
14779
+ const paths = await this.getPlistPaths();
14780
+ return paths.length > 0;
14776
14781
  }
14777
14782
  async get(key) {
14778
- try {
14779
- const plistFile = await this.getPlistPath();
14780
- if (!plistFile) return {
14781
- value: null,
14782
- path: null
14783
- };
14783
+ const plistPaths = await this.getPlistPaths();
14784
+ if (plistPaths.length === 0) return {
14785
+ value: null,
14786
+ path: null
14787
+ };
14788
+ for (const plistFile of plistPaths) {
14784
14789
  const plistXml = await fs.default.promises.readFile(plistFile, "utf-8");
14785
14790
  const plistObject = import_plist.default.parse(plistXml);
14786
14791
  if (key in plistObject) {
14787
14792
  const value = plistObject[key];
14788
- if (value === null || value === void 0) return {
14789
- value: null,
14790
- path: path.default.relative((0, __hot_updater_plugin_core.getCwd)(), plistFile)
14791
- };
14792
- if (typeof value === "string") return {
14793
- value,
14794
- path: path.default.relative((0, __hot_updater_plugin_core.getCwd)(), plistFile)
14795
- };
14793
+ if (value === null || value === void 0) continue;
14794
+ const stringValue = typeof value === "string" ? value : String(value);
14796
14795
  return {
14797
- value: String(value),
14796
+ value: stringValue,
14798
14797
  path: path.default.relative((0, __hot_updater_plugin_core.getCwd)(), plistFile)
14799
14798
  };
14800
14799
  }
14801
- return {
14802
- value: null,
14803
- path: path.default.relative((0, __hot_updater_plugin_core.getCwd)(), plistFile)
14804
- };
14805
- } catch (error) {
14806
- return {
14807
- value: null,
14808
- path: ""
14809
- };
14810
14800
  }
14801
+ return {
14802
+ value: null,
14803
+ path: path.default.relative((0, __hot_updater_plugin_core.getCwd)(), plistPaths[0] || "")
14804
+ };
14811
14805
  }
14812
14806
  async set(key, value) {
14813
- const plistFile = await this.getPlistPath();
14814
- if (!plistFile) {
14815
- console.warn("hot-updater: Info.plist not found. Skipping iOS-specific config modifications.");
14807
+ const plistPaths = await this.getPlistPaths();
14808
+ if (plistPaths.length === 0) {
14809
+ console.warn("hot-updater: No Info.plist files found. Skipping iOS-specific config modifications.");
14816
14810
  return { path: null };
14817
14811
  }
14818
- const plistXml = await fs.default.promises.readFile(plistFile, "utf-8");
14819
- const plistObject = import_plist.default.parse(plistXml);
14820
- plistObject[key] = value;
14821
- const newPlistXml = import_plist.default.build(plistObject, {
14822
- indent: " ",
14823
- pretty: true
14824
- });
14825
- await fs.default.promises.writeFile(plistFile, newPlistXml);
14826
- return { path: path.default.relative((0, __hot_updater_plugin_core.getCwd)(), plistFile) };
14812
+ const updatedPaths = [];
14813
+ for (const plistFile of plistPaths) try {
14814
+ const plistXml = await fs.default.promises.readFile(plistFile, "utf-8");
14815
+ const plistObject = import_plist.default.parse(plistXml);
14816
+ plistObject[key] = value;
14817
+ const newPlistXml = import_plist.default.build(plistObject, {
14818
+ indent: " ",
14819
+ pretty: true
14820
+ });
14821
+ await fs.default.promises.writeFile(plistFile, newPlistXml);
14822
+ updatedPaths.push(path.default.relative((0, __hot_updater_plugin_core.getCwd)(), plistFile));
14823
+ } catch (error) {
14824
+ throw new Error(`Failed to parse or update Info.plist: ${error}`);
14825
+ }
14826
+ return { path: updatedPaths.length > 0 ? updatedPaths.join(", ") : null };
14827
14827
  }
14828
14828
  };
14829
14829
 
14830
14830
  //#endregion
14831
14831
  //#region src/utils/setFingerprintHash.ts
14832
14832
  const setAndroidFingerprintHash = async (hash) => {
14833
- const androidParser = new AndroidConfigParser();
14833
+ const config = await (0, __hot_updater_plugin_core.loadConfig)(null);
14834
+ const customPaths = config.platform?.android?.stringResourcePaths;
14835
+ const androidParser = new AndroidConfigParser(customPaths);
14834
14836
  return await androidParser.set("hot_updater_fingerprint_hash", hash);
14835
14837
  };
14836
14838
  const setIosFingerprintHash = async (hash) => {
14837
- const iosParser = new IosConfigParser();
14839
+ const config = await (0, __hot_updater_plugin_core.loadConfig)(null);
14840
+ const customPaths = config.platform?.ios?.infoPlistPaths;
14841
+ const iosParser = new IosConfigParser(customPaths);
14838
14842
  return await iosParser.set("HOT_UPDATER_FINGERPRINT_HASH", hash);
14839
14843
  };
14840
14844
  const setFingerprintHash = async (platform, hash) => {
@@ -1464,11 +1464,11 @@ function isAttribute(name) {
1464
1464
  //#endregion
1465
1465
  //#region src/utils/configParser/androidParser.ts
1466
1466
  var AndroidConfigParser = class {
1467
- stringsXmlPath;
1467
+ stringsXmlPaths;
1468
1468
  parser;
1469
1469
  builder;
1470
- constructor() {
1471
- this.stringsXmlPath = path.join(getCwd(), "android", "app", "src", "main", "res", "values", "strings.xml");
1470
+ constructor(customPaths) {
1471
+ this.stringsXmlPaths = customPaths || [path.join(getCwd(), "android", "app", "src", "main", "res", "values", "strings.xml")];
1472
1472
  const options = {
1473
1473
  ignoreAttributes: false,
1474
1474
  attributeNamePrefix: "@_",
@@ -1487,40 +1487,44 @@ var AndroidConfigParser = class {
1487
1487
  });
1488
1488
  }
1489
1489
  async exists() {
1490
- return fs$1.existsSync(this.stringsXmlPath);
1490
+ return this.stringsXmlPaths.some((path$11) => fs$1.existsSync(path$11));
1491
+ }
1492
+ getExistingPaths() {
1493
+ return this.stringsXmlPaths.filter((path$11) => fs$1.existsSync(path$11));
1491
1494
  }
1492
1495
  async get(key) {
1493
- if (!await this.exists()) return {
1496
+ const existingPaths = this.getExistingPaths();
1497
+ if (existingPaths.length === 0) return {
1494
1498
  value: null,
1495
- path: path.relative(getCwd(), this.stringsXmlPath)
1499
+ path: path.relative(getCwd(), this.stringsXmlPaths[0] || "")
1496
1500
  };
1497
- try {
1498
- const content = await fs$1.promises.readFile(this.stringsXmlPath, "utf-8");
1501
+ for (const stringsXmlPath of existingPaths) try {
1502
+ const content = await fs$1.promises.readFile(stringsXmlPath, "utf-8");
1499
1503
  const result = this.parser.parse(content);
1500
- if (!result.resources.string) return {
1501
- value: null,
1502
- path: path.relative(getCwd(), this.stringsXmlPath)
1503
- };
1504
+ if (!result.resources.string) continue;
1504
1505
  const strings = Array.isArray(result.resources.string) ? result.resources.string : [result.resources.string];
1505
1506
  const stringElement = strings.find((str) => str["@_name"] === key && str["@_moduleConfig"] === "true");
1506
- return {
1507
- value: stringElement?.["#text"]?.trim() ?? null,
1508
- path: path.relative(getCwd(), this.stringsXmlPath)
1507
+ if (stringElement?.["#text"]) return {
1508
+ value: stringElement["#text"].trim(),
1509
+ path: path.relative(getCwd(), stringsXmlPath)
1509
1510
  };
1510
1511
  } catch (error) {
1511
- return {
1512
- value: null,
1513
- path: path.relative(getCwd(), this.stringsXmlPath)
1514
- };
1512
+ throw new Error(`Failed to get ${stringsXmlPath}: ${error}`);
1515
1513
  }
1514
+ return {
1515
+ value: null,
1516
+ path: path.relative(getCwd(), existingPaths[0] || "")
1517
+ };
1516
1518
  }
1517
1519
  async set(key, value) {
1518
- if (!await this.exists()) {
1519
- console.warn("hot-updater: strings.xml not found. Skipping Android-specific config modifications.");
1520
+ const existingPaths = this.getExistingPaths();
1521
+ if (existingPaths.length === 0) {
1522
+ console.warn("hot-updater: No strings.xml files found. Skipping Android-specific config modifications.");
1520
1523
  return { path: null };
1521
1524
  }
1522
- const content = await fs$1.promises.readFile(this.stringsXmlPath, "utf-8");
1523
- try {
1525
+ const updatedPaths = [];
1526
+ for (const stringsXmlPath of existingPaths) try {
1527
+ const content = await fs$1.promises.readFile(stringsXmlPath, "utf-8");
1524
1528
  const result = this.parser.parse(content);
1525
1529
  if (!result.resources.string) result.resources.string = [];
1526
1530
  const strings = Array.isArray(result.resources.string) ? result.resources.string : [result.resources.string];
@@ -1534,11 +1538,12 @@ var AndroidConfigParser = class {
1534
1538
  else strings.push(stringElement);
1535
1539
  result.resources.string = strings.length === 1 ? strings[0] : strings;
1536
1540
  const newContent = this.builder.build(result);
1537
- await fs$1.promises.writeFile(this.stringsXmlPath, newContent, "utf-8");
1538
- return { path: path.relative(getCwd(), this.stringsXmlPath) };
1541
+ await fs$1.promises.writeFile(stringsXmlPath, newContent, "utf-8");
1542
+ updatedPaths.push(path.relative(getCwd(), stringsXmlPath));
1539
1543
  } catch (error) {
1540
1544
  throw new Error(`Failed to parse or update strings.xml: ${error}`);
1541
1545
  }
1546
+ return { path: updatedPaths.length > 0 ? updatedPaths.join(", ") : null };
1542
1547
  }
1543
1548
  };
1544
1549
 
@@ -14757,84 +14762,83 @@ var require_plist = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/plist
14757
14762
  var import_out$1 = /* @__PURE__ */ __toESM(require_out(), 1);
14758
14763
  var import_plist = /* @__PURE__ */ __toESM(require_plist(), 1);
14759
14764
  var IosConfigParser = class {
14760
- async getPlistPath() {
14761
- const [plistFile] = await import_out$1.default.glob("*/Info.plist", {
14765
+ customPaths;
14766
+ constructor(customPaths) {
14767
+ this.customPaths = customPaths;
14768
+ }
14769
+ async getPlistPaths() {
14770
+ if (this.customPaths) return this.customPaths.map((p$1) => path.isAbsolute(p$1) ? p$1 : path.join(getCwd(), p$1)).filter((p$1) => fs$1.existsSync(p$1));
14771
+ const plistFiles = await import_out$1.default.glob("*/Info.plist", {
14762
14772
  cwd: path.join(getCwd(), "ios"),
14763
14773
  absolute: true,
14764
14774
  onlyFiles: true
14765
14775
  });
14766
- if (!plistFile) return null;
14767
- return plistFile;
14776
+ return plistFiles;
14768
14777
  }
14769
14778
  async exists() {
14770
- try {
14771
- await this.getPlistPath();
14772
- return true;
14773
- } catch {
14774
- return false;
14775
- }
14779
+ const paths = await this.getPlistPaths();
14780
+ return paths.length > 0;
14776
14781
  }
14777
14782
  async get(key) {
14778
- try {
14779
- const plistFile = await this.getPlistPath();
14780
- if (!plistFile) return {
14781
- value: null,
14782
- path: null
14783
- };
14783
+ const plistPaths = await this.getPlistPaths();
14784
+ if (plistPaths.length === 0) return {
14785
+ value: null,
14786
+ path: null
14787
+ };
14788
+ for (const plistFile of plistPaths) {
14784
14789
  const plistXml = await fs$1.promises.readFile(plistFile, "utf-8");
14785
14790
  const plistObject = import_plist.default.parse(plistXml);
14786
14791
  if (key in plistObject) {
14787
14792
  const value = plistObject[key];
14788
- if (value === null || value === void 0) return {
14789
- value: null,
14790
- path: path.relative(getCwd(), plistFile)
14791
- };
14792
- if (typeof value === "string") return {
14793
- value,
14794
- path: path.relative(getCwd(), plistFile)
14795
- };
14793
+ if (value === null || value === void 0) continue;
14794
+ const stringValue = typeof value === "string" ? value : String(value);
14796
14795
  return {
14797
- value: String(value),
14796
+ value: stringValue,
14798
14797
  path: path.relative(getCwd(), plistFile)
14799
14798
  };
14800
14799
  }
14801
- return {
14802
- value: null,
14803
- path: path.relative(getCwd(), plistFile)
14804
- };
14805
- } catch (error) {
14806
- return {
14807
- value: null,
14808
- path: ""
14809
- };
14810
14800
  }
14801
+ return {
14802
+ value: null,
14803
+ path: path.relative(getCwd(), plistPaths[0] || "")
14804
+ };
14811
14805
  }
14812
14806
  async set(key, value) {
14813
- const plistFile = await this.getPlistPath();
14814
- if (!plistFile) {
14815
- console.warn("hot-updater: Info.plist not found. Skipping iOS-specific config modifications.");
14807
+ const plistPaths = await this.getPlistPaths();
14808
+ if (plistPaths.length === 0) {
14809
+ console.warn("hot-updater: No Info.plist files found. Skipping iOS-specific config modifications.");
14816
14810
  return { path: null };
14817
14811
  }
14818
- const plistXml = await fs$1.promises.readFile(plistFile, "utf-8");
14819
- const plistObject = import_plist.default.parse(plistXml);
14820
- plistObject[key] = value;
14821
- const newPlistXml = import_plist.default.build(plistObject, {
14822
- indent: " ",
14823
- pretty: true
14824
- });
14825
- await fs$1.promises.writeFile(plistFile, newPlistXml);
14826
- return { path: path.relative(getCwd(), plistFile) };
14812
+ const updatedPaths = [];
14813
+ for (const plistFile of plistPaths) try {
14814
+ const plistXml = await fs$1.promises.readFile(plistFile, "utf-8");
14815
+ const plistObject = import_plist.default.parse(plistXml);
14816
+ plistObject[key] = value;
14817
+ const newPlistXml = import_plist.default.build(plistObject, {
14818
+ indent: " ",
14819
+ pretty: true
14820
+ });
14821
+ await fs$1.promises.writeFile(plistFile, newPlistXml);
14822
+ updatedPaths.push(path.relative(getCwd(), plistFile));
14823
+ } catch (error) {
14824
+ throw new Error(`Failed to parse or update Info.plist: ${error}`);
14825
+ }
14826
+ return { path: updatedPaths.length > 0 ? updatedPaths.join(", ") : null };
14827
14827
  }
14828
14828
  };
14829
14829
 
14830
14830
  //#endregion
14831
14831
  //#region src/utils/setFingerprintHash.ts
14832
14832
  const setAndroidFingerprintHash = async (hash) => {
14833
- const androidParser = new AndroidConfigParser();
14833
+ const config = await loadConfig(null);
14834
+ const customPaths = config.platform?.android?.stringResourcePaths;
14835
+ const androidParser = new AndroidConfigParser(customPaths);
14834
14836
  return await androidParser.set("hot_updater_fingerprint_hash", hash);
14835
14837
  };
14836
14838
  const setIosFingerprintHash = async (hash) => {
14837
- const iosParser = new IosConfigParser();
14839
+ const config = await loadConfig(null);
14840
+ const customPaths = config.platform?.ios?.infoPlistPaths;
14841
+ const iosParser = new IosConfigParser(customPaths);
14838
14842
  return await iosParser.set("HOT_UPDATER_FINGERPRINT_HASH", hash);
14839
14843
  };
14840
14844
  const setFingerprintHash = async (platform, hash) => {
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  const require_picocolors$1 = require('./picocolors-y8lGs7d-.cjs');
3
- const require_fingerprint = require('./fingerprint-3QU5apyj.cjs');
3
+ const require_fingerprint = require('./fingerprint-CNuaoV3R.cjs');
4
4
  const node_events = require_picocolors$1.__toESM(require("node:events"));
5
5
  const node_child_process = require_picocolors$1.__toESM(require("node:child_process"));
6
6
  const node_path = require_picocolors$1.__toESM(require("node:path"));
@@ -34968,8 +34968,10 @@ const appendToProjectRootGitignore = ({ cwd, globLines }) => {
34968
34968
  const willAppendedLines = [];
34969
34969
  for (const line of globLines) if (!allLines.find((l) => l.trim() === line)) willAppendedLines.push(line);
34970
34970
  if (!willAppendedLines.length) return false;
34971
- fs.default.appendFileSync(gitIgnorePath, [comment, ...willAppendedLines].join("\n"), { encoding: "utf8" });
34972
- } else fs.default.writeFileSync(gitIgnorePath, [comment, ...globLines].join("\n"), { encoding: "utf8" });
34971
+ const needsNewlineBefore = content.length > 0 && !content.endsWith("\n");
34972
+ const textToAppend = [comment, ...willAppendedLines].join("\n");
34973
+ fs.default.appendFileSync(gitIgnorePath, `${needsNewlineBefore ? "\n" : ""}${textToAppend}\n`, { encoding: "utf8" });
34974
+ } else fs.default.writeFileSync(gitIgnorePath, `${[comment, ...globLines].join("\n")}\n`, { encoding: "utf8" });
34973
34975
  return true;
34974
34976
  };
34975
34977
 
@@ -35807,6 +35809,7 @@ const init = async () => {
35807
35809
  }
35808
35810
  default: throw new Error("Invalid provider");
35809
35811
  }
35812
+ if (appendToProjectRootGitignore({ globLines: [".env.hotupdater"] })) __clack_prompts.log.info(".gitignore has been modified to include .env.hotupdater");
35810
35813
  if (appendOutputDirectoryIntoGitignore()) __clack_prompts.log.info(".gitignore has been modified");
35811
35814
  };
35812
35815
 
@@ -35841,21 +35844,29 @@ function merge(target, source) {
35841
35844
  //#region src/utils/setChannel.ts
35842
35845
  const DEFAULT_CHANNEL$1 = "production";
35843
35846
  const setAndroidChannel = async (channel) => {
35844
- const androidParser = new require_fingerprint.AndroidConfigParser();
35847
+ const config = await (0, __hot_updater_plugin_core.loadConfig)(null);
35848
+ const customPaths = config.platform?.android?.stringResourcePaths;
35849
+ const androidParser = new require_fingerprint.AndroidConfigParser(customPaths);
35845
35850
  return await androidParser.set("hot_updater_channel", channel);
35846
35851
  };
35847
35852
  const getAndroidChannel = async () => {
35848
- const androidParser = new require_fingerprint.AndroidConfigParser();
35849
- if (!androidParser.exists()) throw new Error("android/app/src/main/res/values/strings.xml not found");
35853
+ const config = await (0, __hot_updater_plugin_core.loadConfig)(null);
35854
+ const customPaths = config.platform?.android?.stringResourcePaths;
35855
+ const androidParser = new require_fingerprint.AndroidConfigParser(customPaths);
35856
+ if (!await androidParser.exists()) throw new Error("No Android strings.xml files found");
35850
35857
  return merge({ value: DEFAULT_CHANNEL$1 }, await androidParser.get("hot_updater_channel"));
35851
35858
  };
35852
35859
  const setIosChannel = async (channel) => {
35853
- const iosParser = new require_fingerprint.IosConfigParser();
35860
+ const config = await (0, __hot_updater_plugin_core.loadConfig)(null);
35861
+ const customPaths = config.platform?.ios?.infoPlistPaths;
35862
+ const iosParser = new require_fingerprint.IosConfigParser(customPaths);
35854
35863
  return await iosParser.set("HOT_UPDATER_CHANNEL", channel);
35855
35864
  };
35856
35865
  const getIosChannel = async () => {
35857
- const iosParser = new require_fingerprint.IosConfigParser();
35858
- if (!iosParser.exists()) throw new Error("Info.plist not found");
35866
+ const config = await (0, __hot_updater_plugin_core.loadConfig)(null);
35867
+ const customPaths = config.platform?.ios?.infoPlistPaths;
35868
+ const iosParser = new require_fingerprint.IosConfigParser(customPaths);
35869
+ if (!await iosParser.exists()) throw new Error("No iOS Info.plist files found");
35859
35870
  return merge({ value: DEFAULT_CHANNEL$1 }, await iosParser.get("HOT_UPDATER_CHANNEL"));
35860
35871
  };
35861
35872
  const setChannel = async (platform$2, channel) => {
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { __commonJS, __require, __toESM, require_picocolors } from "./picocolors-BnzanxXs.js";
3
- import { AndroidConfigParser, IosConfigParser, createAndInjectFingerprintFiles, generateFingerprints, getFingerprintDiff, isFingerprintEquals, nativeFingerprint, readLocalFingerprint, require_base64_js, require_out, require_plist, showFingerprintDiff } from "./fingerprint-DLeoZ3u_.js";
3
+ import { AndroidConfigParser, IosConfigParser, createAndInjectFingerprintFiles, generateFingerprints, getFingerprintDiff, isFingerprintEquals, nativeFingerprint, readLocalFingerprint, require_base64_js, require_out, require_plist, showFingerprintDiff } from "./fingerprint-CyVxz4OY.js";
4
4
  import { EventEmitter, addAbortListener, on, once, setMaxListeners } from "node:events";
5
5
  import childProcess, { ChildProcess, execFile, spawn, spawnSync } from "node:child_process";
6
6
  import path from "node:path";
@@ -34974,8 +34974,10 @@ const appendToProjectRootGitignore = ({ cwd, globLines }) => {
34974
34974
  const willAppendedLines = [];
34975
34975
  for (const line of globLines) if (!allLines.find((l) => l.trim() === line)) willAppendedLines.push(line);
34976
34976
  if (!willAppendedLines.length) return false;
34977
- fs$1.appendFileSync(gitIgnorePath, [comment, ...willAppendedLines].join("\n"), { encoding: "utf8" });
34978
- } else fs$1.writeFileSync(gitIgnorePath, [comment, ...globLines].join("\n"), { encoding: "utf8" });
34977
+ const needsNewlineBefore = content.length > 0 && !content.endsWith("\n");
34978
+ const textToAppend = [comment, ...willAppendedLines].join("\n");
34979
+ fs$1.appendFileSync(gitIgnorePath, `${needsNewlineBefore ? "\n" : ""}${textToAppend}\n`, { encoding: "utf8" });
34980
+ } else fs$1.writeFileSync(gitIgnorePath, `${[comment, ...globLines].join("\n")}\n`, { encoding: "utf8" });
34979
34981
  return true;
34980
34982
  };
34981
34983
 
@@ -35813,6 +35815,7 @@ const init = async () => {
35813
35815
  }
35814
35816
  default: throw new Error("Invalid provider");
35815
35817
  }
35818
+ if (appendToProjectRootGitignore({ globLines: [".env.hotupdater"] })) p.log.info(".gitignore has been modified to include .env.hotupdater");
35816
35819
  if (appendOutputDirectoryIntoGitignore()) p.log.info(".gitignore has been modified");
35817
35820
  };
35818
35821
 
@@ -35847,21 +35850,29 @@ function merge(target, source) {
35847
35850
  //#region src/utils/setChannel.ts
35848
35851
  const DEFAULT_CHANNEL$1 = "production";
35849
35852
  const setAndroidChannel = async (channel) => {
35850
- const androidParser = new AndroidConfigParser();
35853
+ const config = await loadConfig(null);
35854
+ const customPaths = config.platform?.android?.stringResourcePaths;
35855
+ const androidParser = new AndroidConfigParser(customPaths);
35851
35856
  return await androidParser.set("hot_updater_channel", channel);
35852
35857
  };
35853
35858
  const getAndroidChannel = async () => {
35854
- const androidParser = new AndroidConfigParser();
35855
- if (!androidParser.exists()) throw new Error("android/app/src/main/res/values/strings.xml not found");
35859
+ const config = await loadConfig(null);
35860
+ const customPaths = config.platform?.android?.stringResourcePaths;
35861
+ const androidParser = new AndroidConfigParser(customPaths);
35862
+ if (!await androidParser.exists()) throw new Error("No Android strings.xml files found");
35856
35863
  return merge({ value: DEFAULT_CHANNEL$1 }, await androidParser.get("hot_updater_channel"));
35857
35864
  };
35858
35865
  const setIosChannel = async (channel) => {
35859
- const iosParser = new IosConfigParser();
35866
+ const config = await loadConfig(null);
35867
+ const customPaths = config.platform?.ios?.infoPlistPaths;
35868
+ const iosParser = new IosConfigParser(customPaths);
35860
35869
  return await iosParser.set("HOT_UPDATER_CHANNEL", channel);
35861
35870
  };
35862
35871
  const getIosChannel = async () => {
35863
- const iosParser = new IosConfigParser();
35864
- if (!iosParser.exists()) throw new Error("Info.plist not found");
35872
+ const config = await loadConfig(null);
35873
+ const customPaths = config.platform?.ios?.infoPlistPaths;
35874
+ const iosParser = new IosConfigParser(customPaths);
35875
+ if (!await iosParser.exists()) throw new Error("No iOS Info.plist files found");
35865
35876
  return merge({ value: DEFAULT_CHANNEL$1 }, await iosParser.get("HOT_UPDATER_CHANNEL"));
35866
35877
  };
35867
35878
  const setChannel = async (platform$2, channel) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hot-updater",
3
3
  "type": "module",
4
- "version": "0.20.0",
4
+ "version": "0.20.1",
5
5
  "bin": {
6
6
  "hot-updater": "./dist/index.js"
7
7
  },
@@ -49,13 +49,13 @@
49
49
  },
50
50
  "dependencies": {
51
51
  "@clack/prompts": "0.10.0",
52
- "@expo/fingerprint": "0.12.4",
52
+ "@expo/fingerprint": "0.13.4",
53
53
  "cosmiconfig": "^9.0.0",
54
54
  "cosmiconfig-typescript-loader": "^5.0.0",
55
55
  "es-git": "^0.2.0",
56
- "@hot-updater/core": "0.20.0",
57
- "@hot-updater/plugin-core": "0.20.0",
58
- "@hot-updater/console": "0.20.0"
56
+ "@hot-updater/console": "0.20.1",
57
+ "@hot-updater/core": "0.20.1",
58
+ "@hot-updater/plugin-core": "0.20.1"
59
59
  },
60
60
  "devDependencies": {
61
61
  "fast-xml-parser": "^5.2.3",
@@ -86,10 +86,10 @@
86
86
  "read-package-up": "^11.0.0",
87
87
  "semver": "^7.6.3",
88
88
  "uuidv7": "^1.0.2",
89
- "@hot-updater/aws": "0.20.0",
90
- "@hot-updater/cloudflare": "0.20.0",
91
- "@hot-updater/firebase": "0.20.0",
92
- "@hot-updater/supabase": "0.20.0"
89
+ "@hot-updater/aws": "0.20.1",
90
+ "@hot-updater/cloudflare": "0.20.1",
91
+ "@hot-updater/supabase": "0.20.1",
92
+ "@hot-updater/firebase": "0.20.1"
93
93
  },
94
94
  "peerDependencies": {
95
95
  "@hot-updater/aws": "*",