@hot-updater/react-native 0.29.2 → 0.29.4

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.
Files changed (55) hide show
  1. package/HotUpdater.podspec +0 -4
  2. package/android/src/oldarch/HotUpdaterModule.kt +12 -4
  3. package/android/src/oldarch/HotUpdaterSpec.kt +3 -5
  4. package/ios/HotUpdater/Internal/ArchiveExtractionUtilities.swift +178 -0
  5. package/ios/HotUpdater/Internal/BundleFileStorageService.swift +82 -47
  6. package/ios/HotUpdater/Internal/StreamingTarArchiveExtractor.swift +359 -0
  7. package/ios/HotUpdater/Internal/TarArchiveExtractor.swift +386 -0
  8. package/ios/HotUpdater/Internal/TarBrDecompressionStrategy.swift +7 -213
  9. package/ios/HotUpdater/Internal/TarGzDecompressionStrategy.swift +8 -126
  10. package/ios/HotUpdater/Internal/URLSessionDownloadService.swift +13 -2
  11. package/ios/HotUpdater/Internal/ZipArchiveExtractor.swift +462 -0
  12. package/ios/HotUpdater/Internal/ZipDecompressionStrategy.swift +4 -113
  13. package/lib/commonjs/DefaultResolver.js.map +1 -1
  14. package/lib/commonjs/checkForUpdate.js.map +1 -1
  15. package/lib/commonjs/index.js +0 -7
  16. package/lib/commonjs/index.js.map +1 -1
  17. package/lib/commonjs/native.js.map +1 -1
  18. package/lib/commonjs/native.spec.js.map +1 -1
  19. package/lib/commonjs/store.js.map +1 -1
  20. package/lib/commonjs/types.js.map +1 -1
  21. package/lib/commonjs/wrap.js.map +1 -1
  22. package/lib/module/DefaultResolver.js.map +1 -1
  23. package/lib/module/checkForUpdate.js.map +1 -1
  24. package/lib/module/index.js +0 -7
  25. package/lib/module/index.js.map +1 -1
  26. package/lib/module/native.js.map +1 -1
  27. package/lib/module/native.spec.js.map +1 -1
  28. package/lib/module/store.js.map +1 -1
  29. package/lib/module/types.js.map +1 -1
  30. package/lib/module/wrap.js.map +1 -1
  31. package/lib/typescript/commonjs/DefaultResolver.d.ts.map +1 -1
  32. package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -1
  33. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  34. package/lib/typescript/commonjs/native.d.ts.map +1 -1
  35. package/lib/typescript/commonjs/store.d.ts.map +1 -1
  36. package/lib/typescript/commonjs/types.d.ts.map +1 -1
  37. package/lib/typescript/commonjs/wrap.d.ts.map +1 -1
  38. package/lib/typescript/module/DefaultResolver.d.ts.map +1 -1
  39. package/lib/typescript/module/checkForUpdate.d.ts.map +1 -1
  40. package/lib/typescript/module/index.d.ts.map +1 -1
  41. package/lib/typescript/module/native.d.ts.map +1 -1
  42. package/lib/typescript/module/store.d.ts.map +1 -1
  43. package/lib/typescript/module/types.d.ts.map +1 -1
  44. package/lib/typescript/module/wrap.d.ts.map +1 -1
  45. package/package.json +9 -9
  46. package/plugin/build/transformers.js +83 -97
  47. package/plugin/build/withHotUpdater.js +159 -239
  48. package/src/DefaultResolver.ts +1 -0
  49. package/src/checkForUpdate.ts +1 -0
  50. package/src/index.ts +0 -7
  51. package/src/native.spec.ts +4 -6
  52. package/src/native.ts +1 -0
  53. package/src/store.ts +1 -0
  54. package/src/types.ts +1 -0
  55. package/src/wrap.tsx +1 -0
@@ -1,69 +1,24 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
- }
37
- };
38
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
39
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
40
4
  };
41
5
  Object.defineProperty(exports, "__esModule", { value: true });
42
- var promises_1 = require("node:fs/promises");
43
- var cli_tools_1 = require("@hot-updater/cli-tools");
44
- var config_plugins_1 = require("expo/config-plugins");
45
- var hot_updater_1 = require("hot-updater");
46
- var path_1 = __importDefault(require("path"));
47
- var package_json_1 = __importDefault(require("../../package.json"));
48
- var transformers_1 = require("./transformers");
49
- var fingerprintCache = null;
50
- var getFingerprint = function () { return __awaiter(void 0, void 0, void 0, function () {
51
- return __generator(this, function (_a) {
52
- switch (_a.label) {
53
- case 0:
54
- if (fingerprintCache) {
55
- return [2 /*return*/, fingerprintCache];
56
- }
57
- return [4 /*yield*/, (0, hot_updater_1.generateFingerprints)()];
58
- case 1:
59
- fingerprintCache = _a.sent();
60
- return [4 /*yield*/, (0, hot_updater_1.createFingerprintJSON)(fingerprintCache)];
61
- case 2:
62
- _a.sent();
63
- return [2 /*return*/, fingerprintCache];
64
- }
65
- });
66
- }); };
6
+ const promises_1 = require("node:fs/promises");
7
+ const path_1 = __importDefault(require("path"));
8
+ const cli_tools_1 = require("@hot-updater/cli-tools");
9
+ const config_plugins_1 = require("expo/config-plugins");
10
+ const hot_updater_1 = require("hot-updater");
11
+ const package_json_1 = __importDefault(require("../../package.json"));
12
+ const transformers_1 = require("./transformers");
13
+ let fingerprintCache = null;
14
+ const getFingerprint = async () => {
15
+ if (fingerprintCache) {
16
+ return fingerprintCache;
17
+ }
18
+ fingerprintCache = await (0, hot_updater_1.generateFingerprints)();
19
+ await (0, hot_updater_1.createFingerprintJSON)(fingerprintCache);
20
+ return fingerprintCache;
21
+ };
67
22
  /**
68
23
  * Extract public key for embedding in native configs.
69
24
  * Supports multiple sources with priority order:
@@ -72,92 +27,82 @@ var getFingerprint = function () { return __awaiter(void 0, void 0, void 0, func
72
27
  * 3. Public key file (derived from privateKeyPath)
73
28
  * 4. Skip with warning (graceful fallback)
74
29
  */
75
- var getPublicKeyFromConfig = function (signingConfig) { return __awaiter(void 0, void 0, void 0, function () {
76
- var envPrivateKey, publicKeyPEM, privateKeyPath, publicKeyPath, privateKeyPEM, publicKeyPEM, _privateKeyError_1, publicKeyPEM, _publicKeyError_1;
77
- return __generator(this, function (_a) {
78
- switch (_a.label) {
79
- case 0:
80
- // If signing not enabled, no public key needed
81
- if (!(signingConfig === null || signingConfig === void 0 ? void 0 : signingConfig.enabled)) {
82
- return [2 /*return*/, null];
83
- }
84
- envPrivateKey = process.env.HOT_UPDATER_PRIVATE_KEY;
85
- if (envPrivateKey) {
86
- try {
87
- publicKeyPEM = (0, hot_updater_1.getPublicKeyFromPrivate)(envPrivateKey);
88
- console.log("[hot-updater] Using public key extracted from HOT_UPDATER_PRIVATE_KEY environment variable");
89
- return [2 /*return*/, publicKeyPEM.trim()];
90
- }
91
- catch (error) {
92
- console.warn("[hot-updater] WARNING: Failed to extract public key from HOT_UPDATER_PRIVATE_KEY:\n" +
93
- "".concat(error instanceof Error ? error.message : String(error), "\n"));
94
- // Continue to try other methods
95
- }
96
- }
97
- // If no privateKeyPath configured, can't proceed with file-based methods
98
- if (!signingConfig.privateKeyPath) {
99
- console.warn("[hot-updater] WARNING: signing.enabled is true but no privateKeyPath configured.\n" +
100
- "Public key will not be embedded. Set HOT_UPDATER_PRIVATE_KEY environment variable or configure privateKeyPath.");
101
- return [2 /*return*/, null];
102
- }
103
- privateKeyPath = path_1.default.isAbsolute(signingConfig.privateKeyPath)
104
- ? signingConfig.privateKeyPath
105
- : path_1.default.resolve(process.cwd(), signingConfig.privateKeyPath);
106
- publicKeyPath = privateKeyPath.replace(/private-key\.pem$/, "public-key.pem");
107
- _a.label = 1;
108
- case 1:
109
- _a.trys.push([1, 3, , 8]);
110
- return [4 /*yield*/, (0, hot_updater_1.loadPrivateKey)(privateKeyPath)];
111
- case 2:
112
- privateKeyPEM = _a.sent();
113
- publicKeyPEM = (0, hot_updater_1.getPublicKeyFromPrivate)(privateKeyPEM);
114
- console.log("[hot-updater] Extracted public key from ".concat(privateKeyPath));
115
- return [2 /*return*/, publicKeyPEM.trim()];
116
- case 3:
117
- _privateKeyError_1 = _a.sent();
118
- _a.label = 4;
119
- case 4:
120
- _a.trys.push([4, 6, , 7]);
121
- return [4 /*yield*/, (0, promises_1.readFile)(publicKeyPath, "utf-8")];
122
- case 5:
123
- publicKeyPEM = _a.sent();
124
- console.log("[hot-updater] Using public key from ".concat(publicKeyPath));
125
- return [2 /*return*/, publicKeyPEM.trim()];
126
- case 6:
127
- _publicKeyError_1 = _a.sent();
128
- // Priority 4: All sources failed - throw error
129
- throw new Error("[hot-updater] Failed to load public key for bundle signing.\n\n" +
130
- "Signing is enabled (signing.enabled: true) but no public key sources found.\n\n" +
131
- "For EAS builds, use EAS Secrets:\n" +
132
- ' eas env:create --name HOT_UPDATER_PRIVATE_KEY --value "$(cat keys/private-key.pem)"\n\n' +
133
- "Or add to eas.json:\n" +
134
- ' "env": { "HOT_UPDATER_PRIVATE_KEY": "-----BEGIN PRIVATE KEY-----\\n..." }\n\n' +
135
- "For local development:\n" +
136
- " npx hot-updater keys generate\n\n" +
137
- "Searched locations:\n" +
138
- " - HOT_UPDATER_PRIVATE_KEY environment variable\n" +
139
- " - Private key file: ".concat(privateKeyPath, "\n") +
140
- " - Public key file: ".concat(publicKeyPath, "\n"));
141
- case 7: return [3 /*break*/, 8];
142
- case 8: return [2 /*return*/];
30
+ const getPublicKeyFromConfig = async (signingConfig) => {
31
+ // If signing not enabled, no public key needed
32
+ if (!signingConfig?.enabled) {
33
+ return null;
34
+ }
35
+ // Priority 1: Environment variable with private key PEM (EAS builds)
36
+ const envPrivateKey = process.env.HOT_UPDATER_PRIVATE_KEY;
37
+ if (envPrivateKey) {
38
+ try {
39
+ const publicKeyPEM = (0, hot_updater_1.getPublicKeyFromPrivate)(envPrivateKey);
40
+ console.log("[hot-updater] Using public key extracted from HOT_UPDATER_PRIVATE_KEY environment variable");
41
+ return publicKeyPEM.trim();
143
42
  }
144
- });
145
- }); };
43
+ catch (error) {
44
+ console.warn("[hot-updater] WARNING: Failed to extract public key from HOT_UPDATER_PRIVATE_KEY:\n" +
45
+ `${error instanceof Error ? error.message : String(error)}\n`);
46
+ // Continue to try other methods
47
+ }
48
+ }
49
+ // If no privateKeyPath configured, can't proceed with file-based methods
50
+ if (!signingConfig.privateKeyPath) {
51
+ console.warn("[hot-updater] WARNING: signing.enabled is true but no privateKeyPath configured.\n" +
52
+ "Public key will not be embedded. Set HOT_UPDATER_PRIVATE_KEY environment variable or configure privateKeyPath.");
53
+ return null;
54
+ }
55
+ // Resolve paths
56
+ const privateKeyPath = path_1.default.isAbsolute(signingConfig.privateKeyPath)
57
+ ? signingConfig.privateKeyPath
58
+ : path_1.default.resolve(process.cwd(), signingConfig.privateKeyPath);
59
+ const publicKeyPath = privateKeyPath.replace(/private-key\.pem$/, "public-key.pem");
60
+ try {
61
+ // Priority 2: Private key file (existing method)
62
+ const privateKeyPEM = await (0, hot_updater_1.loadPrivateKey)(privateKeyPath);
63
+ const publicKeyPEM = (0, hot_updater_1.getPublicKeyFromPrivate)(privateKeyPEM);
64
+ console.log(`[hot-updater] Extracted public key from ${privateKeyPath}`);
65
+ return publicKeyPEM.trim();
66
+ }
67
+ catch {
68
+ try {
69
+ // Priority 3: Public key file (fallback)
70
+ const publicKeyPEM = await (0, promises_1.readFile)(publicKeyPath, "utf-8");
71
+ console.log(`[hot-updater] Using public key from ${publicKeyPath}`);
72
+ return publicKeyPEM.trim();
73
+ }
74
+ catch {
75
+ // Priority 4: All sources failed - throw error
76
+ throw new Error("[hot-updater] Failed to load public key for bundle signing.\n\n" +
77
+ "Signing is enabled (signing.enabled: true) but no public key sources found.\n\n" +
78
+ "For EAS builds, use EAS Secrets:\n" +
79
+ ' eas env:create --name HOT_UPDATER_PRIVATE_KEY --value "$(cat keys/private-key.pem)"\n\n' +
80
+ "Or add to eas.json:\n" +
81
+ ' "env": { "HOT_UPDATER_PRIVATE_KEY": "-----BEGIN PRIVATE KEY-----\\n..." }\n\n' +
82
+ "For local development:\n" +
83
+ " npx hot-updater keys generate\n\n" +
84
+ `Searched locations:\n` +
85
+ ` - HOT_UPDATER_PRIVATE_KEY environment variable\n` +
86
+ ` - Private key file: ${privateKeyPath}\n` +
87
+ ` - Public key file: ${publicKeyPath}\n`);
88
+ }
89
+ }
90
+ };
146
91
  /**
147
92
  * Native code modifications - should only run once
148
93
  */
149
- var withHotUpdaterNativeCode = function (config) {
150
- var modifiedConfig = config;
94
+ const withHotUpdaterNativeCode = (config) => {
95
+ let modifiedConfig = config;
151
96
  // === iOS: Objective-C & Swift in AppDelegate ===
152
- modifiedConfig = (0, config_plugins_1.withAppDelegate)(modifiedConfig, function (cfg) {
153
- var contents = cfg.modResults.contents;
97
+ modifiedConfig = (0, config_plugins_1.withAppDelegate)(modifiedConfig, (cfg) => {
98
+ let contents = cfg.modResults.contents;
154
99
  contents = (0, transformers_1.transformIOS)(contents);
155
100
  cfg.modResults.contents = contents;
156
101
  return cfg;
157
102
  });
158
103
  // === Android: Kotlin in MainApplication ===
159
- modifiedConfig = (0, config_plugins_1.withMainApplication)(modifiedConfig, function (cfg) {
160
- var contents = cfg.modResults.contents;
104
+ modifiedConfig = (0, config_plugins_1.withMainApplication)(modifiedConfig, (cfg) => {
105
+ let contents = cfg.modResults.contents;
161
106
  contents = (0, transformers_1.transformAndroid)(contents);
162
107
  cfg.modResults.contents = contents;
163
108
  return cfg;
@@ -167,118 +112,93 @@ var withHotUpdaterNativeCode = function (config) {
167
112
  /**
168
113
  * Configuration updates - should run every time
169
114
  */
170
- var withHotUpdaterConfigAsync = function (props) { return function (config) {
171
- var channel = props.channel || "production";
172
- var modifiedConfig = config;
115
+ const withHotUpdaterConfigAsync = (props) => (config) => {
116
+ const channel = props.channel || "production";
117
+ let modifiedConfig = config;
173
118
  // === iOS: Add channel and fingerprint to Info.plist ===
174
- modifiedConfig = (0, config_plugins_1.withInfoPlist)(modifiedConfig, function (cfg) { return __awaiter(void 0, void 0, void 0, function () {
175
- var fingerprintHash, config, fingerprint, publicKey;
176
- return __generator(this, function (_a) {
177
- switch (_a.label) {
178
- case 0:
179
- fingerprintHash = null;
180
- return [4 /*yield*/, (0, cli_tools_1.loadConfig)(null)];
181
- case 1:
182
- config = _a.sent();
183
- if (!(config.updateStrategy !== "appVersion")) return [3 /*break*/, 3];
184
- return [4 /*yield*/, getFingerprint()];
185
- case 2:
186
- fingerprint = _a.sent();
187
- fingerprintHash = fingerprint.ios.hash;
188
- _a.label = 3;
189
- case 3: return [4 /*yield*/, getPublicKeyFromConfig(config.signing)];
190
- case 4:
191
- publicKey = _a.sent();
192
- cfg.modResults.HOT_UPDATER_CHANNEL = channel;
193
- if (fingerprintHash) {
194
- cfg.modResults.HOT_UPDATER_FINGERPRINT_HASH = fingerprintHash;
195
- }
196
- if (publicKey) {
197
- cfg.modResults.HOT_UPDATER_PUBLIC_KEY = publicKey;
198
- }
199
- return [2 /*return*/, cfg];
200
- }
201
- });
202
- }); });
119
+ modifiedConfig = (0, config_plugins_1.withInfoPlist)(modifiedConfig, async (cfg) => {
120
+ let fingerprintHash = null;
121
+ const config = await (0, cli_tools_1.loadConfig)(null);
122
+ if (config.updateStrategy !== "appVersion") {
123
+ const fingerprint = await getFingerprint();
124
+ fingerprintHash = fingerprint.ios.hash;
125
+ }
126
+ // Load public key if signing is enabled
127
+ const publicKey = await getPublicKeyFromConfig(config.signing);
128
+ cfg.modResults.HOT_UPDATER_CHANNEL = channel;
129
+ if (fingerprintHash) {
130
+ cfg.modResults.HOT_UPDATER_FINGERPRINT_HASH = fingerprintHash;
131
+ }
132
+ if (publicKey) {
133
+ cfg.modResults.HOT_UPDATER_PUBLIC_KEY = publicKey;
134
+ }
135
+ return cfg;
136
+ });
203
137
  // === Android: Add channel and fingerprint to strings.xml ===
204
- modifiedConfig = (0, config_plugins_1.withStringsXml)(modifiedConfig, function (cfg) { return __awaiter(void 0, void 0, void 0, function () {
205
- var fingerprintHash, config, fingerprint, publicKey;
206
- return __generator(this, function (_a) {
207
- switch (_a.label) {
208
- case 0:
209
- fingerprintHash = null;
210
- return [4 /*yield*/, (0, cli_tools_1.loadConfig)(null)];
211
- case 1:
212
- config = _a.sent();
213
- if (!(config.updateStrategy !== "appVersion")) return [3 /*break*/, 3];
214
- return [4 /*yield*/, getFingerprint()];
215
- case 2:
216
- fingerprint = _a.sent();
217
- fingerprintHash = fingerprint.android.hash;
218
- _a.label = 3;
219
- case 3: return [4 /*yield*/, getPublicKeyFromConfig(config.signing)];
220
- case 4:
221
- publicKey = _a.sent();
222
- // Ensure resources object exists
223
- if (!cfg.modResults.resources) {
224
- cfg.modResults.resources = {};
225
- }
226
- if (!cfg.modResults.resources.string) {
227
- cfg.modResults.resources.string = [];
228
- }
229
- // Remove existing hot_updater_channel entry if it exists
230
- cfg.modResults.resources.string = cfg.modResults.resources.string.filter(function (item) { return !(item.$ && item.$.name === "hot_updater_channel"); });
231
- // Add the new hot_updater_channel entry
232
- cfg.modResults.resources.string.push({
233
- $: {
234
- name: "hot_updater_channel",
235
- moduleConfig: "true",
236
- },
237
- _: channel,
238
- });
239
- if (fingerprintHash) {
240
- // Remove existing hot_updater_fingerprint_hash entry if it exists
241
- cfg.modResults.resources.string =
242
- cfg.modResults.resources.string.filter(function (item) {
243
- return !(item.$ && item.$.name === "hot_updater_fingerprint_hash");
244
- });
245
- // Add the new hot_updater_fingerprint_hash entry
246
- cfg.modResults.resources.string.push({
247
- $: {
248
- name: "hot_updater_fingerprint_hash",
249
- moduleConfig: "true",
250
- },
251
- _: fingerprintHash,
252
- });
253
- }
254
- if (publicKey) {
255
- // Remove existing hot_updater_public_key entry if it exists
256
- cfg.modResults.resources.string =
257
- cfg.modResults.resources.string.filter(function (item) { return !(item.$ && item.$.name === "hot_updater_public_key"); });
258
- // Add the new hot_updater_public_key entry
259
- cfg.modResults.resources.string.push({
260
- $: {
261
- name: "hot_updater_public_key",
262
- moduleConfig: "true",
263
- },
264
- _: publicKey,
265
- });
266
- }
267
- return [2 /*return*/, cfg];
268
- }
138
+ modifiedConfig = (0, config_plugins_1.withStringsXml)(modifiedConfig, async (cfg) => {
139
+ let fingerprintHash = null;
140
+ const config = await (0, cli_tools_1.loadConfig)(null);
141
+ if (config.updateStrategy !== "appVersion") {
142
+ const fingerprint = await getFingerprint();
143
+ fingerprintHash = fingerprint.android.hash;
144
+ }
145
+ // Load public key if signing is enabled
146
+ const publicKey = await getPublicKeyFromConfig(config.signing);
147
+ // Ensure resources object exists
148
+ if (!cfg.modResults.resources) {
149
+ cfg.modResults.resources = {};
150
+ }
151
+ if (!cfg.modResults.resources.string) {
152
+ cfg.modResults.resources.string = [];
153
+ }
154
+ // Remove existing hot_updater_channel entry if it exists
155
+ cfg.modResults.resources.string = cfg.modResults.resources.string.filter((item) => !(item.$ && item.$.name === "hot_updater_channel"));
156
+ // Add the new hot_updater_channel entry
157
+ cfg.modResults.resources.string.push({
158
+ $: {
159
+ name: "hot_updater_channel",
160
+ moduleConfig: "true",
161
+ },
162
+ _: channel,
269
163
  });
270
- }); });
164
+ if (fingerprintHash) {
165
+ // Remove existing hot_updater_fingerprint_hash entry if it exists
166
+ cfg.modResults.resources.string =
167
+ cfg.modResults.resources.string.filter((item) => !(item.$ && item.$.name === "hot_updater_fingerprint_hash"));
168
+ // Add the new hot_updater_fingerprint_hash entry
169
+ cfg.modResults.resources.string.push({
170
+ $: {
171
+ name: "hot_updater_fingerprint_hash",
172
+ moduleConfig: "true",
173
+ },
174
+ _: fingerprintHash,
175
+ });
176
+ }
177
+ if (publicKey) {
178
+ // Remove existing hot_updater_public_key entry if it exists
179
+ cfg.modResults.resources.string =
180
+ cfg.modResults.resources.string.filter((item) => !(item.$ && item.$.name === "hot_updater_public_key"));
181
+ // Add the new hot_updater_public_key entry
182
+ cfg.modResults.resources.string.push({
183
+ $: {
184
+ name: "hot_updater_public_key",
185
+ moduleConfig: "true",
186
+ },
187
+ _: publicKey,
188
+ });
189
+ }
190
+ return cfg;
191
+ });
271
192
  return modifiedConfig;
272
- }; };
193
+ };
273
194
  /**
274
195
  * Main plugin that combines both native code (run once) and config (run always)
275
196
  */
276
- var withHotUpdater = function (config, props) {
277
- if (props === void 0) { props = {}; }
197
+ const withHotUpdater = (config, props = {}) => {
278
198
  // Apply plugins in order
279
199
  return (0, config_plugins_1.withPlugins)(config, [
280
200
  // Native code modifications - wrapped with createRunOncePlugin
281
- (0, config_plugins_1.createRunOncePlugin)(withHotUpdaterNativeCode, "".concat(package_json_1.default.name, "-native"), package_json_1.default.version),
201
+ (0, config_plugins_1.createRunOncePlugin)(withHotUpdaterNativeCode, `${package_json_1.default.name}-native`, package_json_1.default.version),
282
202
  // Configuration updates - runs every time
283
203
  withHotUpdaterConfigAsync(props),
284
204
  ]);
@@ -1,4 +1,5 @@
1
1
  import type { AppUpdateInfo } from "@hot-updater/core";
2
+
2
3
  import { fetchUpdateInfo } from "./fetchUpdateInfo";
3
4
  import type { HotUpdaterResolver, ResolverCheckUpdateParams } from "./types";
4
5
 
@@ -1,5 +1,6 @@
1
1
  import type { AppUpdateInfo } from "@hot-updater/core";
2
2
  import { Platform } from "react-native";
3
+
3
4
  import { HotUpdaterError } from "./error";
4
5
  import {
5
6
  getAppVersion,
package/src/index.ts CHANGED
@@ -62,13 +62,6 @@ const registerGlobalGetBaseURL = () => {
62
62
  globalThis.HotUpdaterGetBaseURL = fn;
63
63
  }
64
64
  }
65
-
66
- // Register to global (React Native, Node.js)
67
- if (typeof global !== "undefined") {
68
- if (!global.HotUpdaterGetBaseURL) {
69
- global.HotUpdaterGetBaseURL = fn;
70
- }
71
- }
72
65
  };
73
66
 
74
67
  // Call registration immediately on module load
@@ -314,9 +314,8 @@ describe("notifyAppReady", () => {
314
314
  nativeModuleMock.getBaseURL.mockReturnValue("file:///bundle-123");
315
315
  nativeModuleMock.updateBundle.mockResolvedValue(true);
316
316
 
317
- const { getBaseURL, getBundleId, getManifest, updateBundle } = await import(
318
- "./native"
319
- );
317
+ const { getBaseURL, getBundleId, getManifest, updateBundle } =
318
+ await import("./native");
320
319
 
321
320
  expect(getBundleId()).toBe("bundle-123");
322
321
  expect(getManifest()).toEqual({
@@ -366,9 +365,8 @@ describe("notifyAppReady", () => {
366
365
  nativeModuleMock.getBaseURL.mockReturnValue("file:///bundle-beta");
367
366
  nativeModuleMock.resetChannel.mockResolvedValue(true);
368
367
 
369
- const { getBaseURL, getBundleId, getManifest, resetChannel } = await import(
370
- "./native"
371
- );
368
+ const { getBaseURL, getBundleId, getManifest, resetChannel } =
369
+ await import("./native");
372
370
 
373
371
  expect(getBundleId()).toBe("bundle-beta");
374
372
  expect(getManifest()).toEqual({
package/src/native.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  type UpdateStatus,
6
6
  } from "@hot-updater/core";
7
7
  import { NativeEventEmitter, Platform } from "react-native";
8
+
8
9
  import { HotUpdaterErrorCode, isHotUpdaterError } from "./error";
9
10
  import HotUpdaterNative, {
10
11
  type UpdateBundleParams,
package/src/store.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import useSyncExternalStoreExports from "use-sync-external-store/shim/with-selector";
2
+
2
3
  import { addListener } from "./native";
3
4
 
4
5
  export type HotUpdaterState = {
package/src/types.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { AppUpdateInfo } from "@hot-updater/core";
2
+
2
3
  import type { NotifyAppReadyResult } from "./native";
3
4
 
4
5
  /**
package/src/wrap.tsx CHANGED
@@ -1,4 +1,5 @@
1
1
  import React, { useEffect, useState } from "react";
2
+
2
3
  import { checkForUpdate } from "./checkForUpdate";
3
4
  import type { HotUpdaterError } from "./error";
4
5
  import { useEventCallback } from "./hooks/useEventCallback";