mirror of
https://gitcode.com/gh_mirrors/re/react-native-pushy.git
synced 2025-11-22 23:46:10 +08:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57206dd2f1 | ||
|
|
4e27d906c3 | ||
|
|
c24f469475 | ||
|
|
8f8a29eda8 | ||
|
|
a78542b214 | ||
|
|
8d9ae57a5f | ||
|
|
2502935fc0 | ||
|
|
8e6d9bf460 | ||
|
|
897f334343 | ||
|
|
33bc69c3fb | ||
|
|
5028ce31be | ||
|
|
d3a4007763 | ||
|
|
a4f3e3cc38 | ||
|
|
9d51128ed3 | ||
|
|
eddb072927 | ||
|
|
4f9417d620 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -52,3 +52,8 @@ Example/testHotUpdate/harmony
|
|||||||
Example/testHotUpdate/android/app/.cxx
|
Example/testHotUpdate/android/app/.cxx
|
||||||
Example/harmony_use_pushy/libs
|
Example/harmony_use_pushy/libs
|
||||||
**/mcp.json
|
**/mcp.json
|
||||||
|
|
||||||
|
|
||||||
|
harmony/package
|
||||||
|
**/oh_modules
|
||||||
|
harmony/pushy/.preview
|
||||||
|
|||||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -4,9 +4,3 @@
|
|||||||
[submodule "android/jni/HDiffPatch"]
|
[submodule "android/jni/HDiffPatch"]
|
||||||
path = android/jni/HDiffPatch
|
path = android/jni/HDiffPatch
|
||||||
url = https://github.com/sisong/HDiffPatch.git
|
url = https://github.com/sisong/HDiffPatch.git
|
||||||
[submodule "harmony/src/main/cpp/HDiffPatch"]
|
|
||||||
path = harmony/src/main/cpp/HDiffPatch
|
|
||||||
url = https://github.com/sisong/HDiffPatch.git
|
|
||||||
[submodule "harmony/src/main/cpp/lzma"]
|
|
||||||
path = harmony/src/main/cpp/lzma
|
|
||||||
url = https://github.com/sisong/lzma.git
|
|
||||||
|
|||||||
@@ -1,41 +1,49 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
app: {
|
||||||
"signingConfigs": [],
|
signingConfigs: [],
|
||||||
"products": [
|
products: [
|
||||||
{
|
{
|
||||||
"name": "default",
|
name: 'default',
|
||||||
"signingConfig": "default",
|
signingConfig: 'default',
|
||||||
"compatibleSdkVersion": "5.0.0(12)",
|
compatibleSdkVersion: '5.0.0(12)',
|
||||||
"runtimeOS": "HarmonyOS",
|
runtimeOS: 'HarmonyOS',
|
||||||
"buildOption": {
|
buildOption: {
|
||||||
"strictMode": {
|
strictMode: {
|
||||||
"caseSensitiveCheck": true,
|
caseSensitiveCheck: true,
|
||||||
"useNormalizedOHMUrl": true
|
useNormalizedOHMUrl: true,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"buildModeSet": [
|
buildModeSet: [
|
||||||
{
|
{
|
||||||
"name": "debug",
|
name: 'debug',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "release"
|
name: 'release',
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"modules": [
|
],
|
||||||
|
},
|
||||||
|
modules: [
|
||||||
{
|
{
|
||||||
"name": "entry",
|
name: 'entry',
|
||||||
"srcPath": "./entry",
|
srcPath: './entry',
|
||||||
"targets": [
|
targets: [
|
||||||
{
|
{
|
||||||
"name": "default",
|
name: 'default',
|
||||||
"applyToProducts": [
|
applyToProducts: ['default'],
|
||||||
"default"
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
]
|
{
|
||||||
}
|
name: 'pushy',
|
||||||
]
|
srcPath: '../../../harmony/pushy',
|
||||||
|
targets: [
|
||||||
|
{
|
||||||
|
name: 'default',
|
||||||
|
applyToProducts: ['default'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
}
|
}
|
||||||
@@ -1,25 +1,26 @@
|
|||||||
{
|
{
|
||||||
"meta": {
|
"meta": {
|
||||||
"stableOrder": true
|
"stableOrder": true,
|
||||||
|
"enableUnifiedLockfile": false
|
||||||
},
|
},
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
|
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
|
||||||
"specifiers": {
|
"specifiers": {
|
||||||
"@rnoh/react-native-openharmony@0.72.38": "@rnoh/react-native-openharmony@0.72.38",
|
"@rnoh/react-native-openharmony@0.72.38": "@rnoh/react-native-openharmony@0.72.38",
|
||||||
"pushy@../../node_modules/react-native-update/harmony": "pushy@../../node_modules/react-native-update/harmony"
|
"pushy@../../node_modules/react-native-update/harmony/pushy": "pushy@../../node_modules/react-native-update/harmony/pushy"
|
||||||
},
|
},
|
||||||
"packages": {
|
"packages": {
|
||||||
"@rnoh/react-native-openharmony@0.72.38": {
|
"@rnoh/react-native-openharmony@0.72.38": {
|
||||||
"name": "@rnoh/react-native-openharmony",
|
"name": "",
|
||||||
"version": "0.72.38",
|
"version": "0.72.38",
|
||||||
"integrity": "sha512-br5SIrbB0OarSLirenleE7eTOX1lNccMJ7nb/G7qWTyJ7kW4DalmTXVKYpoT2qaOLls1uEE7McD1OjbZZM9jug==",
|
"integrity": "sha512-br5SIrbB0OarSLirenleE7eTOX1lNccMJ7nb/G7qWTyJ7kW4DalmTXVKYpoT2qaOLls1uEE7McD1OjbZZM9jug==",
|
||||||
"resolved": "https://ohpm.openharmony.cn/ohpm/@rnoh/react-native-openharmony/-/react-native-openharmony-0.72.38.har",
|
"resolved": "https://ohpm.openharmony.cn/ohpm/@rnoh/react-native-openharmony/-/react-native-openharmony-0.72.38.har",
|
||||||
"registryType": "ohpm"
|
"registryType": "ohpm"
|
||||||
},
|
},
|
||||||
"pushy@../../node_modules/react-native-update/harmony": {
|
"pushy@../../node_modules/react-native-update/harmony/pushy": {
|
||||||
"name": "pushy",
|
"name": "pushy",
|
||||||
"version": "3.1.0-0.0.7",
|
"version": "3.1.0-0.0.7",
|
||||||
"resolved": "../../node_modules/react-native-update/harmony",
|
"resolved": "",
|
||||||
"registryType": "local",
|
"registryType": "local",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rnoh/react-native-openharmony": "^0.72.38"
|
"@rnoh/react-native-openharmony": "^0.72.38"
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "entry",
|
name: 'entry',
|
||||||
"version": "1.0.0",
|
version: '1.0.0',
|
||||||
"description": "Please describe the basic information.",
|
description: 'Please describe the basic information.',
|
||||||
"main": "",
|
main: '',
|
||||||
"author": "",
|
author: '',
|
||||||
"license": "",
|
license: '',
|
||||||
"dependencies": {
|
dependencies: {
|
||||||
"@rnoh/react-native-openharmony": "0.72.38",
|
'@rnoh/react-native-openharmony': '0.72.38',
|
||||||
"pushy": "file:../../node_modules/react-native-update/harmony/pushy.har",
|
pushy: 'file:../../node_modules/react-native-update/harmony/pushy',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {appTasks} from '@ohos/hvigor-ohos-plugin';
|
import {appTasks} from '@ohos/hvigor-ohos-plugin';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
|
system: appTasks /* Built-in plugin of Hvigor. It cannot be modified. */,
|
||||||
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
|
plugins: [] /* Custom plugin to extend the functionality of Hvigor. */,
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
"react-native-paper": "^5.14.5",
|
"react-native-paper": "^5.14.5",
|
||||||
"react-native-safe-area-context": "^5.6.1",
|
"react-native-safe-area-context": "^5.6.1",
|
||||||
"react-native-svg": "^15.13.0",
|
"react-native-svg": "^15.13.0",
|
||||||
"react-native-update": "^10.31.0-beta.4",
|
"react-native-update": "^10.31.2",
|
||||||
"react-native-vector-icons": "^10.3.0",
|
"react-native-vector-icons": "^10.3.0",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -1430,7 +1430,7 @@
|
|||||||
|
|
||||||
"react-native-svg": ["react-native-svg@15.13.0", "", { "dependencies": { "css-select": "^5.1.0", "css-tree": "^1.1.3", "warn-once": "0.1.1" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-/YPK+PAAXg4T0x2d2vYPvqqAhOYid2bRKxUVT7STIyd1p2JxWmsGQkfZxXCkEFN7TwLfIyVlT5RimT91Pj/qXw=="],
|
"react-native-svg": ["react-native-svg@15.13.0", "", { "dependencies": { "css-select": "^5.1.0", "css-tree": "^1.1.3", "warn-once": "0.1.1" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-/YPK+PAAXg4T0x2d2vYPvqqAhOYid2bRKxUVT7STIyd1p2JxWmsGQkfZxXCkEFN7TwLfIyVlT5RimT91Pj/qXw=="],
|
||||||
|
|
||||||
"react-native-update": ["react-native-update@10.31.0-beta.4", "", { "dependencies": { "nanoid": "^3.3.3", "react-native-url-polyfill": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-native": ">=0.59.0" } }, "sha512-6TdSq9PdxH07IHFcMkhMaPxA81teike++PZtgVWbL1GJiZJ5MXpLhwsxD2Nd4x+eHJY8pj4wgMBC8iCAfqVJlg=="],
|
"react-native-update": ["react-native-update@10.31.2", "", { "dependencies": { "nanoid": "^3.3.3", "react-native-url-polyfill": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-native": ">=0.59.0" } }, "sha512-doKTDyU/+6eN1jDswSh1HxnM9/XuxYFM65dLadsYVR+JvdLJ0PtbceSauthv4HYI3QXoeGaStkrRCaQAVKvp+w=="],
|
||||||
|
|
||||||
"react-native-url-polyfill": ["react-native-url-polyfill@2.0.0", "", { "dependencies": { "whatwg-url-without-unicode": "8.0.0-3" }, "peerDependencies": { "react-native": "*" } }, "sha512-My330Do7/DvKnEvwQc0WdcBnFPploYKp9CYlefDXzIdEaA+PAhDYllkvGeEroEzvc4Kzzj2O4yVdz8v6fjRvhA=="],
|
"react-native-url-polyfill": ["react-native-url-polyfill@2.0.0", "", { "dependencies": { "whatwg-url-without-unicode": "8.0.0-3" }, "peerDependencies": { "react-native": "*" } }, "sha512-My330Do7/DvKnEvwQc0WdcBnFPploYKp9CYlefDXzIdEaA+PAhDYllkvGeEroEzvc4Kzzj2O4yVdz8v6fjRvhA=="],
|
||||||
|
|
||||||
|
|||||||
@@ -1835,7 +1835,7 @@ PODS:
|
|||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- SocketRocket
|
- SocketRocket
|
||||||
- Yoga
|
- Yoga
|
||||||
- react-native-update (10.31.0-beta.4):
|
- react-native-update (10.31.2):
|
||||||
- boost
|
- boost
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- fast_float
|
- fast_float
|
||||||
@@ -1854,7 +1854,7 @@ PODS:
|
|||||||
- React-graphics
|
- React-graphics
|
||||||
- React-ImageManager
|
- React-ImageManager
|
||||||
- React-jsi
|
- React-jsi
|
||||||
- react-native-update/RCTPushy (= 10.31.0-beta.4)
|
- react-native-update/RCTPushy (= 10.31.2)
|
||||||
- React-NativeModulesApple
|
- React-NativeModulesApple
|
||||||
- React-RCTFabric
|
- React-RCTFabric
|
||||||
- React-renderercss
|
- React-renderercss
|
||||||
@@ -1866,7 +1866,7 @@ PODS:
|
|||||||
- SocketRocket
|
- SocketRocket
|
||||||
- SSZipArchive
|
- SSZipArchive
|
||||||
- Yoga
|
- Yoga
|
||||||
- react-native-update/RCTPushy (10.31.0-beta.4):
|
- react-native-update/RCTPushy (10.31.2):
|
||||||
- boost
|
- boost
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- fast_float
|
- fast_float
|
||||||
@@ -2800,7 +2800,7 @@ SPEC CHECKSUMS:
|
|||||||
React-Mapbuffer: 9d2434a42701d6144ca18f0ca1c4507808ca7696
|
React-Mapbuffer: 9d2434a42701d6144ca18f0ca1c4507808ca7696
|
||||||
React-microtasksnativemodule: 75b6604b667d297292345302cc5bfb6b6aeccc1b
|
React-microtasksnativemodule: 75b6604b667d297292345302cc5bfb6b6aeccc1b
|
||||||
react-native-safe-area-context: c6e2edd1c1da07bdce287fa9d9e60c5f7b514616
|
react-native-safe-area-context: c6e2edd1c1da07bdce287fa9d9e60c5f7b514616
|
||||||
react-native-update: 66be7f3c9572c483d6f43405097cdf8fd5c93d84
|
react-native-update: 7a05a78c6da651c1961b8407859f44bd0aa9b03a
|
||||||
React-NativeModulesApple: 879fbdc5dcff7136abceb7880fe8a2022a1bd7c3
|
React-NativeModulesApple: 879fbdc5dcff7136abceb7880fe8a2022a1bd7c3
|
||||||
React-oscompat: 93b5535ea7f7dff46aaee4f78309a70979bdde9d
|
React-oscompat: 93b5535ea7f7dff46aaee4f78309a70979bdde9d
|
||||||
React-perflogger: 5536d2df3d18fe0920263466f7b46a56351c0510
|
React-perflogger: 5536d2df3d18fe0920263466f7b46a56351c0510
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
"react-native-paper": "^5.14.5",
|
"react-native-paper": "^5.14.5",
|
||||||
"react-native-safe-area-context": "^5.6.1",
|
"react-native-safe-area-context": "^5.6.1",
|
||||||
"react-native-svg": "^15.13.0",
|
"react-native-svg": "^15.13.0",
|
||||||
"react-native-update": "^10.31.0-beta.4",
|
"react-native-update": "^10.31.2",
|
||||||
"react-native-vector-icons": "^10.3.0"
|
"react-native-vector-icons": "^10.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
27
android/proguard.pro
vendored
27
android/proguard.pro
vendored
@@ -10,28 +10,9 @@
|
|||||||
-keepnames class com.facebook.react.devsupport.** { *; }
|
-keepnames class com.facebook.react.devsupport.** { *; }
|
||||||
|
|
||||||
# Keep fields used in reflection
|
# Keep fields used in reflection
|
||||||
-keepclassmembers class com.facebook.react.ReactInstanceManager {
|
-keepclassmembers class com.facebook.react.ReactActivity { *; }
|
||||||
private JSBundleLoader mBundleLoader;
|
-keepclassmembers class com.facebook.react.ReactInstanceManager { *; }
|
||||||
private String mJSBundleFile;
|
-keepclassmembers class com.facebook.react.ReactDelegate { *; }
|
||||||
}
|
-keepclassmembers class com.facebook.react.ReactHost { *; }
|
||||||
|
|
||||||
-keepclassmembers class com.facebook.react.ReactDelegate {
|
|
||||||
private ReactHost mReactHost;
|
|
||||||
}
|
|
||||||
|
|
||||||
-keepclassmembers class com.facebook.react.ReactHost {
|
|
||||||
private boolean mUseDevSupport;
|
|
||||||
private ReactHostDelegate mReactHostDelegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Keep Expo related classes
|
|
||||||
-keepnames class expo.modules.ExpoReactHostFactory$ExpoReactHostDelegate { *; }
|
-keepnames class expo.modules.ExpoReactHostFactory$ExpoReactHostDelegate { *; }
|
||||||
|
|
||||||
# Keep methods used in reflection
|
|
||||||
-keepclassmembers class com.facebook.react.ReactActivity {
|
|
||||||
public ReactDelegate getReactDelegate();
|
|
||||||
}
|
|
||||||
|
|
||||||
-keepclassmembers class com.facebook.react.ReactHost {
|
|
||||||
public void reload(java.lang.String);
|
|
||||||
}
|
|
||||||
@@ -25,6 +25,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.CRC32;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import okio.BufferedSink;
|
import okio.BufferedSink;
|
||||||
@@ -198,6 +199,10 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
return fout.toByteArray();
|
return fout.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getCRC32AsDecimal(long crc32Value) {
|
||||||
|
return String.valueOf(crc32Value & 0xFFFFFFFFL);
|
||||||
|
}
|
||||||
|
|
||||||
private void copyFilesWithBlacklist(String current, File from, File to, JSONObject blackList) throws IOException {
|
private void copyFilesWithBlacklist(String current, File from, File to, JSONObject blackList) throws IOException {
|
||||||
File[] files = from.listFiles();
|
File[] files = from.listFiles();
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
@@ -273,12 +278,41 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
zipFile.close();
|
zipFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void copyFromResourceV2(HashMap<String, ArrayList<File>> resToCopy2) throws IOException {
|
||||||
|
SafeZipFile zipFile = new SafeZipFile(new File(context.getPackageResourcePath()));
|
||||||
|
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||||
|
while (entries.hasMoreElements()) {
|
||||||
|
ZipEntry ze = entries.nextElement();
|
||||||
|
String fn = ze.getName();
|
||||||
|
long zipCrc32 = ze.getCrc();
|
||||||
|
String crc32Decimal = getCRC32AsDecimal(zipCrc32);
|
||||||
|
ArrayList<File> targets = resToCopy2.get(crc32Decimal);
|
||||||
|
if (targets != null) {
|
||||||
|
File lastTarget = null;
|
||||||
|
for (File target: targets) {
|
||||||
|
if (UpdateContext.DEBUG) {
|
||||||
|
Log.d("react-native-update", "Copying from resource " + fn + " to " + target);
|
||||||
|
}
|
||||||
|
if (lastTarget != null) {
|
||||||
|
copyFile(lastTarget, target);
|
||||||
|
} else {
|
||||||
|
zipFile.unzipToFile(ze, target);
|
||||||
|
lastTarget = target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zipFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
private void doPatchFromApk(DownloadTaskParams param) throws IOException, JSONException {
|
private void doPatchFromApk(DownloadTaskParams param) throws IOException, JSONException {
|
||||||
downloadFile(param);
|
downloadFile(param);
|
||||||
|
|
||||||
removeDirectory(param.unzipDirectory);
|
removeDirectory(param.unzipDirectory);
|
||||||
param.unzipDirectory.mkdirs();
|
param.unzipDirectory.mkdirs();
|
||||||
HashMap<String, ArrayList<File>> copyList = new HashMap<String, ArrayList<File>>();
|
HashMap<String, ArrayList<File>> copyList = new HashMap<String, ArrayList<File>>();
|
||||||
|
HashMap<String, ArrayList<File>> copiesv2List = new HashMap<String, ArrayList<File>>();
|
||||||
|
Boolean isV2 = false;
|
||||||
|
|
||||||
boolean foundDiff = false;
|
boolean foundDiff = false;
|
||||||
boolean foundBundlePatch = false;
|
boolean foundBundlePatch = false;
|
||||||
@@ -297,7 +331,35 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
JSONObject obj = (JSONObject)new JSONTokener(json).nextValue();
|
JSONObject obj = (JSONObject)new JSONTokener(json).nextValue();
|
||||||
|
|
||||||
JSONObject copies = obj.getJSONObject("copies");
|
JSONObject copies = obj.getJSONObject("copies");
|
||||||
|
JSONObject copiesv2 = obj.getJSONObject("copiesv2");
|
||||||
Iterator<?> keys = copies.keys();
|
Iterator<?> keys = copies.keys();
|
||||||
|
Iterator<?> keysV2 = copiesv2.keys();
|
||||||
|
if(keysV2.hasNext()){
|
||||||
|
isV2 = true;
|
||||||
|
while( keysV2.hasNext() ) {
|
||||||
|
String from = (String)keysV2.next();
|
||||||
|
String to = copiesv2.getString(from);
|
||||||
|
if (from.isEmpty()) {
|
||||||
|
from = to;
|
||||||
|
}
|
||||||
|
ArrayList<File> target = null;
|
||||||
|
if (!copiesv2List.containsKey(from)) {
|
||||||
|
target = new ArrayList<File>();
|
||||||
|
copiesv2List.put(from, target);
|
||||||
|
} else {
|
||||||
|
target = copiesv2List.get((from));
|
||||||
|
}
|
||||||
|
File toFile = new File(param.unzipDirectory, to);
|
||||||
|
|
||||||
|
// Fixing a Zip Path Traversal Vulnerability
|
||||||
|
// https://support.google.com/faqs/answer/9294009
|
||||||
|
String canonicalPath = toFile.getCanonicalPath();
|
||||||
|
if (!canonicalPath.startsWith(param.unzipDirectory.getCanonicalPath() + File.separator)) {
|
||||||
|
throw new SecurityException("Illegal name: " + to);
|
||||||
|
}
|
||||||
|
target.add(toFile);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
while( keys.hasNext() ) {
|
while( keys.hasNext() ) {
|
||||||
String to = (String)keys.next();
|
String to = (String)keys.next();
|
||||||
String from = copies.getString(to);
|
String from = copies.getString(to);
|
||||||
@@ -321,6 +383,7 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
}
|
}
|
||||||
target.add(toFile);
|
target.add(toFile);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (fn.equals("index.bundlejs.patch")) {
|
if (fn.equals("index.bundlejs.patch")) {
|
||||||
@@ -348,7 +411,11 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
throw new Error("bundle patch not found");
|
throw new Error("bundle patch not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isV2){
|
||||||
|
copyFromResourceV2(copiesv2List);
|
||||||
|
}else{
|
||||||
copyFromResource(copyList);
|
copyFromResource(copyList);
|
||||||
|
}
|
||||||
|
|
||||||
if (UpdateContext.DEBUG) {
|
if (UpdateContext.DEBUG) {
|
||||||
Log.d("react-native-update", "Unzip finished");
|
Log.d("react-native-update", "Unzip finished");
|
||||||
|
|||||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"meta": {
|
"meta": {
|
||||||
"stableOrder": true
|
"stableOrder": true,
|
||||||
|
"enableUnifiedLockfile": false
|
||||||
},
|
},
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
|
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
|
||||||
@@ -9,7 +10,7 @@
|
|||||||
},
|
},
|
||||||
"packages": {
|
"packages": {
|
||||||
"@rnoh/react-native-openharmony@0.72.38": {
|
"@rnoh/react-native-openharmony@0.72.38": {
|
||||||
"name": "@rnoh/react-native-openharmony",
|
"name": "",
|
||||||
"version": "0.72.38",
|
"version": "0.72.38",
|
||||||
"integrity": "sha512-br5SIrbB0OarSLirenleE7eTOX1lNccMJ7nb/G7qWTyJ7kW4DalmTXVKYpoT2qaOLls1uEE7McD1OjbZZM9jug==",
|
"integrity": "sha512-br5SIrbB0OarSLirenleE7eTOX1lNccMJ7nb/G7qWTyJ7kW4DalmTXVKYpoT2qaOLls1uEE7McD1OjbZZM9jug==",
|
||||||
"resolved": "https://ohpm.openharmony.cn/ohpm/@rnoh/react-native-openharmony/-/react-native-openharmony-0.72.38.har",
|
"resolved": "https://ohpm.openharmony.cn/ohpm/@rnoh/react-native-openharmony/-/react-native-openharmony-0.72.38.har",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"license": "ISC",
|
"license": "MIT",
|
||||||
"types": "",
|
"types": "",
|
||||||
"devDependencies": {},
|
"devDependencies": {},
|
||||||
"name": "pushy",
|
"name": "pushy",
|
||||||
@@ -8,5 +8,6 @@
|
|||||||
"version": "3.1.0-0.0.7",
|
"version": "3.1.0-0.0.7",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rnoh/react-native-openharmony":"^0.72.38"
|
"@rnoh/react-native-openharmony":"^0.72.38"
|
||||||
}
|
},
|
||||||
|
"modelVersion": "5.0.0"
|
||||||
}
|
}
|
||||||
|
|||||||
1
harmony/pushy/src/main/cpp/HDiffPatch
Symbolic link
1
harmony/pushy/src/main/cpp/HDiffPatch
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../../../../android/jni/HDiffPatch
|
||||||
1
harmony/pushy/src/main/cpp/lzma
Symbolic link
1
harmony/pushy/src/main/cpp/lzma
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../../../../android/jni/lzma
|
||||||
@@ -83,7 +83,7 @@ export class DownloadTask {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (response.responseCode > 299) {
|
if (response.responseCode > 299) {
|
||||||
throw new Error(`Server error: ${response.responseCode}`);
|
throw Error(`Server error: ${response.responseCode}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const contentLength = parseInt(response.header['content-length'] || '0');
|
const contentLength = parseInt(response.header['content-length'] || '0');
|
||||||
@@ -108,9 +108,10 @@ export class DownloadTask {
|
|||||||
const stats = await fileIo.stat(params.targetFile);
|
const stats = await fileIo.stat(params.targetFile);
|
||||||
const fileSize = stats.size;
|
const fileSize = stats.size;
|
||||||
if (fileSize !== contentLength) {
|
if (fileSize !== contentLength) {
|
||||||
throw new Error(`Download incomplete: expected ${contentLength} bytes but got ${stats.size} bytes`);
|
throw Error(
|
||||||
|
`Download incomplete: expected ${contentLength} bytes but got ${stats.size} bytes`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Download failed:', error);
|
console.error('Download failed:', error);
|
||||||
throw error;
|
throw error;
|
||||||
@@ -142,7 +143,7 @@ export class DownloadTask {
|
|||||||
bytesRead = await fileIo
|
bytesRead = await fileIo
|
||||||
.read(reader.fd, arrayBuffer)
|
.read(reader.fd, arrayBuffer)
|
||||||
.catch((err: BusinessError) => {
|
.catch((err: BusinessError) => {
|
||||||
throw new Error(
|
throw Error(
|
||||||
`Error reading file: ${err.message}, code: ${err.code}`,
|
`Error reading file: ${err.message}, code: ${err.code}`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -154,7 +155,7 @@ export class DownloadTask {
|
|||||||
length: bytesRead,
|
length: bytesRead,
|
||||||
})
|
})
|
||||||
.catch((err: BusinessError) => {
|
.catch((err: BusinessError) => {
|
||||||
throw new Error(
|
throw Error(
|
||||||
`Error writing file: ${err.message}, code: ${err.code}`,
|
`Error writing file: ${err.message}, code: ${err.code}`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -301,10 +302,10 @@ export class DownloadTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!foundDiff) {
|
if (!foundDiff) {
|
||||||
throw new Error('diff.json not found');
|
throw Error('diff.json not found');
|
||||||
}
|
}
|
||||||
if (!foundBundlePatch) {
|
if (!foundBundlePatch) {
|
||||||
throw new Error('bundle patch not found');
|
throw Error('bundle patch not found');
|
||||||
}
|
}
|
||||||
await this.copyFromResource(copyList);
|
await this.copyFromResource(copyList);
|
||||||
}
|
}
|
||||||
@@ -366,12 +367,18 @@ export class DownloadTask {
|
|||||||
new Uint8Array(entry.content),
|
new Uint8Array(entry.content),
|
||||||
);
|
);
|
||||||
const outputFile = `${params.unzipDirectory}/bundle.harmony.js`;
|
const outputFile = `${params.unzipDirectory}/bundle.harmony.js`;
|
||||||
const writer = await fileIo.open(outputFile, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY);
|
const writer = await fileIo.open(
|
||||||
|
outputFile,
|
||||||
|
fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY,
|
||||||
|
);
|
||||||
const chunkSize = 4096;
|
const chunkSize = 4096;
|
||||||
let bytesWritten = 0;
|
let bytesWritten = 0;
|
||||||
const totalLength = patched.byteLength;
|
const totalLength = patched.byteLength;
|
||||||
while (bytesWritten < totalLength) {
|
while (bytesWritten < totalLength) {
|
||||||
const chunk = patched.slice(bytesWritten, bytesWritten + chunkSize);
|
const chunk = patched.slice(
|
||||||
|
bytesWritten,
|
||||||
|
bytesWritten + chunkSize,
|
||||||
|
);
|
||||||
await fileIo.write(writer.fd, chunk);
|
await fileIo.write(writer.fd, chunk);
|
||||||
bytesWritten += chunk.byteLength;
|
bytesWritten += chunk.byteLength;
|
||||||
}
|
}
|
||||||
@@ -387,10 +394,10 @@ export class DownloadTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!foundDiff) {
|
if (!foundDiff) {
|
||||||
throw new Error('diff.json not found');
|
throw Error('diff.json not found');
|
||||||
}
|
}
|
||||||
if (!foundBundlePatch) {
|
if (!foundBundlePatch) {
|
||||||
throw new Error('bundle patch not found');
|
throw Error('bundle patch not found');
|
||||||
}
|
}
|
||||||
console.info('Patch from PPK completed');
|
console.info('Patch from PPK completed');
|
||||||
}
|
}
|
||||||
@@ -478,7 +485,7 @@ export class DownloadTask {
|
|||||||
await this.downloadFile(params);
|
await this.downloadFile(params);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown task type: ${params.type}`);
|
throw Error(`Unknown task type: ${params.type}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
params.listener?.onDownloadCompleted(params);
|
params.listener?.onDownloadCompleted(params);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export class PushyFileJSBundleProvider extends JSBundleProvider {
|
|||||||
this.updateContext = new UpdateContext(context);
|
this.updateContext = new UpdateContext(context);
|
||||||
}
|
}
|
||||||
getURL(): string {
|
getURL(): string {
|
||||||
return this.updateContext.getBundleUrl().substring(1);
|
return this.updateContext.getBundleUrl()?.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBundle(): Promise<ArrayBuffer> {
|
async getBundle(): Promise<ArrayBuffer> {
|
||||||
|
|||||||
@@ -9,47 +9,47 @@ import { UpdateModuleImpl } from './UpdateModuleImpl';
|
|||||||
import { UpdateContext } from './UpdateContext';
|
import { UpdateContext } from './UpdateContext';
|
||||||
import { EventHub } from './EventHub';
|
import { EventHub } from './EventHub';
|
||||||
|
|
||||||
const TAG = "PushyTurboModule"
|
const TAG = 'PushyTurboModule';
|
||||||
|
|
||||||
export class PushyTurboModule extends TurboModule {
|
export class PushyTurboModule extends TurboModule {
|
||||||
mUiCtx: common.UIAbilityContext
|
mUiCtx: common.UIAbilityContext;
|
||||||
context: UpdateContext
|
context: UpdateContext;
|
||||||
|
|
||||||
constructor(protected ctx: TurboModuleContext) {
|
constructor(protected ctx: TurboModuleContext) {
|
||||||
super(ctx);
|
super(ctx);
|
||||||
logger.debug(TAG, ",PushyTurboModule constructor");
|
logger.debug(TAG, ',PushyTurboModule constructor');
|
||||||
this.mUiCtx = ctx.uiAbilityContext
|
this.mUiCtx = ctx.uiAbilityContext;
|
||||||
this.context = new UpdateContext(this.mUiCtx)
|
this.context = new UpdateContext(this.mUiCtx);
|
||||||
EventHub.getInstance().setRNInstance(ctx.rnInstance)
|
EventHub.getInstance().setRNInstance(ctx.rnInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
getConstants(): Object {
|
getConstants(): Object {
|
||||||
logger.debug(TAG, ",call getConstants");
|
logger.debug(TAG, ',call getConstants');
|
||||||
const context = this.mUiCtx;
|
const context = this.mUiCtx;
|
||||||
const preferencesManager = dataPreferences.getPreferencesSync(context,{ name: 'update' });
|
const preferencesManager = dataPreferences.getPreferencesSync(context,{ name: 'update' });
|
||||||
const isFirstTime = preferencesManager.getSync("isFirstTime", false) as boolean;
|
const isFirstTime = preferencesManager.getSync('isFirstTime', false) as boolean;
|
||||||
const rolledBackVersion = preferencesManager.getSync("rolledBackVersion", "") as string;
|
const rolledBackVersion = preferencesManager.getSync('rolledBackVersion', '') as string;
|
||||||
const uuid = preferencesManager.getSync("uuid", "") as string;
|
const uuid = preferencesManager.getSync('uuid', '') as string;
|
||||||
const currentVersion = preferencesManager.getSync("currentVersion", "") as string;
|
const currentVersion = preferencesManager.getSync('currentVersion', '') as string;
|
||||||
const currentVersionInfo = this.context.getKv(`hash_${currentVersion}`);
|
const currentVersionInfo = this.context.getKv(`hash_${currentVersion}`);
|
||||||
const buildTime = preferencesManager.getSync("buildTime", "") as string;
|
const buildTime = preferencesManager.getSync('buildTime', '') as string;
|
||||||
const isUsingBundleUrl = this.context.getIsUsingBundleUrl();
|
const isUsingBundleUrl = this.context.getIsUsingBundleUrl();
|
||||||
let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION;
|
let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION;
|
||||||
let packageVersion = '';
|
let packageVersion = '';
|
||||||
try {
|
try {
|
||||||
const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleFlags);
|
const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleFlags);
|
||||||
packageVersion = bundleInfo?.versionName || "Unknown"
|
packageVersion = bundleInfo?.versionName || 'Unknown';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to get bundle info:", error);
|
console.error('Failed to get bundle info:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFirstTime) {
|
if (isFirstTime) {
|
||||||
preferencesManager.deleteSync("isFirstTime");
|
preferencesManager.deleteSync('isFirstTime');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rolledBackVersion) {
|
if (rolledBackVersion) {
|
||||||
preferencesManager.deleteSync("rolledBackVersion");
|
preferencesManager.deleteSync('rolledBackVersion');
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -62,12 +62,12 @@ getConstants(): Object {
|
|||||||
isFirstTime,
|
isFirstTime,
|
||||||
rolledBackVersion,
|
rolledBackVersion,
|
||||||
uuid,
|
uuid,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
setLocalHashInfo(hash: string, info: string): boolean {
|
setLocalHashInfo(hash: string, info: string): boolean {
|
||||||
logger.debug(TAG, ",call setLocalHashInfo");
|
logger.debug(TAG, ',call setLocalHashInfo');
|
||||||
return UpdateModuleImpl.setLocalHashInfo(this.context, hash, info);
|
return UpdateModuleImpl.setLocalHashInfo(this.context, hash, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,50 +76,50 @@ getConstants(): Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async setUuid(uuid: string): Promise<boolean> {
|
async setUuid(uuid: string): Promise<boolean> {
|
||||||
logger.debug(TAG, `,call setUuid`);
|
logger.debug(TAG, ',call setUuid');
|
||||||
return UpdateModuleImpl.setUuid(this.context,uuid);
|
return UpdateModuleImpl.setUuid(this.context,uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
async reloadUpdate(options: { hash: string }): Promise<void> {
|
async reloadUpdate(options: { hash: string }): Promise<void> {
|
||||||
logger.debug(TAG, `,call reloadUpdate`);
|
logger.debug(TAG, ',call reloadUpdate');
|
||||||
return UpdateModuleImpl.reloadUpdate(this.context, this.mUiCtx, options);
|
return UpdateModuleImpl.reloadUpdate(this.context, this.mUiCtx, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setNeedUpdate(options: { hash: string }): Promise<boolean> {
|
async setNeedUpdate(options: { hash: string }): Promise<boolean> {
|
||||||
logger.debug(TAG, `,call setNeedUpdate`);
|
logger.debug(TAG, ',call setNeedUpdate');
|
||||||
return UpdateModuleImpl.setNeedUpdate(this.context, options);
|
return UpdateModuleImpl.setNeedUpdate(this.context, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async markSuccess(): Promise<boolean> {
|
async markSuccess(): Promise<boolean> {
|
||||||
logger.debug(TAG, `,call markSuccess`);
|
logger.debug(TAG, ',call markSuccess');
|
||||||
return UpdateModuleImpl.markSuccess(this.context);
|
return UpdateModuleImpl.markSuccess(this.context);
|
||||||
}
|
}
|
||||||
|
|
||||||
async downloadPatchFromPpk(options: { updateUrl: string; hash: string; originHash: string }): Promise<void> {
|
async downloadPatchFromPpk(options: { updateUrl: string; hash: string; originHash: string }): Promise<void> {
|
||||||
logger.debug(TAG, `,call downloadPatchFromPpk`);
|
logger.debug(TAG, ',call downloadPatchFromPpk');
|
||||||
return UpdateModuleImpl.downloadPatchFromPpk(this.context, options);
|
return UpdateModuleImpl.downloadPatchFromPpk(this.context, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async downloadPatchFromPackage(options: { updateUrl: string; hash: string }): Promise<void> {
|
async downloadPatchFromPackage(options: { updateUrl: string; hash: string }): Promise<void> {
|
||||||
logger.debug(TAG, `,call downloadPatchFromPackage`);
|
logger.debug(TAG, ',call downloadPatchFromPackage');
|
||||||
return UpdateModuleImpl.downloadPatchFromPackage(this.context, options);
|
return UpdateModuleImpl.downloadPatchFromPackage(this.context, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async downloadFullUpdate(options: { updateUrl: string; hash: string }): Promise<void> {
|
async downloadFullUpdate(options: { updateUrl: string; hash: string }): Promise<void> {
|
||||||
logger.debug(TAG, `,call downloadFullUpdate`);
|
logger.debug(TAG, ',call downloadFullUpdate');
|
||||||
return UpdateModuleImpl.downloadFullUpdate(this.context, options);
|
return UpdateModuleImpl.downloadFullUpdate(this.context, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async downloadAndInstallApk(options: { url: string; target: string; hash: string }): Promise<void> {
|
async downloadAndInstallApk(options: { url: string; target: string; hash: string }): Promise<void> {
|
||||||
logger.debug(TAG, `,call downloadAndInstallApk`);
|
logger.debug(TAG, ',call downloadAndInstallApk');
|
||||||
return UpdateModuleImpl.downloadAndInstallApk(this.mUiCtx, options);
|
return UpdateModuleImpl.downloadAndInstallApk(this.mUiCtx, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
addListener(eventName: string): void {
|
addListener(eventName: string): void {
|
||||||
logger.debug(TAG, `,call addListener`);
|
logger.debug(TAG, ',call addListener');
|
||||||
}
|
}
|
||||||
|
|
||||||
removeListeners(count: number): void {
|
removeListeners(count: number): void {
|
||||||
logger.debug(TAG, `,call removeListeners`);
|
logger.debug(TAG, ',call removeListeners');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,9 @@ export class UpdateContext {
|
|||||||
|
|
||||||
private initPreferences() {
|
private initPreferences() {
|
||||||
try {
|
try {
|
||||||
this.preferences = preferences.getPreferencesSync(this.context, {name:'update'});
|
this.preferences = preferences.getPreferencesSync(this.context, {
|
||||||
|
name: 'update',
|
||||||
|
});
|
||||||
const packageVersion = this.getPackageVersion();
|
const packageVersion = this.getPackageVersion();
|
||||||
const storedVersion = this.preferences.getSync('packageVersion', '');
|
const storedVersion = this.preferences.getSync('packageVersion', '');
|
||||||
if (!storedVersion) {
|
if (!storedVersion) {
|
||||||
@@ -87,7 +89,11 @@ export class UpdateContext {
|
|||||||
this.cleanUp();
|
this.cleanUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async downloadFullUpdate(url: string, hash: string, listener: DownloadFileListener): Promise<void> {
|
public async downloadFullUpdate(
|
||||||
|
url: string,
|
||||||
|
hash: string,
|
||||||
|
listener: DownloadFileListener,
|
||||||
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const params = new DownloadTaskParams();
|
const params = new DownloadTaskParams();
|
||||||
params.type = DownloadTaskParams.TASK_TYPE_PATCH_FULL;
|
params.type = DownloadTaskParams.TASK_TYPE_PATCH_FULL;
|
||||||
@@ -102,7 +108,12 @@ export class UpdateContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async downloadFile(url: string, hash: string, fileName: string, listener: DownloadFileListener): Promise<void> {
|
public async downloadFile(
|
||||||
|
url: string,
|
||||||
|
hash: string,
|
||||||
|
fileName: string,
|
||||||
|
listener: DownloadFileListener,
|
||||||
|
): Promise<void> {
|
||||||
const params = new DownloadTaskParams();
|
const params = new DownloadTaskParams();
|
||||||
params.type = DownloadTaskParams.TASK_TYPE_PLAIN_DOWNLOAD;
|
params.type = DownloadTaskParams.TASK_TYPE_PLAIN_DOWNLOAD;
|
||||||
params.url = url;
|
params.url = url;
|
||||||
@@ -114,7 +125,12 @@ export class UpdateContext {
|
|||||||
await downloadTask.execute(params);
|
await downloadTask.execute(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async downloadPatchFromPpk(url: string, hash: string, originHash: string, listener: DownloadFileListener): Promise<void> {
|
public async downloadPatchFromPpk(
|
||||||
|
url: string,
|
||||||
|
hash: string,
|
||||||
|
originHash: string,
|
||||||
|
listener: DownloadFileListener,
|
||||||
|
): Promise<void> {
|
||||||
const params = new DownloadTaskParams();
|
const params = new DownloadTaskParams();
|
||||||
params.type = DownloadTaskParams.TASK_TYPE_PATCH_FROM_PPK;
|
params.type = DownloadTaskParams.TASK_TYPE_PATCH_FROM_PPK;
|
||||||
params.url = url;
|
params.url = url;
|
||||||
@@ -129,7 +145,11 @@ export class UpdateContext {
|
|||||||
await downloadTask.execute(params);
|
await downloadTask.execute(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async downloadPatchFromPackage(url: string, hash: string, listener: DownloadFileListener): Promise<void> {
|
public async downloadPatchFromPackage(
|
||||||
|
url: string,
|
||||||
|
hash: string,
|
||||||
|
listener: DownloadFileListener,
|
||||||
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const params = new DownloadTaskParams();
|
const params = new DownloadTaskParams();
|
||||||
params.type = DownloadTaskParams.TASK_TYPE_PATCH_FROM_APP;
|
params.type = DownloadTaskParams.TASK_TYPE_PATCH_FROM_APP;
|
||||||
@@ -151,7 +171,7 @@ export class UpdateContext {
|
|||||||
try {
|
try {
|
||||||
const bundlePath = `${this.rootDir}/${hash}/bundle.harmony.js`;
|
const bundlePath = `${this.rootDir}/${hash}/bundle.harmony.js`;
|
||||||
if (!fileIo.accessSync(bundlePath)) {
|
if (!fileIo.accessSync(bundlePath)) {
|
||||||
throw new Error(`Bundle version ${hash} not found.`);
|
throw Error(`Bundle version ${hash} not found.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const lastVersion = this.getKv('currentVersion');
|
const lastVersion = this.getKv('currentVersion');
|
||||||
@@ -162,13 +182,16 @@ export class UpdateContext {
|
|||||||
|
|
||||||
this.setKv('firstTime', 'true');
|
this.setKv('firstTime', 'true');
|
||||||
this.setKv('firstTimeOk', 'false');
|
this.setKv('firstTimeOk', 'false');
|
||||||
this.setKv('rolledBackVersion', "");
|
this.setKv('rolledBackVersion', '');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to switch version:', e);
|
console.error('Failed to switch version:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getBundleUrl(context: common.UIAbilityContext, defaultAssetsUrl?: string): string {
|
public static getBundleUrl(
|
||||||
|
context: common.UIAbilityContext,
|
||||||
|
defaultAssetsUrl?: string,
|
||||||
|
): string {
|
||||||
return new UpdateContext(context).getBundleUrl(defaultAssetsUrl);
|
return new UpdateContext(context).getBundleUrl(defaultAssetsUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,13 +225,14 @@ export class UpdateContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getPackageVersion(): string {
|
getPackageVersion(): string {
|
||||||
let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION;
|
let bundleFlags =
|
||||||
|
bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION;
|
||||||
let packageVersion = '';
|
let packageVersion = '';
|
||||||
try {
|
try {
|
||||||
const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleFlags);
|
const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleFlags);
|
||||||
packageVersion = bundleInfo?.versionName || "Unknown";
|
packageVersion = bundleInfo?.versionName || 'Unknown';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("获取包信息失败:", error);
|
console.error('获取包信息失败:', error);
|
||||||
}
|
}
|
||||||
return packageVersion;
|
return packageVersion;
|
||||||
}
|
}
|
||||||
@@ -220,7 +244,10 @@ export class UpdateContext {
|
|||||||
|
|
||||||
private rollBack(): string {
|
private rollBack(): string {
|
||||||
const lastVersion = this.preferences.getSync('lastVersion', '') as string;
|
const lastVersion = this.preferences.getSync('lastVersion', '') as string;
|
||||||
const currentVersion = this.preferences.getSync('currentVersion', '') as string;
|
const currentVersion = this.preferences.getSync(
|
||||||
|
'currentVersion',
|
||||||
|
'',
|
||||||
|
) as string;
|
||||||
if (!lastVersion) {
|
if (!lastVersion) {
|
||||||
this.preferences.deleteSync('currentVersion');
|
this.preferences.deleteSync('currentVersion');
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ import { UpdateContext } from './UpdateContext';
|
|||||||
import { DownloadTaskParams } from './DownloadTaskParams';
|
import { DownloadTaskParams } from './DownloadTaskParams';
|
||||||
import logger from './Logger';
|
import logger from './Logger';
|
||||||
|
|
||||||
const TAG = "UpdateModuleImpl";
|
const TAG = 'UpdateModuleImpl';
|
||||||
|
|
||||||
export class UpdateModuleImpl {
|
export class UpdateModuleImpl {
|
||||||
static readonly NAME = "Pushy";
|
static readonly NAME = 'Pushy';
|
||||||
|
|
||||||
static async downloadFullUpdate(
|
static async downloadFullUpdate(
|
||||||
updateContext: UpdateContext,
|
updateContext: UpdateContext,
|
||||||
options: { updateUrl: string; hash: string }
|
options: { updateUrl: string; hash: string },
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await updateContext.downloadFullUpdate(options.updateUrl, options.hash, {
|
await updateContext.downloadFullUpdate(options.updateUrl, options.hash, {
|
||||||
@@ -20,7 +20,7 @@ export class UpdateModuleImpl {
|
|||||||
},
|
},
|
||||||
onDownloadFailed: (error: Error) => {
|
onDownloadFailed: (error: Error) => {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(TAG, `downloadFullUpdate failed: ${error}`);
|
logger.error(TAG, `downloadFullUpdate failed: ${error}`);
|
||||||
@@ -30,18 +30,18 @@ export class UpdateModuleImpl {
|
|||||||
|
|
||||||
static async downloadAndInstallApk(
|
static async downloadAndInstallApk(
|
||||||
context: common.UIAbilityContext,
|
context: common.UIAbilityContext,
|
||||||
options: { url: string; hash: string; target: string }
|
options: { url: string; hash: string; target: string },
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const want = {
|
const want = {
|
||||||
action: 'action.system.home',
|
action: 'action.system.home',
|
||||||
parameters: {
|
parameters: {
|
||||||
uri: 'appmarket://details'
|
uri: 'appmarket://details',
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!context) {
|
if (!context) {
|
||||||
throw new Error('获取context失败');
|
throw Error('获取context失败');
|
||||||
}
|
}
|
||||||
|
|
||||||
await context.startAbility(want);
|
await context.startAbility(want);
|
||||||
@@ -53,17 +53,21 @@ export class UpdateModuleImpl {
|
|||||||
|
|
||||||
static async downloadPatchFromPackage(
|
static async downloadPatchFromPackage(
|
||||||
updateContext: UpdateContext,
|
updateContext: UpdateContext,
|
||||||
options: { updateUrl: string; hash: string }
|
options: { updateUrl: string; hash: string },
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
return await updateContext.downloadPatchFromPackage(options.updateUrl, options.hash, {
|
return await updateContext.downloadPatchFromPackage(
|
||||||
|
options.updateUrl,
|
||||||
|
options.hash,
|
||||||
|
{
|
||||||
onDownloadCompleted: (params: DownloadTaskParams) => {
|
onDownloadCompleted: (params: DownloadTaskParams) => {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
},
|
},
|
||||||
onDownloadFailed: (error: Error) => {
|
onDownloadFailed: (error: Error) => {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
},
|
||||||
});
|
},
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(TAG, `downloadPatchFromPackage failed: ${error}`);
|
logger.error(TAG, `downloadPatchFromPackage failed: ${error}`);
|
||||||
throw error;
|
throw error;
|
||||||
@@ -72,7 +76,7 @@ export class UpdateModuleImpl {
|
|||||||
|
|
||||||
static async downloadPatchFromPpk(
|
static async downloadPatchFromPpk(
|
||||||
updateContext: UpdateContext,
|
updateContext: UpdateContext,
|
||||||
options: { updateUrl: string; hash: string; originHash: string }
|
options: { updateUrl: string; hash: string; originHash: string },
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await updateContext.downloadPatchFromPpk(
|
await updateContext.downloadPatchFromPpk(
|
||||||
@@ -85,49 +89,49 @@ export class UpdateModuleImpl {
|
|||||||
},
|
},
|
||||||
onDownloadFailed: (error: Error) => {
|
onDownloadFailed: (error: Error) => {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(TAG, `downloadPatchFromPpk failed: ${error}`);
|
logger.error(TAG, `downloadPatchFromPpk failed: ${error}`);
|
||||||
throw new Error(`执行报错: ${error.message}`);
|
throw Error(`执行报错: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async reloadUpdate(
|
static async reloadUpdate(
|
||||||
updateContext: UpdateContext,
|
updateContext: UpdateContext,
|
||||||
context: common.UIAbilityContext,
|
context: common.UIAbilityContext,
|
||||||
options: { hash: string }
|
options: { hash: string },
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const hash = options.hash;
|
const hash = options.hash;
|
||||||
if (!hash) {
|
if (!hash) {
|
||||||
throw new Error('hash不能为空');
|
throw Error('hash不能为空');
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await updateContext.switchVersion(hash);
|
await updateContext.switchVersion(hash);
|
||||||
const bundleInfo = await bundleManager.getBundleInfoForSelf(
|
const bundleInfo = await bundleManager.getBundleInfoForSelf(
|
||||||
bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION
|
bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION,
|
||||||
);
|
);
|
||||||
await context.terminateSelf();
|
await context.terminateSelf();
|
||||||
const want = {
|
const want = {
|
||||||
bundleName: bundleInfo.name,
|
bundleName: bundleInfo.name,
|
||||||
abilityName: context.abilityInfo?.name
|
abilityName: context.abilityInfo?.name,
|
||||||
};
|
};
|
||||||
await context.startAbility(want);
|
await context.startAbility(want);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(TAG, `reloadUpdate failed: ${error}`);
|
logger.error(TAG, `reloadUpdate failed: ${error}`);
|
||||||
throw new Error(`pushy:switchVersion failed ${error.message}`);
|
throw Error(`pushy:switchVersion failed ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async setNeedUpdate(
|
static async setNeedUpdate(
|
||||||
updateContext: UpdateContext,
|
updateContext: UpdateContext,
|
||||||
options: { hash: string }
|
options: { hash: string },
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const hash = options.hash;
|
const hash = options.hash;
|
||||||
if (!hash) {
|
if (!hash) {
|
||||||
throw new Error('hash不能为空');
|
throw Error('hash不能为空');
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -135,7 +139,7 @@ export class UpdateModuleImpl {
|
|||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(TAG, `setNeedUpdate failed: ${error}`);
|
logger.error(TAG, `setNeedUpdate failed: ${error}`);
|
||||||
throw new Error(`switchVersionLater failed: ${error.message}`);
|
throw Error(`switchVersionLater failed: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,20 +149,20 @@ export class UpdateModuleImpl {
|
|||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(TAG, `markSuccess failed: ${error}`);
|
logger.error(TAG, `markSuccess failed: ${error}`);
|
||||||
throw new Error(`执行报错: ${error.message}`);
|
throw Error(`执行报错: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async setUuid(
|
static async setUuid(
|
||||||
updateContext: UpdateContext,
|
updateContext: UpdateContext,
|
||||||
uuid: string
|
uuid: string,
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
await updateContext.setKv('uuid', uuid);
|
await updateContext.setKv('uuid', uuid);
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(TAG, `setUuid failed: ${error}`);
|
logger.error(TAG, `setUuid failed: ${error}`);
|
||||||
throw new Error(`执行报错: ${error.message}`);
|
throw Error(`执行报错: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,16 +178,13 @@ export class UpdateModuleImpl {
|
|||||||
static setLocalHashInfo(
|
static setLocalHashInfo(
|
||||||
updateContext: UpdateContext,
|
updateContext: UpdateContext,
|
||||||
hash: string,
|
hash: string,
|
||||||
info: string
|
info: string,
|
||||||
): boolean {
|
): boolean {
|
||||||
updateContext.setKv(`hash_${hash}`, info);
|
updateContext.setKv(`hash_${hash}`, info);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static getLocalHashInfo(
|
static getLocalHashInfo(updateContext: UpdateContext, hash: string): string {
|
||||||
updateContext: UpdateContext,
|
|
||||||
hash: string
|
|
||||||
): string {
|
|
||||||
const value = updateContext.getKv(`hash_${hash}`);
|
const value = updateContext.getKv(`hash_${hash}`);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,7 +178,9 @@ RCT_EXPORT_MODULE(RCTPushy);
|
|||||||
NSDictionary *pushyInfo = [defaults dictionaryForKey:keyPushyInfo];
|
NSDictionary *pushyInfo = [defaults dictionaryForKey:keyPushyInfo];
|
||||||
NSString *currentVersion = [pushyInfo objectForKey:paramCurrentVersion];
|
NSString *currentVersion = [pushyInfo objectForKey:paramCurrentVersion];
|
||||||
ret[@"currentVersion"] = currentVersion;
|
ret[@"currentVersion"] = currentVersion;
|
||||||
|
if (currentVersion != nil) {
|
||||||
ret[@"currentVersionInfo"] = [defaults objectForKey:[keyHashInfo stringByAppendingString:currentVersion]];
|
ret[@"currentVersionInfo"] = [defaults objectForKey:[keyHashInfo stringByAppendingString:currentVersion]];
|
||||||
|
}
|
||||||
|
|
||||||
// clear isFirstTimemarked
|
// clear isFirstTimemarked
|
||||||
if (ret[@"isFirstTime"]) {
|
if (ret[@"isFirstTime"]) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-native-update",
|
"name": "react-native-update",
|
||||||
"version": "10.31.1",
|
"version": "10.34.1",
|
||||||
"description": "react-native hot update",
|
"description": "react-native hot update",
|
||||||
"main": "src/index",
|
"main": "src/index",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
"lint": "eslint \"src/*.@(ts|tsx|js|jsx)\" && tsc --noEmit",
|
"lint": "eslint \"src/*.@(ts|tsx|js|jsx)\" && tsc --noEmit",
|
||||||
"submodule": "git submodule update --init --recursive",
|
"submodule": "git submodule update --init --recursive",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"build-lib": "bun submodule && $ANDROID_HOME/ndk/20.1.5948944/ndk-build NDK_PROJECT_PATH=android APP_BUILD_SCRIPT=android/jni/Android.mk NDK_APPLICATION_MK=android/jni/Application.mk NDK_LIBS_OUT=android/lib",
|
"build:so": "bun submodule && $ANDROID_HOME/ndk/28.2.13676358/ndk-build NDK_PROJECT_PATH=android APP_BUILD_SCRIPT=android/jni/Android.mk NDK_APPLICATION_MK=android/jni/Application.mk NDK_LIBS_OUT=android/lib",
|
||||||
"build:ios-debug": "cd Example/testHotUpdate && bun && detox build --configuration ios.sim.debug",
|
"build:ios-debug": "cd Example/testHotUpdate && bun && detox build --configuration ios.sim.debug",
|
||||||
"build:ios-release": "cd Example/testHotUpdate && bun && detox build --configuration ios.sim.release",
|
"build:ios-release": "cd Example/testHotUpdate && bun && detox build --configuration ios.sim.release",
|
||||||
"test:ios-debug": "cd Example/testHotUpdate && detox test --configuration ios.sim.debug",
|
"test:ios-debug": "cd Example/testHotUpdate && detox test --configuration ios.sim.debug",
|
||||||
@@ -72,6 +72,5 @@
|
|||||||
"react-native": "0.73",
|
"react-native": "0.73",
|
||||||
"ts-jest": "^29.3.2",
|
"ts-jest": "^29.3.2",
|
||||||
"typescript": "^5.6.3"
|
"typescript": "^5.6.3"
|
||||||
},
|
}
|
||||||
"packageManager": "yarn@1.22.21+sha1.1959a18351b811cdeedbd484a8f86c3cc3bbaf72"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
buildTime,
|
buildTime,
|
||||||
cInfo,
|
cInfo,
|
||||||
currentVersion,
|
currentVersion,
|
||||||
getCurrentVersionInfo,
|
currentVersionInfo,
|
||||||
isFirstTime,
|
isFirstTime,
|
||||||
isRolledBack,
|
isRolledBack,
|
||||||
packageVersion,
|
packageVersion,
|
||||||
@@ -93,7 +93,6 @@ export class Pushy {
|
|||||||
clientType: 'Pushy' | 'Cresc' = 'Pushy';
|
clientType: 'Pushy' | 'Cresc' = 'Pushy';
|
||||||
lastChecking?: number;
|
lastChecking?: number;
|
||||||
lastRespJson?: Promise<CheckResult>;
|
lastRespJson?: Promise<CheckResult>;
|
||||||
lastRespText?: Promise<string>;
|
|
||||||
|
|
||||||
version = cInfo.rnu;
|
version = cInfo.rnu;
|
||||||
loggerPromise = (() => {
|
loggerPromise = (() => {
|
||||||
@@ -116,7 +115,7 @@ export class Pushy {
|
|||||||
|
|
||||||
if (Platform.OS === 'ios' || Platform.OS === 'android') {
|
if (Platform.OS === 'ios' || Platform.OS === 'android') {
|
||||||
if (!options.appKey) {
|
if (!options.appKey) {
|
||||||
throw new Error(i18n.t('error_appkey_required'));
|
throw Error(i18n.t('error_appkey_required'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +163,6 @@ export class Pushy {
|
|||||||
log(type + ' ' + message);
|
log(type + ' ' + message);
|
||||||
await this.loggerPromise.promise;
|
await this.loggerPromise.promise;
|
||||||
const { logger = noop, appKey } = this.options;
|
const { logger = noop, appKey } = this.options;
|
||||||
const info = await getCurrentVersionInfo();
|
|
||||||
const overridePackageVersion = this.options.overridePackageVersion;
|
const overridePackageVersion = this.options.overridePackageVersion;
|
||||||
logger({
|
logger({
|
||||||
type,
|
type,
|
||||||
@@ -176,7 +174,7 @@ export class Pushy {
|
|||||||
overridePackageVersion,
|
overridePackageVersion,
|
||||||
buildTime,
|
buildTime,
|
||||||
message,
|
message,
|
||||||
...info,
|
...currentVersionInfo,
|
||||||
...data,
|
...data,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -293,10 +291,10 @@ export class Pushy {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
this.throwIfEnabled(new Error('errorCheckingUseBackup'));
|
this.throwIfEnabled(Error('errorCheckingUseBackup'));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.throwIfEnabled(new Error('errorCheckingGetBackup'));
|
this.throwIfEnabled(Error('errorCheckingGetBackup'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!resp) {
|
if (!resp) {
|
||||||
@@ -304,21 +302,21 @@ export class Pushy {
|
|||||||
type: 'errorChecking',
|
type: 'errorChecking',
|
||||||
message: this.t('error_cannot_connect_server'),
|
message: this.t('error_cannot_connect_server'),
|
||||||
});
|
});
|
||||||
this.throwIfEnabled(new Error('errorChecking'));
|
this.throwIfEnabled(Error('errorChecking'));
|
||||||
return this.lastRespJson ? await this.lastRespJson : emptyObj;
|
return this.lastRespJson ? await this.lastRespJson : emptyObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resp.status !== 200) {
|
if (!resp.ok) {
|
||||||
|
const respText = await resp.text();
|
||||||
const errorMessage = this.t('error_http_status', {
|
const errorMessage = this.t('error_http_status', {
|
||||||
status: resp.status,
|
status: resp.status,
|
||||||
statusText: resp.statusText,
|
statusText: respText,
|
||||||
});
|
});
|
||||||
this.report({
|
this.report({
|
||||||
type: 'errorChecking',
|
type: 'errorChecking',
|
||||||
message: errorMessage,
|
message: errorMessage,
|
||||||
});
|
});
|
||||||
this.throwIfEnabled(new Error(errorMessage));
|
this.throwIfEnabled(Error(errorMessage));
|
||||||
log('error checking response:', resp.status, await resp.text());
|
|
||||||
return this.lastRespJson ? await this.lastRespJson : emptyObj;
|
return this.lastRespJson ? await this.lastRespJson : emptyObj;
|
||||||
}
|
}
|
||||||
this.lastRespJson = resp.json();
|
this.lastRespJson = resp.json();
|
||||||
@@ -435,7 +433,7 @@ export class Pushy {
|
|||||||
message: e.message,
|
message: e.message,
|
||||||
});
|
});
|
||||||
errorMessages.push(errorMessage);
|
errorMessages.push(errorMessage);
|
||||||
lastError = new Error(errorMessage);
|
lastError = Error(errorMessage);
|
||||||
log(errorMessage);
|
log(errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -454,7 +452,7 @@ export class Pushy {
|
|||||||
message: e.message,
|
message: e.message,
|
||||||
});
|
});
|
||||||
errorMessages.push(errorMessage);
|
errorMessages.push(errorMessage);
|
||||||
lastError = new Error(errorMessage);
|
lastError = Error(errorMessage);
|
||||||
log(errorMessage);
|
log(errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -474,7 +472,7 @@ export class Pushy {
|
|||||||
message: e.message,
|
message: e.message,
|
||||||
});
|
});
|
||||||
errorMessages.push(errorMessage);
|
errorMessages.push(errorMessage);
|
||||||
lastError = new Error(errorMessage);
|
lastError = Error(errorMessage);
|
||||||
log(errorMessage);
|
log(errorMessage);
|
||||||
}
|
}
|
||||||
} else if (__DEV__) {
|
} else if (__DEV__) {
|
||||||
@@ -532,7 +530,7 @@ export class Pushy {
|
|||||||
}
|
}
|
||||||
if (sharedState.apkStatus === 'downloaded') {
|
if (sharedState.apkStatus === 'downloaded') {
|
||||||
this.report({ type: 'errorInstallApk' });
|
this.report({ type: 'errorInstallApk' });
|
||||||
this.throwIfEnabled(new Error('errorInstallApk'));
|
this.throwIfEnabled(Error('errorInstallApk'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Platform.Version <= 23) {
|
if (Platform.Version <= 23) {
|
||||||
@@ -542,7 +540,7 @@ export class Pushy {
|
|||||||
);
|
);
|
||||||
if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
|
if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
|
||||||
this.report({ type: 'rejectStoragePermission' });
|
this.report({ type: 'rejectStoragePermission' });
|
||||||
this.throwIfEnabled(new Error('rejectStoragePermission'));
|
this.throwIfEnabled(Error('rejectStoragePermission'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
@@ -575,7 +573,7 @@ export class Pushy {
|
|||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
sharedState.apkStatus = null;
|
sharedState.apkStatus = null;
|
||||||
this.report({ type: 'errorDownloadAndInstallApk' });
|
this.report({ type: 'errorDownloadAndInstallApk' });
|
||||||
this.throwIfEnabled(new Error('errorDownloadAndInstallApk'));
|
this.throwIfEnabled(Error('errorDownloadAndInstallApk'));
|
||||||
});
|
});
|
||||||
sharedState.apkStatus = 'downloaded';
|
sharedState.apkStatus = 'downloaded';
|
||||||
if (sharedState.progressHandlers[progressKey]) {
|
if (sharedState.progressHandlers[progressKey]) {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const PushyModule =
|
|||||||
export const UpdateModule = PushyModule;
|
export const UpdateModule = PushyModule;
|
||||||
|
|
||||||
if (!PushyModule) {
|
if (!PushyModule) {
|
||||||
throw new Error(
|
throw Error(
|
||||||
'Failed to load react-native-update native module, please try to recompile',
|
'Failed to load react-native-update native module, please try to recompile',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ import { Pushy, Cresc, sharedState } from './client';
|
|||||||
import { currentVersion, packageVersion, getCurrentVersionInfo, currentVersionInfo } from './core';
|
import { currentVersion, packageVersion, getCurrentVersionInfo, currentVersionInfo } from './core';
|
||||||
import {
|
import {
|
||||||
CheckResult,
|
CheckResult,
|
||||||
MixedCheckResult,
|
|
||||||
ProgressData,
|
ProgressData,
|
||||||
UpdateTestPayload,
|
UpdateTestPayload,
|
||||||
|
VersionInfo,
|
||||||
} from './type';
|
} from './type';
|
||||||
import { UpdateContext } from './context';
|
import { UpdateContext } from './context';
|
||||||
import { URL } from 'react-native-url-polyfill';
|
import { URL } from 'react-native-url-polyfill';
|
||||||
@@ -163,7 +163,7 @@ export const UpdateProvider = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lastChecking.current = now;
|
lastChecking.current = now;
|
||||||
let rootInfo: MixedCheckResult | undefined;
|
let rootInfo: CheckResult | undefined;
|
||||||
try {
|
try {
|
||||||
rootInfo = await client.checkUpdate(extra);
|
rootInfo = await client.checkUpdate(extra);
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
@@ -175,12 +175,12 @@ export const UpdateProvider = ({
|
|||||||
if (!rootInfo) {
|
if (!rootInfo) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const versions = rootInfo.versions || [rootInfo as CheckResult];
|
const versions = [rootInfo.expVersion, rootInfo].filter(Boolean) as VersionInfo[];
|
||||||
delete rootInfo.versions;
|
delete rootInfo.expVersion;
|
||||||
for (const versionInfo of versions) {
|
for (const versionInfo of versions) {
|
||||||
const info: CheckResult = {
|
const info: CheckResult = {
|
||||||
...versionInfo,
|
|
||||||
...rootInfo,
|
...rootInfo,
|
||||||
|
...versionInfo,
|
||||||
};
|
};
|
||||||
const rollout = info.config?.rollout?.[packageVersion];
|
const rollout = info.config?.rollout?.[packageVersion];
|
||||||
if (info.update && rollout) {
|
if (info.update && rollout) {
|
||||||
@@ -242,7 +242,7 @@ export const UpdateProvider = ({
|
|||||||
alertUpdate(
|
alertUpdate(
|
||||||
client.t('alert_title'),
|
client.t('alert_title'),
|
||||||
client.t('alert_new_version_found', {
|
client.t('alert_new_version_found', {
|
||||||
name: info.name,
|
name: info.name!,
|
||||||
description: info.description,
|
description: info.description,
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
|
|||||||
10
src/type.ts
10
src/type.ts
@@ -24,15 +24,11 @@ interface RootResult {
|
|||||||
paths?: string[];
|
paths?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CheckResult = RootResult & VersionInfo;
|
export type CheckResult = RootResult &
|
||||||
|
Partial<VersionInfo> & {
|
||||||
export type CheckResultV2 = RootResult & {
|
expVersion?: VersionInfo;
|
||||||
versions?: VersionInfo[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MixedCheckResult = CheckResult | CheckResultV2;
|
|
||||||
|
|
||||||
|
|
||||||
export interface ProgressData {
|
export interface ProgressData {
|
||||||
hash: string;
|
hash: string;
|
||||||
received: number;
|
received: number;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export function promiseAny<T>(promises: Promise<T>[]) {
|
|||||||
.catch(() => {
|
.catch(() => {
|
||||||
count++;
|
count++;
|
||||||
if (count === promises.length) {
|
if (count === promises.length) {
|
||||||
reject(new Error(i18n.t('error_all_promises_rejected')));
|
reject(Error(i18n.t('error_all_promises_rejected')));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -51,7 +51,7 @@ const ping = isWeb
|
|||||||
return finalUrl;
|
return finalUrl;
|
||||||
}
|
}
|
||||||
log('ping failed', url, status, statusText);
|
log('ping failed', url, status, statusText);
|
||||||
throw new Error(i18n.t('error_ping_failed'));
|
throw Error(i18n.t('error_ping_failed'));
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
pingFinished = true;
|
pingFinished = true;
|
||||||
@@ -60,7 +60,7 @@ const ping = isWeb
|
|||||||
}),
|
}),
|
||||||
new Promise((_, reject) =>
|
new Promise((_, reject) =>
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
reject(new Error(i18n.t('error_ping_timeout')));
|
reject(Error(i18n.t('error_ping_timeout')));
|
||||||
if (!pingFinished) {
|
if (!pingFinished) {
|
||||||
log('ping timeout', url);
|
log('ping timeout', url);
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ export const enhancedFetch = async (
|
|||||||
if (r.ok) {
|
if (r.ok) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
throw new Error(
|
throw Error(
|
||||||
i18n.t('error_http_status', {
|
i18n.t('error_http_status', {
|
||||||
status: r.status,
|
status: r.status,
|
||||||
statusText: r.statusText,
|
statusText: r.statusText,
|
||||||
|
|||||||
Reference in New Issue
Block a user