@bravemobile/react-native-code-push 8.2.5 → 8.3.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.
@@ -0,0 +1,94 @@
1
+ trigger:
2
+ - master
3
+
4
+ pr:
5
+ - master
6
+
7
+ variables:
8
+ - name: api-level
9
+ value: '27'
10
+
11
+ pool:
12
+ vmImage: 'macOS-12'
13
+
14
+ stages:
15
+ - stage: RunTests
16
+ displayName: 'Run Android & IOS tests'
17
+ jobs:
18
+ - job: TestAndroid
19
+ timeoutInMinutes: 120
20
+ displayName: 'Test android'
21
+ steps:
22
+
23
+ - script: |
24
+ adb devices
25
+ displayName: 'Start adb server'
26
+
27
+ - script: |
28
+ $ANDROID_HOME/tools/bin/sdkmanager "system-images;android-$(api-level);google_apis;x86"
29
+ displayName: 'Download system image'
30
+
31
+ - script: |
32
+ $ANDROID_HOME/tools/bin/avdmanager create avd --force --name TestEmulator --abi google_apis/x86 --package 'system-images;android-$(api-level);google_apis;x86' --device "Nexus 6P"
33
+ displayName: 'Creating Android emulator'
34
+
35
+ - script: |
36
+ $ANDROID_HOME/emulator/emulator -avd TestEmulator -noaudio -no-window -no-snapshot-save -no-boot-anim -memory 6144 &
37
+ displayName: 'Start Android emulator'
38
+
39
+ - script: |
40
+ $ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done'
41
+ displayName: 'Wait for emulator to boot'
42
+
43
+ - script: |
44
+ adb shell settings put global window_animation_scale 0.0
45
+ displayName: 'Disable animations and transitions'
46
+
47
+ - script: |
48
+ adb shell settings put global transition_animation_scale 0.0
49
+ displayName: 'Disable animations and transitions'
50
+
51
+ - script: |
52
+ adb shell settings put global animator_duration_scale 0.0
53
+ displayName: 'Disable animations and transitions'
54
+
55
+
56
+ - task: JavaToolInstaller@0
57
+ inputs:
58
+ versionSpec: '11'
59
+ jdkArchitectureOption: 'x64'
60
+ jdkSourceOption: 'PreInstalled'
61
+ displayName: 'Change Java version'
62
+
63
+ - script: |
64
+ npm install
65
+ displayName: 'Package Installation'
66
+
67
+ - script: |
68
+ npm run build:tests && npm run test:setup:android
69
+ displayName: 'Setup Android tests'
70
+
71
+ - script: |
72
+ npm run test:fast:android
73
+ displayName: 'Run Android test'
74
+
75
+ - job: TestIOS
76
+ timeoutInMinutes: 120
77
+ displayName: 'Test IOS'
78
+ steps:
79
+
80
+ - script: |
81
+ npm install
82
+ displayName: 'Install dependencies'
83
+
84
+ - script: |
85
+ npm run build:tests && npm run test:setup:ios
86
+ displayName: 'Setup iOS tests'
87
+
88
+ - script: |
89
+ npm run test:fast:ios
90
+ displayName: 'Run tests'
91
+
92
+
93
+
94
+
package/CodePush.js CHANGED
@@ -625,42 +625,41 @@ function codePushify(options = {}) {
625
625
  sharedCodePushOptions.setUpdateChecker(options.updateChecker);
626
626
  sharedCodePushOptions.setFallbackToAppCenter(options.fallbackToAppCenter);
627
627
 
628
- var decorator = (RootComponent) => {
629
- const extended = class CodePushComponent extends React.Component {
628
+ const decorator = (RootComponent) => {
629
+ class CodePushComponent extends React.Component {
630
+ constructor(props) {
631
+ super(props);
632
+ this.rootComponentRef = React.createRef();
633
+ }
634
+
630
635
  componentDidMount() {
631
636
  if (options.checkFrequency === CodePush.CheckFrequency.MANUAL) {
632
637
  CodePush.notifyAppReady();
633
638
  } else {
634
- let rootComponentInstance = this.refs.rootComponent;
639
+ const rootComponentInstance = this.rootComponentRef.current;
635
640
 
636
641
  let syncStatusCallback;
637
642
  if (rootComponentInstance && rootComponentInstance.codePushStatusDidChange) {
638
- syncStatusCallback = rootComponentInstance.codePushStatusDidChange;
639
- if (rootComponentInstance instanceof React.Component) {
640
- syncStatusCallback = syncStatusCallback.bind(rootComponentInstance);
641
- }
643
+ syncStatusCallback = rootComponentInstance.codePushStatusDidChange.bind(rootComponentInstance);
642
644
  }
643
645
 
644
646
  let downloadProgressCallback;
645
647
  if (rootComponentInstance && rootComponentInstance.codePushDownloadDidProgress) {
646
- downloadProgressCallback = rootComponentInstance.codePushDownloadDidProgress;
647
- if (rootComponentInstance instanceof React.Component) {
648
- downloadProgressCallback = downloadProgressCallback.bind(rootComponentInstance);
649
- }
648
+ downloadProgressCallback = rootComponentInstance.codePushDownloadDidProgress.bind(rootComponentInstance);
650
649
  }
651
650
 
652
651
  let handleBinaryVersionMismatchCallback;
653
652
  if (rootComponentInstance && rootComponentInstance.codePushOnBinaryVersionMismatch) {
654
- handleBinaryVersionMismatchCallback = rootComponentInstance.codePushOnBinaryVersionMismatch;
655
- if (rootComponentInstance instanceof React.Component) {
656
- handleBinaryVersionMismatchCallback = handleBinaryVersionMismatchCallback.bind(rootComponentInstance);
657
- }
653
+ handleBinaryVersionMismatchCallback = rootComponentInstance.codePushOnBinaryVersionMismatch.bind(rootComponentInstance);
658
654
  }
659
655
 
660
656
  CodePush.sync(options, syncStatusCallback, downloadProgressCallback, handleBinaryVersionMismatchCallback);
657
+
661
658
  if (options.checkFrequency === CodePush.CheckFrequency.ON_APP_RESUME) {
662
659
  ReactNative.AppState.addEventListener("change", (newState) => {
663
- newState === "active" && CodePush.sync(options, syncStatusCallback, downloadProgressCallback);
660
+ if (newState === "active") {
661
+ CodePush.sync(options, syncStatusCallback, downloadProgressCallback);
662
+ }
664
663
  });
665
664
  }
666
665
  }
@@ -669,17 +668,17 @@ function codePushify(options = {}) {
669
668
  render() {
670
669
  const props = {...this.props};
671
670
 
672
- // we can set ref property on class components only (not stateless)
673
- // check it by render method
674
- if (RootComponent.prototype.render) {
675
- props.ref = "rootComponent";
671
+ // We can set ref property on class components only (not stateless)
672
+ // Check it by render method
673
+ if (RootComponent.prototype && RootComponent.prototype.render) {
674
+ props.ref = this.rootComponentRef;
676
675
  }
677
676
 
678
677
  return <RootComponent {...props} />
679
678
  }
680
679
  }
681
680
 
682
- return hoistStatics(extended, RootComponent);
681
+ return hoistStatics(CodePushComponent, RootComponent);
683
682
  }
684
683
 
685
684
  if (typeof options === "function") {
@@ -0,0 +1,10 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
+ package="com.microsoft.codepush.react">
3
+
4
+ <uses-permission android:name="android.permission.INTERNET" />
5
+
6
+ <application>
7
+ <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
8
+ </application>
9
+
10
+ </manifest>
@@ -3,8 +3,4 @@
3
3
 
4
4
  <uses-permission android:name="android.permission.INTERNET" />
5
5
 
6
- <application>
7
- <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
8
- </application>
9
-
10
- </manifest>
6
+ </manifest>
@@ -98,7 +98,7 @@ public class CodePushUpdateUtils {
98
98
  }
99
99
 
100
100
  public static void copyNecessaryFilesFromCurrentPackage(String diffManifestFilePath, String currentPackageFolderPath, String newPackageFolderPath) throws IOException {
101
- FileUtils.copyDirectoryContents(currentPackageFolderPath, newPackageFolderPath);
101
+ FileUtils.copyDirectoryContents(currentPackageFolderPath, newPackageFolderPath);
102
102
  JSONObject diffManifest = CodePushUtils.getJsonObjectFromFile(diffManifestFilePath);
103
103
  try {
104
104
  JSONArray deletedFiles = diffManifest.getJSONArray("deletedFiles");
@@ -67,7 +67,9 @@ public class CodePushUtils {
67
67
  String key = it.next();
68
68
  Object obj = null;
69
69
  try {
70
- obj = jsonObj.get(key);
70
+ if (!jsonObj.isNull(key)) {
71
+ obj = jsonObj.get(key);
72
+ }
71
73
  } catch (JSONException jsonException) {
72
74
  // Should not happen.
73
75
  throw new CodePushUnknownException("Key " + key + " should exist in " + jsonObj.toString() + ".", jsonException);
@@ -2,8 +2,8 @@
2
2
 
3
3
  import java.nio.file.Paths;
4
4
 
5
- def config = project.extensions.findByName("react") ?: []
6
- def bundleAssetName = config.bundleAssetName.get() ?: "index.android.bundle"
5
+ def config = project.extensions.findByName("react") ?: [:]
6
+ def bundleAssetName = config.bundleAssetName ? config.bundleAssetName.get() : "index.android.bundle"
7
7
 
8
8
  // because elvis operator
9
9
  def elvisFile(thing) {
@@ -17,6 +17,41 @@ void runBefore(String dependentTaskName, Task task) {
17
17
  }
18
18
  }
19
19
 
20
+ /**
21
+ * Finds the path of the installed npm package with the given name using Node's
22
+ * module resolution algorithm, which searches "node_modules" directories up to
23
+ * the file system root. This handles various cases, including:
24
+ *
25
+ * - Working in the open-source RN repo:
26
+ * Gradle: /path/to/react-native/ReactAndroid
27
+ * Node module: /path/to/react-native/node_modules/[package]
28
+ *
29
+ * - Installing RN as a dependency of an app and searching for hoisted
30
+ * dependencies:
31
+ * Gradle: /path/to/app/node_modules/react-native/ReactAndroid
32
+ * Node module: /path/to/app/node_modules/[package]
33
+ *
34
+ * - Working in a larger repo (e.g., Facebook) that contains RN:
35
+ * Gradle: /path/to/repo/path/to/react-native/ReactAndroid
36
+ * Node module: /path/to/repo/node_modules/[package]
37
+ *
38
+ * The search begins at the given base directory (a File object). The returned
39
+ * path is a string.
40
+ */
41
+ static def findNodeModulePath(baseDir, packageName) {
42
+ def basePath = baseDir.toPath().normalize()
43
+ // Node's module resolution algorithm searches up to the root directory,
44
+ // after which the base path will be null
45
+ while (basePath) {
46
+ def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName)
47
+ if (candidatePath.toFile().exists()) {
48
+ return candidatePath.toString()
49
+ }
50
+ basePath = basePath.getParent()
51
+ }
52
+ return null
53
+ }
54
+
20
55
  android.buildTypes.each { buildType ->
21
56
  // to prevent incorrect long value restoration from strings.xml we need to wrap it with double quotes
22
57
  // https://github.com/microsoft/cordova-plugin-code-push/issues/264
@@ -24,7 +59,7 @@ android.buildTypes.each { buildType ->
24
59
  }
25
60
 
26
61
  gradle.projectsEvaluated {
27
- def debuggableVariants = config.debuggableVariants.get() ?: ['debug']
62
+ def debuggableVariants = config.debuggableVariants ? config.debuggableVariants.get() : ['debug']
28
63
 
29
64
  android.applicationVariants.all { variant ->
30
65
  // No code push for debuggable variants
@@ -34,11 +69,9 @@ gradle.projectsEvaluated {
34
69
 
35
70
  def nodeModulesPath;
36
71
  if (project.hasProperty('nodeModulesPath')) {
37
- nodeModulesPath = project.nodeModulesPath
38
- } else if (config.root) {
39
- nodeModulesPath = Paths.get(config.root.asFile.get().absolutePath, "/node_modules");
72
+ nodeModulesPath = "${project.nodeModulesPath}/react-native-code-push"
40
73
  } else {
41
- nodeModulesPath = "../../node_modules";
74
+ nodeModulesPath = findNodeModulePath(projectDir, "react-native-code-push")
42
75
  }
43
76
 
44
77
  def targetName = variant.name.capitalize()
@@ -49,8 +82,8 @@ gradle.projectsEvaluated {
49
82
  def jsBundleFile;
50
83
 
51
84
  // Additional node commandline arguments
52
- def nodeExecutableAndArgs = config.nodeExecutableAndArgs.get() ?: ["node"]
53
- def extraPackagerArgs = config.extraPackagerArgs.get() ?: []
85
+ def nodeExecutableAndArgs = config.nodeExecutableAndArgs ? config.nodeExecutableAndArgs.get(): ["node"]
86
+ def extraPackagerArgs = config.extraPackagerArgs ? config.extraPackagerArgs.get() : []
54
87
 
55
88
  // Make this task run right after the bundle task
56
89
  def generateBundledResourcesHash;
@@ -59,6 +92,9 @@ gradle.projectsEvaluated {
59
92
  if (reactBundleTask) {
60
93
  jsBundleDir = reactBundleTask.property('jsBundleDir').asFile.get()
61
94
  resourcesDir = reactBundleTask.property('resourcesDir').asFile.get()
95
+
96
+ // mitigates Resource and asset merger: Duplicate resources error
97
+ project.delete(files("${jsBundleDir}"))
62
98
 
63
99
  jsBundleDir.mkdirs()
64
100
  resourcesDir.mkdirs()
@@ -68,7 +104,7 @@ gradle.projectsEvaluated {
68
104
  generateBundledResourcesHash = tasks.create(
69
105
  name: "generateBundledResourcesHash${targetName}",
70
106
  type: Exec) {
71
- commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/react-native-code-push/scripts/generateBundledResourcesHash.js", resourcesDir, jsBundleFile, jsBundleDir)
107
+ commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/scripts/generateBundledResourcesHash.js", resourcesDir, jsBundleFile, jsBundleDir)
72
108
 
73
109
  enabled !debuggableVariants.contains(variant.name) ?: targetName.toLowerCase().contains("release")
74
110
  }
@@ -77,11 +113,11 @@ gradle.projectsEvaluated {
77
113
  runBefore("merge${targetName}Assets", generateBundledResourcesHash)
78
114
  } else {
79
115
  def jsBundleDirConfigName = "jsBundleDir${targetName}"
80
- jsBundleDir = elvisFile(config."$jsBundleDirConfigName").get() ?:
116
+ jsBundleDir = elvisFile(config."$jsBundleDirConfigName") ? elvisFile(config."$jsBundleDirConfigName").get():
81
117
  file("$buildDir/intermediates/assets/${targetPath}")
82
118
 
83
119
  def resourcesDirConfigName = "resourcesDir${targetName}"
84
- resourcesDir = elvisFile(config."${resourcesDirConfigName}").get() ?:
120
+ resourcesDir = elvisFile(config."${resourcesDirConfigName}") ? elvisFile(config."${resourcesDirConfigName}").get():
85
121
  file("$buildDir/intermediates/res/merged/${targetPath}")
86
122
 
87
123
  // In case version of 'Android Plugin for Gradle'' is lower than 1.3.0
@@ -98,14 +134,14 @@ gradle.projectsEvaluated {
98
134
  generateBundledResourcesHash = tasks.create(
99
135
  name: "generateBundledResourcesHash${targetName}",
100
136
  type: Exec) {
101
- commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/react-native-code-push/scripts/generateBundledResourcesHash.js", resourcesDir, jsBundleFile, jsBundleDir, resourcesMapTempFileName)
137
+ commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/scripts/generateBundledResourcesHash.js", resourcesDir, jsBundleFile, jsBundleDir, resourcesMapTempFileName)
102
138
  }
103
139
 
104
140
  // Make this task run right before the bundle task
105
141
  def recordFilesBeforeBundleCommand = tasks.create(
106
142
  name: "recordFilesBeforeBundleCommand${targetName}",
107
143
  type: Exec) {
108
- commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/react-native-code-push/scripts/recordFilesBeforeBundleCommand.js", resourcesDir, resourcesMapTempFileName)
144
+ commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/scripts/recordFilesBeforeBundleCommand.js", resourcesDir, resourcesMapTempFileName)
109
145
  }
110
146
 
111
147
  recordFilesBeforeBundleCommand.dependsOn("merge${targetName}Resources")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bravemobile/react-native-code-push",
3
- "version": "8.2.5",
3
+ "version": "8.3.1",
4
4
  "description": "React Native plugin for the CodePush service",
5
5
  "main": "CodePush.js",
6
6
  "typings": "typings/react-native-code-push.d.ts",
@@ -36,7 +36,7 @@
36
36
  "url": "https://github.com/Soomgo-Mobile/react-native-code-push"
37
37
  },
38
38
  "dependencies": {
39
- "code-push": "^4.2.1",
39
+ "code-push": "^4.2.2",
40
40
  "glob": "^7.1.7",
41
41
  "hoist-non-react-statics": "^3.3.2",
42
42
  "inquirer": "^8.1.5",