@bravemobile/react-native-code-push 12.1.0 → 12.1.2
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/README.md +23 -1
- package/app.plugin.js +1 -0
- package/cli/commands/initCommand/initAndroid.ts +52 -4
- package/cli/commands/initCommand/test/initAndroid.test.ts +42 -0
- package/cli/dist/commands/initCommand/initAndroid.js +40 -4
- package/cli/dist/commands/initCommand/test/initAndroid.test.js +38 -0
- package/expo/plugin/withCodePushAndroid.js +47 -14
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -146,7 +146,28 @@ Then, edit `AppDelegate.swift` like below.
|
|
|
146
146
|
|
|
147
147
|
#### Edit `MainApplication` Code
|
|
148
148
|
|
|
149
|
-
**If you have `MainApplication.kt
|
|
149
|
+
**(RN 0.82+) If you have `MainApplication.kt`**
|
|
150
|
+
|
|
151
|
+
```diff
|
|
152
|
+
+ import com.microsoft.codepush.react.CodePush
|
|
153
|
+
|
|
154
|
+
class MainApplication : Application(), ReactApplication {
|
|
155
|
+
override val reactHost: ReactHost by lazy {
|
|
156
|
+
getDefaultReactHost(
|
|
157
|
+
context = applicationContext,
|
|
158
|
+
packageList =
|
|
159
|
+
PackageList(this).packages.apply {
|
|
160
|
+
// Packages that cannot be autolinked yet can be added manually here, for example:
|
|
161
|
+
// add(MyReactNativePackage())
|
|
162
|
+
},
|
|
163
|
+
+ jsBundleFilePath = CodePush.getJSBundleFile(),
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
// ...
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**(RN 0.73+) If you have `MainApplication.kt`**
|
|
150
171
|
|
|
151
172
|
```diff
|
|
152
173
|
+ import com.microsoft.codepush.react.CodePush
|
|
@@ -163,6 +184,7 @@ Then, edit `AppDelegate.swift` like below.
|
|
|
163
184
|
}
|
|
164
185
|
```
|
|
165
186
|
|
|
187
|
+
|
|
166
188
|
**Or if you have `MainApplication.java`**
|
|
167
189
|
|
|
168
190
|
```diff
|
package/app.plugin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("./expo/plugin/withCodePush");
|
|
@@ -2,14 +2,62 @@ import path from "path";
|
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import { EOL } from "os";
|
|
4
4
|
|
|
5
|
+
const IMPORT_CODE_PUSH = 'import com.microsoft.codepush.react.CodePush';
|
|
6
|
+
const RN_LEGACY_MARKER = 'object : DefaultReactNativeHost(this)';
|
|
7
|
+
const RN_082_MARKER = ' getDefaultReactHost(';
|
|
8
|
+
|
|
5
9
|
export function modifyMainApplicationKt(mainApplicationContent: string) {
|
|
6
|
-
|
|
10
|
+
const hasCodePushImport = mainApplicationContent.includes(IMPORT_CODE_PUSH);
|
|
11
|
+
const hasGetJSBundleFileFn = mainApplicationContent.includes('CodePush.getJSBundleFile()');
|
|
12
|
+
|
|
13
|
+
if (hasCodePushImport && hasGetJSBundleFileFn) {
|
|
7
14
|
console.log('log: MainApplication.kt already has CodePush initialized.');
|
|
8
15
|
return mainApplicationContent;
|
|
9
16
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
17
|
+
|
|
18
|
+
let updatedContent = mainApplicationContent;
|
|
19
|
+
|
|
20
|
+
if (!hasCodePushImport) {
|
|
21
|
+
updatedContent = mainApplicationContent.replace('import com.facebook.react.ReactApplication', `import com.facebook.react.ReactApplication${EOL}${IMPORT_CODE_PUSH}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const isExtendingDefaultReactNativeHost = mainApplicationContent.includes(RN_LEGACY_MARKER);
|
|
25
|
+
|
|
26
|
+
// RN <0.82
|
|
27
|
+
if (isExtendingDefaultReactNativeHost) {
|
|
28
|
+
if (!hasGetJSBundleFileFn) {
|
|
29
|
+
updatedContent = updatedContent.replace('override fun getJSMainModuleName(): String = "index"', `override fun getJSMainModuleName(): String = "index"${EOL} override fun getJSBundleFile(): String = CodePush.getJSBundleFile()`);
|
|
30
|
+
}
|
|
31
|
+
return updatedContent;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// RN 0.82+
|
|
35
|
+
const isUsingGetDefaultReactHost = mainApplicationContent.includes(RN_082_MARKER);
|
|
36
|
+
if (isUsingGetDefaultReactHost) {
|
|
37
|
+
if (!hasGetJSBundleFileFn) {
|
|
38
|
+
return addJsBundleFilePathArgument(updatedContent);
|
|
39
|
+
}
|
|
40
|
+
return updatedContent;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
throw new Error('Unsupported MainApplication.kt structure.');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function addJsBundleFilePathArgument(mainApplicationContent: string) {
|
|
47
|
+
const packageListArgumentPattern = /(packageList\s*=\s*\n\s*PackageList\(this\)[\s\S]+?\},\s*\n)/;
|
|
48
|
+
|
|
49
|
+
if (!packageListArgumentPattern.test(mainApplicationContent)) {
|
|
50
|
+
console.log('log: Could not find packageList argument while updating MainApplication.kt.');
|
|
51
|
+
return mainApplicationContent;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return mainApplicationContent.replace(packageListArgumentPattern, (match) => {
|
|
55
|
+
if (match.includes('jsBundleFilePath')) {
|
|
56
|
+
return match;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return `${match} jsBundleFilePath = CodePush.getJSBundleFile(),${EOL}`;
|
|
60
|
+
});
|
|
13
61
|
}
|
|
14
62
|
|
|
15
63
|
export async function initAndroid() {
|
|
@@ -47,6 +47,37 @@ class MainApplication : Application(), ReactApplication {
|
|
|
47
47
|
}
|
|
48
48
|
`;
|
|
49
49
|
|
|
50
|
+
// https://github.com/react-native-community/template/blob/0.82.1/template/android/app/src/main/java/com/helloworld/MainApplication.kt
|
|
51
|
+
const ktRN82Template = `
|
|
52
|
+
package com.helloworld
|
|
53
|
+
|
|
54
|
+
import android.app.Application
|
|
55
|
+
import com.facebook.react.PackageList
|
|
56
|
+
import com.facebook.react.ReactApplication
|
|
57
|
+
import com.facebook.react.ReactHost
|
|
58
|
+
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
|
|
59
|
+
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
|
|
60
|
+
|
|
61
|
+
class MainApplication : Application(), ReactApplication {
|
|
62
|
+
|
|
63
|
+
override val reactHost: ReactHost by lazy {
|
|
64
|
+
getDefaultReactHost(
|
|
65
|
+
context = applicationContext,
|
|
66
|
+
packageList =
|
|
67
|
+
PackageList(this).packages.apply {
|
|
68
|
+
// Packages that cannot be autolinked yet can be added manually here, for example:
|
|
69
|
+
// add(MyReactNativePackage())
|
|
70
|
+
},
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
override fun onCreate() {
|
|
75
|
+
super.onCreate()
|
|
76
|
+
loadReactNative(this)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
`;
|
|
80
|
+
|
|
50
81
|
describe('Android init command', () => {
|
|
51
82
|
it('should correctly modify Kotlin MainApplication content', () => {
|
|
52
83
|
const modifiedContent = modifyMainApplicationKt(ktTemplate);
|
|
@@ -54,6 +85,17 @@ describe('Android init command', () => {
|
|
|
54
85
|
expect(modifiedContent).toContain('override fun getJSBundleFile(): String = CodePush.getJSBundleFile()');
|
|
55
86
|
});
|
|
56
87
|
|
|
88
|
+
it('should insert jsBundleFilePath argument for RN 0.82 style MainApplication', () => {
|
|
89
|
+
const modifiedContent = modifyMainApplicationKt(ktRN82Template);
|
|
90
|
+
|
|
91
|
+
expect(modifiedContent).toContain('import com.microsoft.codepush.react.CodePush');
|
|
92
|
+
expect(modifiedContent).toContain('jsBundleFilePath = CodePush.getJSBundleFile()');
|
|
93
|
+
|
|
94
|
+
const packageListIndex = modifiedContent.indexOf('packageList =');
|
|
95
|
+
const jsBundleIndex = modifiedContent.indexOf('jsBundleFilePath = CodePush.getJSBundleFile()');
|
|
96
|
+
expect(jsBundleIndex).toBeGreaterThan(packageListIndex);
|
|
97
|
+
});
|
|
98
|
+
|
|
57
99
|
it('should log a message and exit if MainApplication.java is found', async () => {
|
|
58
100
|
const originalCwd = process.cwd();
|
|
59
101
|
|
|
@@ -1,14 +1,50 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import { EOL } from "os";
|
|
4
|
+
const IMPORT_CODE_PUSH = 'import com.microsoft.codepush.react.CodePush';
|
|
5
|
+
const RN_LEGACY_MARKER = 'object : DefaultReactNativeHost(this)';
|
|
6
|
+
const RN_082_MARKER = ' getDefaultReactHost(';
|
|
4
7
|
export function modifyMainApplicationKt(mainApplicationContent) {
|
|
5
|
-
|
|
8
|
+
const hasCodePushImport = mainApplicationContent.includes(IMPORT_CODE_PUSH);
|
|
9
|
+
const hasGetJSBundleFileFn = mainApplicationContent.includes('CodePush.getJSBundleFile()');
|
|
10
|
+
if (hasCodePushImport && hasGetJSBundleFileFn) {
|
|
6
11
|
console.log('log: MainApplication.kt already has CodePush initialized.');
|
|
7
12
|
return mainApplicationContent;
|
|
8
13
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
.replace('
|
|
14
|
+
let updatedContent = mainApplicationContent;
|
|
15
|
+
if (!hasCodePushImport) {
|
|
16
|
+
updatedContent = mainApplicationContent.replace('import com.facebook.react.ReactApplication', `import com.facebook.react.ReactApplication${EOL}${IMPORT_CODE_PUSH}`);
|
|
17
|
+
}
|
|
18
|
+
const isExtendingDefaultReactNativeHost = mainApplicationContent.includes(RN_LEGACY_MARKER);
|
|
19
|
+
// RN <0.82
|
|
20
|
+
if (isExtendingDefaultReactNativeHost) {
|
|
21
|
+
if (!hasGetJSBundleFileFn) {
|
|
22
|
+
updatedContent = updatedContent.replace('override fun getJSMainModuleName(): String = "index"', `override fun getJSMainModuleName(): String = "index"${EOL} override fun getJSBundleFile(): String = CodePush.getJSBundleFile()`);
|
|
23
|
+
}
|
|
24
|
+
return updatedContent;
|
|
25
|
+
}
|
|
26
|
+
// RN 0.82+
|
|
27
|
+
const isUsingGetDefaultReactHost = mainApplicationContent.includes(RN_082_MARKER);
|
|
28
|
+
if (isUsingGetDefaultReactHost) {
|
|
29
|
+
if (!hasGetJSBundleFileFn) {
|
|
30
|
+
return addJsBundleFilePathArgument(updatedContent);
|
|
31
|
+
}
|
|
32
|
+
return updatedContent;
|
|
33
|
+
}
|
|
34
|
+
throw new Error('Unsupported MainApplication.kt structure.');
|
|
35
|
+
}
|
|
36
|
+
function addJsBundleFilePathArgument(mainApplicationContent) {
|
|
37
|
+
const packageListArgumentPattern = /(packageList\s*=\s*\n\s*PackageList\(this\)[\s\S]+?\},\s*\n)/;
|
|
38
|
+
if (!packageListArgumentPattern.test(mainApplicationContent)) {
|
|
39
|
+
console.log('log: Could not find packageList argument while updating MainApplication.kt.');
|
|
40
|
+
return mainApplicationContent;
|
|
41
|
+
}
|
|
42
|
+
return mainApplicationContent.replace(packageListArgumentPattern, (match) => {
|
|
43
|
+
if (match.includes('jsBundleFilePath')) {
|
|
44
|
+
return match;
|
|
45
|
+
}
|
|
46
|
+
return `${match} jsBundleFilePath = CodePush.getJSBundleFile(),${EOL}`;
|
|
47
|
+
});
|
|
12
48
|
}
|
|
13
49
|
export async function initAndroid() {
|
|
14
50
|
console.log('log: Running Android setup...');
|
|
@@ -44,12 +44,50 @@ class MainApplication : Application(), ReactApplication {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
`;
|
|
47
|
+
// https://github.com/react-native-community/template/blob/0.82.1/template/android/app/src/main/java/com/helloworld/MainApplication.kt
|
|
48
|
+
const ktRN82Template = `
|
|
49
|
+
package com.helloworld
|
|
50
|
+
|
|
51
|
+
import android.app.Application
|
|
52
|
+
import com.facebook.react.PackageList
|
|
53
|
+
import com.facebook.react.ReactApplication
|
|
54
|
+
import com.facebook.react.ReactHost
|
|
55
|
+
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
|
|
56
|
+
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
|
|
57
|
+
|
|
58
|
+
class MainApplication : Application(), ReactApplication {
|
|
59
|
+
|
|
60
|
+
override val reactHost: ReactHost by lazy {
|
|
61
|
+
getDefaultReactHost(
|
|
62
|
+
context = applicationContext,
|
|
63
|
+
packageList =
|
|
64
|
+
PackageList(this).packages.apply {
|
|
65
|
+
// Packages that cannot be autolinked yet can be added manually here, for example:
|
|
66
|
+
// add(MyReactNativePackage())
|
|
67
|
+
},
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
override fun onCreate() {
|
|
72
|
+
super.onCreate()
|
|
73
|
+
loadReactNative(this)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
`;
|
|
47
77
|
describe('Android init command', () => {
|
|
48
78
|
it('should correctly modify Kotlin MainApplication content', () => {
|
|
49
79
|
const modifiedContent = modifyMainApplicationKt(ktTemplate);
|
|
50
80
|
expect(modifiedContent).toContain('import com.microsoft.codepush.react.CodePush');
|
|
51
81
|
expect(modifiedContent).toContain('override fun getJSBundleFile(): String = CodePush.getJSBundleFile()');
|
|
52
82
|
});
|
|
83
|
+
it('should insert jsBundleFilePath argument for RN 0.82 style MainApplication', () => {
|
|
84
|
+
const modifiedContent = modifyMainApplicationKt(ktRN82Template);
|
|
85
|
+
expect(modifiedContent).toContain('import com.microsoft.codepush.react.CodePush');
|
|
86
|
+
expect(modifiedContent).toContain('jsBundleFilePath = CodePush.getJSBundleFile()');
|
|
87
|
+
const packageListIndex = modifiedContent.indexOf('packageList =');
|
|
88
|
+
const jsBundleIndex = modifiedContent.indexOf('jsBundleFilePath = CodePush.getJSBundleFile()');
|
|
89
|
+
expect(jsBundleIndex).toBeGreaterThan(packageListIndex);
|
|
90
|
+
});
|
|
53
91
|
it('should log a message and exit if MainApplication.java is found', async () => {
|
|
54
92
|
const originalCwd = process.cwd();
|
|
55
93
|
fs.mkdirSync(tempDir, { recursive: true });
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
const { withMainApplication, WarningAggregator } = require('expo/config-plugins');
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
) {
|
|
3
|
+
const IMPORT_CODE_PUSH = 'import com.microsoft.codepush.react.CodePush';
|
|
4
|
+
const RN_082_MARKER = ' getDefaultReactHost(';
|
|
5
|
+
const JS_BUNDLE_FILE_PATH_ARGUMENT = 'jsBundleFilePath = CodePush.getJSBundleFile()';
|
|
6
|
+
|
|
7
|
+
function androidMainApplicationApplyImplementation(mainApplication, find, add, reverse = false) {
|
|
9
8
|
if (mainApplication.includes(add)) {
|
|
10
9
|
return mainApplication;
|
|
11
10
|
}
|
|
@@ -28,20 +27,54 @@ function androidMainApplicationApplyImplementation(
|
|
|
28
27
|
return mainApplication;
|
|
29
28
|
}
|
|
30
29
|
|
|
30
|
+
function addJsBundleFilePathArgument(mainApplication) {
|
|
31
|
+
if (mainApplication.includes(JS_BUNDLE_FILE_PATH_ARGUMENT)) {
|
|
32
|
+
return mainApplication;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const packageListArgumentPattern = /(packageList\s*=\s*\n\s*PackageList\(this\)[\s\S]+?\},\s*\n)/;
|
|
36
|
+
|
|
37
|
+
if (!packageListArgumentPattern.test(mainApplication)) {
|
|
38
|
+
WarningAggregator.addWarningAndroid(
|
|
39
|
+
'withCodePushAndroid',
|
|
40
|
+
`
|
|
41
|
+
Failed to detect "packageList = PackageList(this)" block in MainApplication.kt.
|
|
42
|
+
Please add "jsBundleFilePath = CodePush.getJSBundleFile()" inside getDefaultReactHost arguments.
|
|
43
|
+
|
|
44
|
+
Android manual setup: https://github.com/Soomgo-Mobile/react-native-code-push#2-1-manual-setup
|
|
45
|
+
`,
|
|
46
|
+
);
|
|
47
|
+
return mainApplication;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return mainApplication.replace(packageListArgumentPattern, (match) => {
|
|
51
|
+
if (match.includes('jsBundleFilePath')) {
|
|
52
|
+
return match;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return `${match} ${JS_BUNDLE_FILE_PATH_ARGUMENT},\n`;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
31
59
|
const withAndroidMainApplicationDependency = (config) => {
|
|
32
60
|
return withMainApplication(config, (action) => {
|
|
33
61
|
action.modResults.contents = androidMainApplicationApplyImplementation(
|
|
34
62
|
action.modResults.contents,
|
|
35
|
-
'
|
|
36
|
-
|
|
37
|
-
true,
|
|
63
|
+
'import com.facebook.react.ReactApplication',
|
|
64
|
+
IMPORT_CODE_PUSH,
|
|
38
65
|
);
|
|
39
66
|
|
|
40
|
-
action.modResults.contents
|
|
41
|
-
action.modResults.contents
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
67
|
+
if (!action.modResults.contents.includes('CodePush.getJSBundleFile()')) {
|
|
68
|
+
if (action.modResults.contents.includes(RN_082_MARKER)) {
|
|
69
|
+
action.modResults.contents = addJsBundleFilePathArgument(action.modResults.contents);
|
|
70
|
+
} else {
|
|
71
|
+
action.modResults.contents = androidMainApplicationApplyImplementation(
|
|
72
|
+
action.modResults.contents,
|
|
73
|
+
'object : DefaultReactNativeHost(this) {',
|
|
74
|
+
' override fun getJSBundleFile(): String = CodePush.getJSBundleFile()\n');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
45
78
|
return action;
|
|
46
79
|
});
|
|
47
80
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bravemobile/react-native-code-push",
|
|
3
|
-
"version": "12.1.
|
|
3
|
+
"version": "12.1.2",
|
|
4
4
|
"description": "React Native plugin for the CodePush service",
|
|
5
5
|
"main": "src/CodePush.js",
|
|
6
6
|
"react-native": "src/CodePush.js",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"typings",
|
|
37
37
|
"*.podspec",
|
|
38
38
|
"react-native.config.js",
|
|
39
|
+
"app.plugin.js",
|
|
39
40
|
"package.json",
|
|
40
|
-
"package-lock.json",
|
|
41
41
|
"!ios/build",
|
|
42
42
|
"!android/build",
|
|
43
43
|
"!android/app/build",
|