@vanikya/ota-react-native 0.2.7 → 0.2.8
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/app.plugin.js +56 -75
- package/lib/commonjs/index.js +1 -1
- package/lib/module/index.js +1 -1
- package/lib/typescript/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -1
package/app.plugin.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
const { withMainApplication, withAppDelegate } = require('@expo/config-plugins');
|
|
1
|
+
const { withMainApplication, withAppDelegate, withDangerousMod } = require('@expo/config-plugins');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* OTA Update Expo Config Plugin
|
|
5
7
|
*
|
|
6
8
|
* This plugin modifies the native code to enable OTA bundle loading:
|
|
7
|
-
* - Android:
|
|
9
|
+
* - Android: Modifies bundle loading for both old and new architecture
|
|
8
10
|
* - iOS: Modifies bundleURL() in AppDelegate.swift
|
|
9
|
-
*
|
|
10
|
-
* Supports both old architecture (getJSBundleFile override) and
|
|
11
|
-
* new architecture (jsBundleFilePath parameter in getDefaultReactHost).
|
|
12
11
|
*/
|
|
13
12
|
|
|
14
13
|
function withOTAUpdateAndroid(config) {
|
|
@@ -35,74 +34,68 @@ function withOTAUpdateAndroid(config) {
|
|
|
35
34
|
let injected = false;
|
|
36
35
|
|
|
37
36
|
// ============================================================
|
|
38
|
-
// Strategy 1:
|
|
39
|
-
// Look for:
|
|
37
|
+
// Strategy 1: Expo New Architecture with ReactNativeHostWrapper
|
|
38
|
+
// Look for: ReactNativeHostWrapper.createReactHost(applicationContext, reactNativeHost)
|
|
39
|
+
// We need to modify the reactNativeHost to include our bundle override
|
|
40
|
+
// AND add a bundleAssetName override to return null when OTA bundle exists
|
|
40
41
|
// ============================================================
|
|
41
|
-
const
|
|
42
|
-
if (
|
|
43
|
-
console.log('[OTAUpdate] Android: Detected
|
|
44
|
-
|
|
45
|
-
// Find the getDefaultReactHost call and add jsBundleFilePath parameter
|
|
46
|
-
// Pattern: getDefaultReactHost(applicationContext, packageList, ...)
|
|
47
|
-
const reactHostRegex = /(getDefaultReactHost\s*\(\s*\n?\s*)(applicationContext)(\s*,)/g;
|
|
48
|
-
|
|
49
|
-
if (reactHostRegex.test(contents)) {
|
|
50
|
-
contents = contents.replace(
|
|
51
|
-
/(getDefaultReactHost\s*\(\s*\n?\s*)(applicationContext)(\s*,)/,
|
|
52
|
-
'$1$2$3\n jsBundleFilePath = OTAUpdateHelper.getJSBundleFile(applicationContext),'
|
|
53
|
-
);
|
|
54
|
-
console.log('[OTAUpdate] Android: Injected jsBundleFilePath parameter (new architecture)');
|
|
55
|
-
injected = true;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
42
|
+
const expoNewArchPattern = /ReactNativeHostWrapper\.createReactHost\s*\(\s*applicationContext\s*,\s*reactNativeHost\s*\)/;
|
|
43
|
+
if (expoNewArchPattern.test(contents)) {
|
|
44
|
+
console.log('[OTAUpdate] Android: Detected Expo New Architecture pattern');
|
|
58
45
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
46
|
+
// For Expo new arch, we need to add getBundleAssetName override
|
|
47
|
+
// to return null when OTA bundle exists (this forces it to use getJSBundleFile)
|
|
48
|
+
const defaultHostPattern = /(object\s*:\s*DefaultReactNativeHost\s*\([^)]*\)\s*\{)/;
|
|
49
|
+
if (defaultHostPattern.test(contents)) {
|
|
50
|
+
const bundleOverride = `
|
|
51
|
+
override fun getJSBundleFile(): String? {
|
|
52
|
+
return OTAUpdateHelper.getJSBundleFile(applicationContext)
|
|
53
|
+
}
|
|
67
54
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
// Add jsBundleFilePath to the parameters
|
|
75
|
-
const newParams = params.trim() + ',\n jsBundleFilePath = OTAUpdateHelper.getJSBundleFile(applicationContext)';
|
|
76
|
-
return `${prefix}${newParams})`;
|
|
55
|
+
override fun getBundleAssetName(): String? {
|
|
56
|
+
// Return null if OTA bundle exists to force using getJSBundleFile
|
|
57
|
+
val otaBundle = OTAUpdateHelper.getJSBundleFile(applicationContext)
|
|
58
|
+
if (otaBundle != null) {
|
|
59
|
+
return null
|
|
77
60
|
}
|
|
78
|
-
|
|
79
|
-
|
|
61
|
+
return super.getBundleAssetName()
|
|
62
|
+
}
|
|
63
|
+
`;
|
|
64
|
+
contents = contents.replace(defaultHostPattern, `$1${bundleOverride}`);
|
|
65
|
+
console.log('[OTAUpdate] Android: Injected getJSBundleFile and getBundleAssetName overrides');
|
|
80
66
|
injected = true;
|
|
81
67
|
}
|
|
82
68
|
}
|
|
83
69
|
|
|
84
70
|
// ============================================================
|
|
85
|
-
// Strategy
|
|
86
|
-
// Look for: object : DefaultReactNativeHost(this) { ... }
|
|
71
|
+
// Strategy 2: Standard DefaultReactNativeHost pattern
|
|
87
72
|
// ============================================================
|
|
88
73
|
if (!injected) {
|
|
89
74
|
const defaultHostPattern = /(object\s*:\s*DefaultReactNativeHost\s*\([^)]*\)\s*\{)/;
|
|
90
75
|
if (defaultHostPattern.test(contents)) {
|
|
91
|
-
console.log('[OTAUpdate] Android: Detected DefaultReactNativeHost
|
|
76
|
+
console.log('[OTAUpdate] Android: Detected DefaultReactNativeHost');
|
|
92
77
|
|
|
93
|
-
const
|
|
78
|
+
const bundleOverride = `
|
|
94
79
|
override fun getJSBundleFile(): String? {
|
|
95
80
|
return OTAUpdateHelper.getJSBundleFile(applicationContext)
|
|
96
81
|
}
|
|
82
|
+
|
|
83
|
+
override fun getBundleAssetName(): String? {
|
|
84
|
+
val otaBundle = OTAUpdateHelper.getJSBundleFile(applicationContext)
|
|
85
|
+
if (otaBundle != null) {
|
|
86
|
+
return null
|
|
87
|
+
}
|
|
88
|
+
return super.getBundleAssetName()
|
|
89
|
+
}
|
|
97
90
|
`;
|
|
98
|
-
contents = contents.replace(defaultHostPattern, `$1${
|
|
99
|
-
console.log('[OTAUpdate] Android: Injected
|
|
91
|
+
contents = contents.replace(defaultHostPattern, `$1${bundleOverride}`);
|
|
92
|
+
console.log('[OTAUpdate] Android: Injected bundle overrides');
|
|
100
93
|
injected = true;
|
|
101
94
|
}
|
|
102
95
|
}
|
|
103
96
|
|
|
104
97
|
// ============================================================
|
|
105
|
-
// Strategy
|
|
98
|
+
// Strategy 3: Look for getUseDeveloperSupport and insert before it
|
|
106
99
|
// ============================================================
|
|
107
100
|
if (!injected) {
|
|
108
101
|
const devSupportPattern = /([ \t]*)(override\s+fun\s+getUseDeveloperSupport\s*\(\s*\))/;
|
|
@@ -112,33 +105,22 @@ function withOTAUpdateAndroid(config) {
|
|
|
112
105
|
const match = contents.match(devSupportPattern);
|
|
113
106
|
const indent = match ? match[1] : ' ';
|
|
114
107
|
|
|
115
|
-
const
|
|
108
|
+
const bundleOverride = `${indent}override fun getJSBundleFile(): String? {
|
|
116
109
|
${indent} return OTAUpdateHelper.getJSBundleFile(applicationContext)
|
|
117
110
|
${indent}}
|
|
118
111
|
|
|
119
|
-
${indent}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
112
|
+
${indent}override fun getBundleAssetName(): String? {
|
|
113
|
+
${indent} val otaBundle = OTAUpdateHelper.getJSBundleFile(applicationContext)
|
|
114
|
+
${indent} if (otaBundle != null) {
|
|
115
|
+
${indent} return null
|
|
116
|
+
${indent} }
|
|
117
|
+
${indent} return super.getBundleAssetName()
|
|
118
|
+
${indent}}
|
|
126
119
|
|
|
127
|
-
|
|
128
|
-
// Strategy 5: Look for ReactNativeHost in any form
|
|
129
|
-
// ============================================================
|
|
130
|
-
if (!injected) {
|
|
131
|
-
const anyHostPattern = /(:\s*ReactNativeHost\s*\{)/;
|
|
132
|
-
if (anyHostPattern.test(contents)) {
|
|
133
|
-
console.log('[OTAUpdate] Android: Found ReactNativeHost block');
|
|
120
|
+
${indent}`;
|
|
134
121
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return OTAUpdateHelper.getJSBundleFile(applicationContext)
|
|
138
|
-
}
|
|
139
|
-
`;
|
|
140
|
-
contents = contents.replace(anyHostPattern, `$1${getJSBundleFileOverride}`);
|
|
141
|
-
console.log('[OTAUpdate] Android: Injected getJSBundleFile in ReactNativeHost');
|
|
122
|
+
contents = contents.replace(devSupportPattern, `${bundleOverride}$2`);
|
|
123
|
+
console.log('[OTAUpdate] Android: Injected bundle overrides before getUseDeveloperSupport');
|
|
142
124
|
injected = true;
|
|
143
125
|
}
|
|
144
126
|
}
|
|
@@ -146,7 +128,6 @@ ${indent}`;
|
|
|
146
128
|
if (!injected) {
|
|
147
129
|
console.warn('[OTAUpdate] Android: ⚠️ Could not find injection point!');
|
|
148
130
|
console.warn('[OTAUpdate] Android: Please manually add getJSBundleFile override');
|
|
149
|
-
console.warn('[OTAUpdate] Android: See documentation for manual setup');
|
|
150
131
|
|
|
151
132
|
// Log relevant lines for debugging
|
|
152
133
|
const lines = contents.split('\n');
|
|
@@ -204,7 +185,7 @@ function withOTAUpdateIOS(config) {
|
|
|
204
185
|
}
|
|
205
186
|
`;
|
|
206
187
|
|
|
207
|
-
// Strategy 1: Look for bundleURL()
|
|
188
|
+
// Strategy 1: Look for bundleURL()
|
|
208
189
|
const bundleURLPattern1 = /(func\s+bundleURL\s*\(\s*\)\s*->\s*URL\?\s*\{)([\s\S]*?)(\n\s*\})/;
|
|
209
190
|
|
|
210
191
|
if (bundleURLPattern1.test(contents)) {
|
|
@@ -227,7 +208,7 @@ ${funcBody}${funcEnd}${helperFunction}`;
|
|
|
227
208
|
return config;
|
|
228
209
|
}
|
|
229
210
|
|
|
230
|
-
// Strategy 2: Look for sourceURL(for bridge:)
|
|
211
|
+
// Strategy 2: Look for sourceURL(for bridge:)
|
|
231
212
|
const sourceURLPattern = /(func\s+sourceURL\s*\(\s*for\s+bridge\s*:\s*RCTBridge\s*\)\s*->\s*URL\?\s*\{)([\s\S]*?)(\n\s*\})/;
|
|
232
213
|
|
|
233
214
|
if (sourceURLPattern.test(contents)) {
|
package/lib/commonjs/index.js
CHANGED
package/lib/module/index.js
CHANGED
|
@@ -10,5 +10,5 @@ export { OTAApiClient, getDeviceInfo } from './utils/api';
|
|
|
10
10
|
export { UpdateStorage, getStorageAdapter } from './utils/storage';
|
|
11
11
|
export { calculateHash, verifyBundleHash, verifySignature, verifyBundle } from './utils/verification';
|
|
12
12
|
// Version info
|
|
13
|
-
export const VERSION = '0.2.
|
|
13
|
+
export const VERSION = '0.2.8';
|
|
14
14
|
//# sourceMappingURL=index.js.map
|
|
@@ -9,5 +9,5 @@ export { UpdateStorage, getStorageAdapter } from './utils/storage';
|
|
|
9
9
|
export type { StoredUpdate, StorageAdapter } from './utils/storage';
|
|
10
10
|
export { calculateHash, verifyBundleHash, verifySignature, verifyBundle, } from './utils/verification';
|
|
11
11
|
export type { VerificationResult } from './utils/verification';
|
|
12
|
-
export declare const VERSION = "0.2.
|
|
12
|
+
export declare const VERSION = "0.2.8";
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
package/package.json
CHANGED
package/src/index.ts
CHANGED