mirror of
https://gitcode.com/gh_mirrors/re/react-native-pushy.git
synced 2025-11-22 23:46:10 +08:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33bc69c3fb | ||
|
|
5028ce31be |
@@ -60,13 +60,13 @@ export class DownloadTask {
|
|||||||
const exists = fileIo.accessSync(params.targetFile);
|
const exists = fileIo.accessSync(params.targetFile);
|
||||||
if (exists) {
|
if (exists) {
|
||||||
await fileIo.unlink(params.targetFile);
|
await fileIo.unlink(params.targetFile);
|
||||||
}else{
|
} else {
|
||||||
const targetDir = params.targetFile.substring(
|
const targetDir = params.targetFile.substring(
|
||||||
0,
|
0,
|
||||||
params.targetFile.lastIndexOf('/'),
|
params.targetFile.lastIndexOf('/'),
|
||||||
);
|
);
|
||||||
const exists = fileIo.accessSync(targetDir);
|
const exists = fileIo.accessSync(targetDir);
|
||||||
if(!exists){
|
if (!exists) {
|
||||||
await fileIo.mkdir(targetDir);
|
await fileIo.mkdir(targetDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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}`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -295,16 +296,16 @@ export class DownloadTask {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fn !== '.DS_Store'){
|
if (fn !== '.DS_Store') {
|
||||||
await zip.decompressFile(fn, params.unzipDirectory);
|
await zip.decompressFile(fn, params.unzipDirectory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|||||||
@@ -6,249 +6,276 @@ import common from '@ohos.app.ability.common';
|
|||||||
import { DownloadTaskParams } from './DownloadTaskParams';
|
import { DownloadTaskParams } from './DownloadTaskParams';
|
||||||
|
|
||||||
export class UpdateContext {
|
export class UpdateContext {
|
||||||
private context: common.UIAbilityContext;
|
private context: common.UIAbilityContext;
|
||||||
private rootDir: string;
|
private rootDir: string;
|
||||||
private preferences: preferences.Preferences;
|
private preferences: preferences.Preferences;
|
||||||
private static DEBUG: boolean = false;
|
private static DEBUG: boolean = false;
|
||||||
private static isUsingBundleUrl: boolean = false;
|
private static isUsingBundleUrl: boolean = false;
|
||||||
|
|
||||||
constructor(context: common.UIAbilityContext) {
|
constructor(context: common.UIAbilityContext) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.rootDir = context.filesDir + '/_update';
|
this.rootDir = context.filesDir + '/_update';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!fileIo.accessSync(this.rootDir)) {
|
if (!fileIo.accessSync(this.rootDir)) {
|
||||||
fileIo.mkdirSync(this.rootDir);
|
fileIo.mkdirSync(this.rootDir);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to create root directory:', e);
|
console.error('Failed to create root directory:', e);
|
||||||
}
|
|
||||||
this.initPreferences();
|
|
||||||
}
|
}
|
||||||
|
this.initPreferences();
|
||||||
|
}
|
||||||
|
|
||||||
private initPreferences() {
|
private initPreferences() {
|
||||||
try {
|
try {
|
||||||
this.preferences = preferences.getPreferencesSync(this.context, {name:'update'});
|
this.preferences = preferences.getPreferencesSync(this.context, {
|
||||||
const packageVersion = this.getPackageVersion();
|
name: 'update',
|
||||||
const storedVersion = this.preferences.getSync('packageVersion', '');
|
});
|
||||||
if(!storedVersion){
|
const packageVersion = this.getPackageVersion();
|
||||||
this.preferences.putSync('packageVersion', packageVersion);
|
const storedVersion = this.preferences.getSync('packageVersion', '');
|
||||||
this.preferences.flush();
|
if (!storedVersion) {
|
||||||
} else if (storedVersion && packageVersion !== storedVersion) {
|
this.preferences.putSync('packageVersion', packageVersion);
|
||||||
this.preferences.clear();
|
this.preferences.flush();
|
||||||
this.preferences.putSync('packageVersion', packageVersion);
|
} else if (storedVersion && packageVersion !== storedVersion) {
|
||||||
this.preferences.flush();
|
this.preferences.clear();
|
||||||
this.cleanUp();
|
this.preferences.putSync('packageVersion', packageVersion);
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to init preferences:', e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public setKv(key: string, value: string): void {
|
|
||||||
this.preferences.putSync(key, value);
|
|
||||||
this.preferences.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
public getKv(key: string): string {
|
|
||||||
return this.preferences.getSync(key, '') as string;
|
|
||||||
}
|
|
||||||
|
|
||||||
public isFirstTime(): boolean {
|
|
||||||
return this.preferences.getSync('firstTime', false) as boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
public rolledBackVersion(): string {
|
|
||||||
return this.preferences.getSync('rolledBackVersion', '') as string;
|
|
||||||
}
|
|
||||||
|
|
||||||
public markSuccess(): void {
|
|
||||||
this.preferences.putSync('firstTimeOk', true);
|
|
||||||
const lastVersion = this.preferences.getSync('lastVersion', '') as string;
|
|
||||||
const curVersion = this.preferences.getSync('currentVersion', '') as string;
|
|
||||||
|
|
||||||
if (lastVersion && lastVersion !== curVersion) {
|
|
||||||
this.preferences.deleteSync('lastVersion');
|
|
||||||
this.preferences.deleteSync(`hash_${lastVersion}`);
|
|
||||||
}
|
|
||||||
this.preferences.flush();
|
this.preferences.flush();
|
||||||
this.cleanUp();
|
this.cleanUp();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to init preferences:', e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public clearFirstTime(): void {
|
public setKv(key: string, value: string): void {
|
||||||
this.preferences.putSync('firstTime', false);
|
this.preferences.putSync(key, value);
|
||||||
this.preferences.flush();
|
this.preferences.flush();
|
||||||
this.cleanUp();
|
}
|
||||||
|
|
||||||
|
public getKv(key: string): string {
|
||||||
|
return this.preferences.getSync(key, '') as string;
|
||||||
|
}
|
||||||
|
|
||||||
|
public isFirstTime(): boolean {
|
||||||
|
return this.preferences.getSync('firstTime', false) as boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
public rolledBackVersion(): string {
|
||||||
|
return this.preferences.getSync('rolledBackVersion', '') as string;
|
||||||
|
}
|
||||||
|
|
||||||
|
public markSuccess(): void {
|
||||||
|
this.preferences.putSync('firstTimeOk', true);
|
||||||
|
const lastVersion = this.preferences.getSync('lastVersion', '') as string;
|
||||||
|
const curVersion = this.preferences.getSync('currentVersion', '') as string;
|
||||||
|
|
||||||
|
if (lastVersion && lastVersion !== curVersion) {
|
||||||
|
this.preferences.deleteSync('lastVersion');
|
||||||
|
this.preferences.deleteSync(`hash_${lastVersion}`);
|
||||||
}
|
}
|
||||||
|
this.preferences.flush();
|
||||||
|
this.cleanUp();
|
||||||
|
}
|
||||||
|
|
||||||
public clearRollbackMark(): void {
|
public clearFirstTime(): void {
|
||||||
this.preferences.putSync('rolledBackVersion', null);
|
this.preferences.putSync('firstTime', false);
|
||||||
this.preferences.flush();
|
this.preferences.flush();
|
||||||
this.cleanUp();
|
this.cleanUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
public clearRollbackMark(): void {
|
||||||
|
this.preferences.putSync('rolledBackVersion', null);
|
||||||
|
this.preferences.flush();
|
||||||
|
this.cleanUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async downloadFullUpdate(
|
||||||
|
url: string,
|
||||||
|
hash: string,
|
||||||
|
listener: DownloadFileListener,
|
||||||
|
): Promise<void> {
|
||||||
|
try {
|
||||||
|
const params = new DownloadTaskParams();
|
||||||
|
params.type = DownloadTaskParams.TASK_TYPE_PATCH_FULL;
|
||||||
|
params.url = url;
|
||||||
|
params.hash = hash;
|
||||||
|
params.listener = listener;
|
||||||
|
params.targetFile = `${this.rootDir}/${hash}.ppk`;
|
||||||
|
const downloadTask = new DownloadTask(this.context);
|
||||||
|
await downloadTask.execute(params);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to download full update:', e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async downloadFullUpdate(url: string, hash: string, listener: DownloadFileListener): Promise<void> {
|
public async downloadFile(
|
||||||
try {
|
url: string,
|
||||||
const params = new DownloadTaskParams();
|
hash: string,
|
||||||
params.type = DownloadTaskParams.TASK_TYPE_PATCH_FULL;
|
fileName: string,
|
||||||
params.url = url;
|
listener: DownloadFileListener,
|
||||||
params.hash = hash;
|
): Promise<void> {
|
||||||
params.listener = listener;
|
const params = new DownloadTaskParams();
|
||||||
params.targetFile = `${this.rootDir}/${hash}.ppk`;
|
params.type = DownloadTaskParams.TASK_TYPE_PLAIN_DOWNLOAD;
|
||||||
const downloadTask = new DownloadTask(this.context);
|
params.url = url;
|
||||||
await downloadTask.execute(params);
|
params.hash = hash;
|
||||||
} catch (e) {
|
params.listener = listener;
|
||||||
console.error('Failed to download full update:', e);
|
params.targetFile = this.rootDir + '/' + fileName;
|
||||||
|
|
||||||
|
const downloadTask = new DownloadTask(this.context);
|
||||||
|
await downloadTask.execute(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async downloadPatchFromPpk(
|
||||||
|
url: string,
|
||||||
|
hash: string,
|
||||||
|
originHash: string,
|
||||||
|
listener: DownloadFileListener,
|
||||||
|
): Promise<void> {
|
||||||
|
const params = new DownloadTaskParams();
|
||||||
|
params.type = DownloadTaskParams.TASK_TYPE_PATCH_FROM_PPK;
|
||||||
|
params.url = url;
|
||||||
|
params.hash = hash;
|
||||||
|
params.originHash = originHash;
|
||||||
|
params.listener = listener;
|
||||||
|
params.targetFile = `${this.rootDir}/${originHash}_${hash}.ppk.patch`;
|
||||||
|
params.unzipDirectory = `${this.rootDir}/${hash}`;
|
||||||
|
params.originDirectory = `${this.rootDir}/${params.originHash}`;
|
||||||
|
|
||||||
|
const downloadTask = new DownloadTask(this.context);
|
||||||
|
await downloadTask.execute(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async downloadPatchFromPackage(
|
||||||
|
url: string,
|
||||||
|
hash: string,
|
||||||
|
listener: DownloadFileListener,
|
||||||
|
): Promise<void> {
|
||||||
|
try {
|
||||||
|
const params = new DownloadTaskParams();
|
||||||
|
params.type = DownloadTaskParams.TASK_TYPE_PATCH_FROM_APP;
|
||||||
|
params.url = url;
|
||||||
|
params.hash = hash;
|
||||||
|
params.listener = listener;
|
||||||
|
params.targetFile = `${this.rootDir}/${hash}.app.patch`;
|
||||||
|
params.unzipDirectory = `${this.rootDir}/${hash}`;
|
||||||
|
|
||||||
|
const downloadTask = new DownloadTask(this.context);
|
||||||
|
return await downloadTask.execute(params);
|
||||||
|
} catch (e) {
|
||||||
|
throw e;
|
||||||
|
console.error('Failed to download APK patch:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public switchVersion(hash: string): void {
|
||||||
|
try {
|
||||||
|
const bundlePath = `${this.rootDir}/${hash}/bundle.harmony.js`;
|
||||||
|
if (!fileIo.accessSync(bundlePath)) {
|
||||||
|
throw Error(`Bundle version ${hash} not found.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const lastVersion = this.getKv('currentVersion');
|
||||||
|
this.setKv('currentVersion', hash);
|
||||||
|
if (lastVersion && lastVersion !== hash) {
|
||||||
|
this.setKv('lastVersion', lastVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setKv('firstTime', 'true');
|
||||||
|
this.setKv('firstTimeOk', 'false');
|
||||||
|
this.setKv('rolledBackVersion', '');
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to switch version:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getBundleUrl(
|
||||||
|
context: common.UIAbilityContext,
|
||||||
|
defaultAssetsUrl?: string,
|
||||||
|
): string {
|
||||||
|
return new UpdateContext(context).getBundleUrl(defaultAssetsUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getBundleUrl(defaultAssetsUrl?: string): string {
|
||||||
|
UpdateContext.isUsingBundleUrl = true;
|
||||||
|
const currentVersion = this.getCurrentVersion();
|
||||||
|
if (!currentVersion) {
|
||||||
|
return defaultAssetsUrl;
|
||||||
|
}
|
||||||
|
if (!this.isFirstTime()) {
|
||||||
|
if (!this.preferences.getSync('firstTimeOk', true)) {
|
||||||
|
return this.rollBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let version = currentVersion;
|
||||||
|
while (version) {
|
||||||
|
const bundleFile = `${this.rootDir}/${version}/bundle.harmony.js`;
|
||||||
|
try {
|
||||||
|
if (!fileIo.accessSync(bundleFile)) {
|
||||||
|
console.error(`Bundle version ${version} not found.`);
|
||||||
|
version = this.rollBack();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
return bundleFile;
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to access bundle file:', e);
|
||||||
|
version = this.rollBack();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return defaultAssetsUrl;
|
||||||
|
}
|
||||||
|
|
||||||
public async downloadFile(url: string, hash: string, fileName: string, listener: DownloadFileListener): Promise<void> {
|
getPackageVersion(): string {
|
||||||
const params = new DownloadTaskParams();
|
let bundleFlags =
|
||||||
params.type = DownloadTaskParams.TASK_TYPE_PLAIN_DOWNLOAD;
|
bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION;
|
||||||
params.url = url;
|
let packageVersion = '';
|
||||||
params.hash = hash;
|
try {
|
||||||
params.listener = listener;
|
const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleFlags);
|
||||||
params.targetFile = this.rootDir + '/' + fileName;
|
packageVersion = bundleInfo?.versionName || 'Unknown';
|
||||||
|
} catch (error) {
|
||||||
const downloadTask = new DownloadTask(this.context);
|
console.error('获取包信息失败:', error);
|
||||||
await downloadTask.execute(params);
|
|
||||||
}
|
}
|
||||||
|
return packageVersion;
|
||||||
|
}
|
||||||
|
|
||||||
public async downloadPatchFromPpk(url: string, hash: string, originHash: string, listener: DownloadFileListener): Promise<void> {
|
public getCurrentVersion(): string {
|
||||||
const params = new DownloadTaskParams();
|
const currentVersion = this.getKv('currentVersion');
|
||||||
params.type = DownloadTaskParams.TASK_TYPE_PATCH_FROM_PPK;
|
return currentVersion;
|
||||||
params.url = url;
|
}
|
||||||
params.hash = hash;
|
|
||||||
params.originHash = originHash;
|
private rollBack(): string {
|
||||||
params.listener = listener;
|
const lastVersion = this.preferences.getSync('lastVersion', '') as string;
|
||||||
params.targetFile = `${this.rootDir}/${originHash}_${hash}.ppk.patch`;
|
const currentVersion = this.preferences.getSync(
|
||||||
params.unzipDirectory = `${this.rootDir}/${hash}`;
|
'currentVersion',
|
||||||
params.originDirectory = `${this.rootDir}/${params.originHash}`;
|
'',
|
||||||
|
) as string;
|
||||||
const downloadTask = new DownloadTask(this.context);
|
if (!lastVersion) {
|
||||||
await downloadTask.execute(params);
|
this.preferences.deleteSync('currentVersion');
|
||||||
|
} else {
|
||||||
|
this.preferences.putSync('currentVersion', lastVersion);
|
||||||
}
|
}
|
||||||
|
this.preferences.putSync('firstTimeOk', true);
|
||||||
|
this.preferences.putSync('firstTime', false);
|
||||||
|
this.preferences.putSync('rolledBackVersion', currentVersion);
|
||||||
|
this.preferences.flush();
|
||||||
|
return lastVersion;
|
||||||
|
}
|
||||||
|
|
||||||
public async downloadPatchFromPackage(url: string, hash: string, listener: DownloadFileListener): Promise<void> {
|
private cleanUp(): void {
|
||||||
try {
|
const params = new DownloadTaskParams();
|
||||||
const params = new DownloadTaskParams();
|
params.type = DownloadTaskParams.TASK_TYPE_CLEANUP;
|
||||||
params.type = DownloadTaskParams.TASK_TYPE_PATCH_FROM_APP;
|
params.hash = this.preferences.getSync('currentVersion', '') as string;
|
||||||
params.url = url;
|
params.originHash = this.preferences.getSync('lastVersion', '') as string;
|
||||||
params.hash = hash;
|
params.unzipDirectory = this.rootDir;
|
||||||
params.listener = listener;
|
const downloadTask = new DownloadTask(this.context);
|
||||||
params.targetFile = `${this.rootDir}/${hash}.app.patch`;
|
downloadTask.execute(params);
|
||||||
params.unzipDirectory = `${this.rootDir}/${hash}`;
|
}
|
||||||
|
|
||||||
const downloadTask = new DownloadTask(this.context);
|
public getIsUsingBundleUrl(): boolean {
|
||||||
return await downloadTask.execute(params);
|
return UpdateContext.isUsingBundleUrl;
|
||||||
} catch (e) {
|
}
|
||||||
throw e;
|
|
||||||
console.error('Failed to download APK patch:', e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public switchVersion(hash: string): void {
|
|
||||||
try {
|
|
||||||
const bundlePath = `${this.rootDir}/${hash}/bundle.harmony.js`;
|
|
||||||
if (!fileIo.accessSync(bundlePath)) {
|
|
||||||
throw new Error(`Bundle version ${hash} not found.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const lastVersion = this.getKv('currentVersion');
|
|
||||||
this.setKv('currentVersion', hash);
|
|
||||||
if (lastVersion && lastVersion !== hash) {
|
|
||||||
this.setKv('lastVersion', lastVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setKv('firstTime', 'true');
|
|
||||||
this.setKv('firstTimeOk', 'false');
|
|
||||||
this.setKv('rolledBackVersion', "");
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to switch version:', e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static getBundleUrl(context: common.UIAbilityContext, defaultAssetsUrl?: string): string {
|
|
||||||
return new UpdateContext(context).getBundleUrl(defaultAssetsUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public getBundleUrl(defaultAssetsUrl?: string): string {
|
|
||||||
UpdateContext.isUsingBundleUrl = true;
|
|
||||||
const currentVersion = this.getCurrentVersion();
|
|
||||||
if (!currentVersion) {
|
|
||||||
return defaultAssetsUrl;
|
|
||||||
}
|
|
||||||
if (!this.isFirstTime()) {
|
|
||||||
if (!this.preferences.getSync('firstTimeOk', true)) {
|
|
||||||
return this.rollBack();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let version = currentVersion;
|
|
||||||
while (version) {
|
|
||||||
const bundleFile = `${this.rootDir}/${version}/bundle.harmony.js`;
|
|
||||||
try {
|
|
||||||
if (!fileIo.accessSync(bundleFile)) {
|
|
||||||
console.error(`Bundle version ${version} not found.`);
|
|
||||||
version = this.rollBack();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return bundleFile;
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to access bundle file:', e);
|
|
||||||
version = this.rollBack();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return defaultAssetsUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
getPackageVersion(): string {
|
|
||||||
let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION;
|
|
||||||
let packageVersion = '';
|
|
||||||
try {
|
|
||||||
const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleFlags);
|
|
||||||
packageVersion = bundleInfo?.versionName || "Unknown";
|
|
||||||
} catch (error) {
|
|
||||||
console.error("获取包信息失败:", error);
|
|
||||||
}
|
|
||||||
return packageVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getCurrentVersion() : string {
|
|
||||||
const currentVersion = this.getKv('currentVersion');
|
|
||||||
return currentVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
private rollBack(): string {
|
|
||||||
const lastVersion = this.preferences.getSync('lastVersion', '') as string;
|
|
||||||
const currentVersion = this.preferences.getSync('currentVersion', '') as string;
|
|
||||||
if (!lastVersion) {
|
|
||||||
this.preferences.deleteSync('currentVersion');
|
|
||||||
} else {
|
|
||||||
this.preferences.putSync('currentVersion', lastVersion);
|
|
||||||
}
|
|
||||||
this.preferences.putSync('firstTimeOk', true);
|
|
||||||
this.preferences.putSync('firstTime', false);
|
|
||||||
this.preferences.putSync('rolledBackVersion', currentVersion);
|
|
||||||
this.preferences.flush();
|
|
||||||
return lastVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
private cleanUp(): void {
|
|
||||||
const params = new DownloadTaskParams();
|
|
||||||
params.type = DownloadTaskParams.TASK_TYPE_CLEANUP;
|
|
||||||
params.hash = this.preferences.getSync('currentVersion', '') as string;
|
|
||||||
params.originHash = this.preferences.getSync('lastVersion', '') as string;
|
|
||||||
params.unzipDirectory = this.rootDir;
|
|
||||||
const downloadTask = new DownloadTask(this.context);
|
|
||||||
downloadTask.execute(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
public getIsUsingBundleUrl(): boolean {
|
|
||||||
return UpdateContext.isUsingBundleUrl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DownloadFileListener {
|
export interface DownloadFileListener {
|
||||||
onDownloadCompleted(params: DownloadTaskParams): void;
|
onDownloadCompleted(params: DownloadTaskParams): void;
|
||||||
onDownloadFailed(error: Error): void;
|
onDownloadFailed(error: Error): void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(
|
||||||
onDownloadCompleted: (params: DownloadTaskParams) => {
|
options.updateUrl,
|
||||||
return Promise.resolve();
|
options.hash,
|
||||||
|
{
|
||||||
|
onDownloadCompleted: (params: DownloadTaskParams) => {
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
onDownloadFailed: (error: Error) => {
|
||||||
|
return Promise.reject(error);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
onDownloadFailed: (error: 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,17 +178,14 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-native-update",
|
"name": "react-native-update",
|
||||||
"version": "10.31.3",
|
"version": "10.32.0",
|
||||||
"description": "react-native hot update",
|
"description": "react-native hot update",
|
||||||
"main": "src/index",
|
"main": "src/index",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -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"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,10 +292,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 +303,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 +434,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 +453,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 +473,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 +531,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 +541,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 +574,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,8 +175,8 @@ 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,
|
...versionInfo,
|
||||||
@@ -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,
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
|
|||||||
12
src/type.ts
12
src/type.ts
@@ -24,14 +24,10 @@ 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;
|
||||||
|
|||||||
@@ -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