同步操作将从 hackcat/react-native-code-push 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
import { AcquisitionManager as Sdk } from "code-push/script/acquisition-sdk";import { Alert } from "./AlertAdapter";import requestFetchAdapter from "./request-fetch-adapter";import { AppState, Platform } from "react-native";import RestartManager from "./RestartManager";import log from "./logging";import hoistStatics from 'hoist-non-react-statics';let NativeCodePush = require("react-native").NativeModules.CodePush;const PackageMixins = require("./package-mixins")(NativeCodePush);async function checkForUpdate(deploymentKey = null, handleBinaryVersionMismatchCallback = null) {/** Before we ask the server if an update exists, we* need to retrieve three pieces of information from the* native side: deployment key, app version (e.g. 1.0.1)* and the hash of the currently running update (if there is one).* This allows the client to only receive updates which are targetted* for their specific deployment and version and which are actually* different from the CodePush update they have already installed.*/const nativeConfig = await getConfiguration();/** If a deployment key was explicitly provided,* then let's override the one we retrieved* from the native-side of the app. This allows* dynamically "redirecting" end-users at different* deployments (e.g. an early access deployment for insiders).*/const config = deploymentKey ? { ...nativeConfig, ...{ deploymentKey } } : nativeConfig;const sdk = getPromisifiedSdk(requestFetchAdapter, config);// Use dynamically overridden getCurrentPackage() during tests.const localPackage = await module.exports.getCurrentPackage();/** If the app has a previously installed update, and that update* was targetted at the same app version that is currently running,* then we want to use its package hash to determine whether a new* release has been made on the server. Otherwise, we only need* to send the app version to the server, since we are interested* in any updates for current app store version, regardless of hash.*/let queryPackage;if (localPackage) {queryPackage = localPackage;} else {queryPackage = { appVersion: config.appVersion };if (Platform.OS === "ios" && config.packageHash) {queryPackage.packageHash = config.packageHash;}}const update = await sdk.queryUpdateWithCurrentPackage(queryPackage);/** There are four cases where checkForUpdate will resolve to null:* ----------------------------------------------------------------* 1) The server said there isn't an update. This is the most common case.* 2) The server said there is an update but it requires a newer binary version.* This would occur when end-users are running an older app store version than* is available, and CodePush is making sure they don't get an update that* potentially wouldn't be compatible with what they are running.* 3) The server said there is an update, but the update's hash is the same as* the currently running update. This should _never_ happen, unless there is a* bug in the server, but we're adding this check just to double-check that the* client app is resilient to a potential issue with the update check.* 4) The server said there is an update, but the update's hash is the same as that* of the binary's currently running version. This should only happen in Android -* unlike iOS, we don't attach the binary's hash to the updateCheck request* because we want to avoid having to install diff updates against the binary's* version, which we can't do yet on Android.*/if (!update || update.updateAppVersion ||localPackage && (update.packageHash === localPackage.packageHash) ||(!localPackage || localPackage._isDebugOnly) && config.packageHash === update.packageHash) {if (update && update.updateAppVersion) {log("An update is available but it is not targeting the binary version of your app.");if (handleBinaryVersionMismatchCallback && typeof handleBinaryVersionMismatchCallback === "function") {handleBinaryVersionMismatchCallback(update)}}return null;} else {const remotePackage = { ...update, ...PackageMixins.remote(sdk.reportStatusDownload) };remotePackage.failedInstall = await NativeCodePush.isFailedUpdate(remotePackage.packageHash);remotePackage.deploymentKey = deploymentKey || nativeConfig.deploymentKey;return remotePackage;}}const getConfiguration = (() => {let config;return async function getConfiguration() {if (config) {return config;} else if (testConfig) {return testConfig;} else {config = await NativeCodePush.getConfiguration();return config;}}})();async function getCurrentPackage() {return await getUpdateMetadata(CodePush.UpdateState.LATEST);}async function getUpdateMetadata(updateState) {let updateMetadata = await NativeCodePush.getUpdateMetadata(updateState || CodePush.UpdateState.RUNNING);if (updateMetadata) {updateMetadata = {...PackageMixins.local, ...updateMetadata};updateMetadata.failedInstall = await NativeCodePush.isFailedUpdate(updateMetadata.packageHash);updateMetadata.isFirstRun = await NativeCodePush.isFirstRun(updateMetadata.packageHash);}return updateMetadata;}function getPromisifiedSdk(requestFetchAdapter, config) {// Use dynamically overridden AcquisitionSdk during tests.const sdk = new module.exports.AcquisitionSdk(requestFetchAdapter, config);sdk.queryUpdateWithCurrentPackage = (queryPackage) => {return new Promise((resolve, reject) => {module.exports.AcquisitionSdk.prototype.queryUpdateWithCurrentPackage.call(sdk, queryPackage, (err, update) => {if (err) {reject(err);} else {resolve(update);}});});};sdk.reportStatusDeploy = (deployedPackage, status, previousLabelOrAppVersion, previousDeploymentKey) => {return new Promise((resolve, reject) => {module.exports.AcquisitionSdk.prototype.reportStatusDeploy.call(sdk, deployedPackage, status, previousLabelOrAppVersion, previousDeploymentKey, (err) => {if (err) {reject(err);} else {resolve();}});});};sdk.reportStatusDownload = (downloadedPackage) => {return new Promise((resolve, reject) => {module.exports.AcquisitionSdk.prototype.reportStatusDownload.call(sdk, downloadedPackage, (err) => {if (err) {reject(err);} else {resolve();}});});};return sdk;}// This ensures that notifyApplicationReadyInternal is only called once// in the lifetime of this module instance.const notifyApplicationReady = (() => {let notifyApplicationReadyPromise;return () => {if (!notifyApplicationReadyPromise) {notifyApplicationReadyPromise = notifyApplicationReadyInternal();}return notifyApplicationReadyPromise;};})();async function notifyApplicationReadyInternal() {await NativeCodePush.notifyApplicationReady();const statusReport = await NativeCodePush.getNewStatusReport();statusReport && tryReportStatus(statusReport); // Don't wait for this to complete.return statusReport;}async function tryReportStatus(statusReport, resumeListener) {const config = await getConfiguration();const previousLabelOrAppVersion = statusReport.previousLabelOrAppVersion;const previousDeploymentKey = statusReport.previousDeploymentKey || config.deploymentKey;try {if (statusReport.appVersion) {log(`Reporting binary update (${statusReport.appVersion})`);const sdk = getPromisifiedSdk(requestFetchAdapter, config);await sdk.reportStatusDeploy(/* deployedPackage */ null, /* status */ null, previousLabelOrAppVersion, previousDeploymentKey);} else {const label = statusReport.package.label;if (statusReport.status === "DeploymentSucceeded") {log(`Reporting CodePush update success (${label})`);} else {log(`Reporting CodePush update rollback (${label})`);}config.deploymentKey = statusReport.package.deploymentKey;const sdk = getPromisifiedSdk(requestFetchAdapter, config);await sdk.reportStatusDeploy(statusReport.package, statusReport.status, previousLabelOrAppVersion, previousDeploymentKey);}NativeCodePush.recordStatusReported(statusReport);resumeListener && AppState.removeEventListener("change", resumeListener);} catch (e) {log(`Report status failed: ${JSON.stringify(statusReport)}`);NativeCodePush.saveStatusReportForRetry(statusReport);// Try again when the app resumesif (!resumeListener) {resumeListener = async (newState) => {if (newState !== "active") return;const refreshedStatusReport = await NativeCodePush.getNewStatusReport();if (refreshedStatusReport) {tryReportStatus(refreshedStatusReport, resumeListener);} else {AppState.removeEventListener("change", resumeListener);}};AppState.addEventListener("change", resumeListener);}}}var testConfig;// This function is only used for tests. Replaces the default SDK, configuration and native bridgefunction setUpTestDependencies(testSdk, providedTestConfig, testNativeBridge) {if (testSdk) module.exports.AcquisitionSdk = testSdk;if (providedTestConfig) testConfig = providedTestConfig;if (testNativeBridge) NativeCodePush = testNativeBridge;}// This function allows only one syncInternal operation to proceed at any given time.// Parallel calls to sync() while one is ongoing yields CodePush.SyncStatus.SYNC_IN_PROGRESS.const sync = (() => {let syncInProgress = false;const setSyncCompleted = () => { syncInProgress = false; };return (options = {}, syncStatusChangeCallback, downloadProgressCallback, handleBinaryVersionMismatchCallback) => {let syncStatusCallbackWithTryCatch, downloadProgressCallbackWithTryCatch;if (typeof syncStatusChangeCallback === "function") {syncStatusCallbackWithTryCatch = (...args) => {try {syncStatusChangeCallback(...args);} catch (error) {log(`An error has occurred : ${error.stack}`);}}}if (typeof downloadProgressCallback === "function") {downloadProgressCallbackWithTryCatch = (...args) => {try {downloadProgressCallback(...args);} catch (error) {log(`An error has occurred: ${error.stack}`);}}}if (syncInProgress) {typeof syncStatusCallbackWithTryCatch === "function"? syncStatusCallbackWithTryCatch(CodePush.SyncStatus.SYNC_IN_PROGRESS): log("Sync already in progress.");return Promise.resolve(CodePush.SyncStatus.SYNC_IN_PROGRESS);}syncInProgress = true;const syncPromise = syncInternal(options, syncStatusCallbackWithTryCatch, downloadProgressCallbackWithTryCatch, handleBinaryVersionMismatchCallback);syncPromise.then(setSyncCompleted).catch(setSyncCompleted);return syncPromise;};})();/** The syncInternal method provides a simple, one-line experience for* incorporating the check, download and installation of an update.** It simply composes the existing API methods together and adds additional* support for respecting mandatory updates, ignoring previously failed* releases, and displaying a standard confirmation UI to the end-user* when an update is available.*/async function syncInternal(options = {}, syncStatusChangeCallback, downloadProgressCallback, handleBinaryVersionMismatchCallback) {let resolvedInstallMode;const syncOptions = {deploymentKey: null,ignoreFailedUpdates: true,installMode: CodePush.InstallMode.ON_NEXT_RESTART,mandatoryInstallMode: CodePush.InstallMode.IMMEDIATE,minimumBackgroundDuration: 0,updateDialog: null,...options};syncStatusChangeCallback = typeof syncStatusChangeCallback === "function"? syncStatusChangeCallback: (syncStatus) => {switch(syncStatus) {case CodePush.SyncStatus.CHECKING_FOR_UPDATE:log("Checking for update.");break;case CodePush.SyncStatus.AWAITING_USER_ACTION:log("Awaiting user action.");break;case CodePush.SyncStatus.DOWNLOADING_PACKAGE:log("Downloading package.");break;case CodePush.SyncStatus.INSTALLING_UPDATE:log("Installing update.");break;case CodePush.SyncStatus.UP_TO_DATE:log("App is up to date.");break;case CodePush.SyncStatus.UPDATE_IGNORED:log("User cancelled the update.");break;case CodePush.SyncStatus.UPDATE_INSTALLED:if (resolvedInstallMode == CodePush.InstallMode.ON_NEXT_RESTART) {log("Update is installed and will be run on the next app restart.");} else if (resolvedInstallMode == CodePush.InstallMode.ON_NEXT_RESUME) {if (syncOptions.minimumBackgroundDuration > 0) {log(`Update is installed and will be run after the app has been in the background for at least ${syncOptions.minimumBackgroundDuration} seconds.`);} else {log("Update is installed and will be run when the app next resumes.");}}break;case CodePush.SyncStatus.UNKNOWN_ERROR:log("An unknown error occurred.");break;}};try {await CodePush.notifyApplicationReady();syncStatusChangeCallback(CodePush.SyncStatus.CHECKING_FOR_UPDATE);const remotePackage = await checkForUpdate(syncOptions.deploymentKey, handleBinaryVersionMismatchCallback);const doDownloadAndInstall = async () => {syncStatusChangeCallback(CodePush.SyncStatus.DOWNLOADING_PACKAGE);const localPackage = await remotePackage.download(downloadProgressCallback);// Determine the correct install mode based on whether the update is mandatory or not.resolvedInstallMode = localPackage.isMandatory ? syncOptions.mandatoryInstallMode : syncOptions.installMode;syncStatusChangeCallback(CodePush.SyncStatus.INSTALLING_UPDATE);await localPackage.install(resolvedInstallMode, syncOptions.minimumBackgroundDuration, () => {syncStatusChangeCallback(CodePush.SyncStatus.UPDATE_INSTALLED);});return CodePush.SyncStatus.UPDATE_INSTALLED;};const updateShouldBeIgnored = remotePackage && (remotePackage.failedInstall && syncOptions.ignoreFailedUpdates);if (!remotePackage || updateShouldBeIgnored) {if (updateShouldBeIgnored) {log("An update is available, but it is being ignored due to having been previously rolled back.");}const currentPackage = await CodePush.getCurrentPackage();if (currentPackage && currentPackage.isPending) {syncStatusChangeCallback(CodePush.SyncStatus.UPDATE_INSTALLED);return CodePush.SyncStatus.UPDATE_INSTALLED;} else {syncStatusChangeCallback(CodePush.SyncStatus.UP_TO_DATE);return CodePush.SyncStatus.UP_TO_DATE;}} else if (syncOptions.updateDialog) {// updateDialog supports any truthy value (e.g. true, "goo", 12),// but we should treat a non-object value as just the default dialogif (typeof syncOptions.updateDialog !== "object") {syncOptions.updateDialog = CodePush.DEFAULT_UPDATE_DIALOG;} else {syncOptions.updateDialog = { ...CodePush.DEFAULT_UPDATE_DIALOG, ...syncOptions.updateDialog };}return await new Promise((resolve, reject) => {let message = null;let installButtonText = null;const dialogButtons = [];if (remotePackage.isMandatory) {message = syncOptions.updateDialog.mandatoryUpdateMessage;installButtonText = syncOptions.updateDialog.mandatoryContinueButtonLabel;} else {message = syncOptions.updateDialog.optionalUpdateMessage;installButtonText = syncOptions.updateDialog.optionalInstallButtonLabel;// Since this is an optional update, add a button// to allow the end-user to ignore itdialogButtons.push({text: syncOptions.updateDialog.optionalIgnoreButtonLabel,onPress: () => {syncStatusChangeCallback(CodePush.SyncStatus.UPDATE_IGNORED);resolve(CodePush.SyncStatus.UPDATE_IGNORED);}});}// Since the install button should be placed to the// right of any other button, add it lastdialogButtons.push({text: installButtonText,onPress:() => {doDownloadAndInstall().then(resolve, reject);}})// If the update has a description, and the developer// explicitly chose to display it, then set that as the messageif (syncOptions.updateDialog.appendReleaseDescription && remotePackage.description) {message += `${syncOptions.updateDialog.descriptionPrefix}${remotePackage.description}`;}syncStatusChangeCallback(CodePush.SyncStatus.AWAITING_USER_ACTION);Alert.alert(syncOptions.updateDialog.title, message, dialogButtons);});} else {return await doDownloadAndInstall();}} catch (error) {syncStatusChangeCallback(CodePush.SyncStatus.UNKNOWN_ERROR);log(error.message);throw error;}};let CodePush;function codePushify(options = {}) {let React;let ReactNative = require("react-native");try { React = require("react"); } catch (e) { }if (!React) {try { React = ReactNative.React; } catch (e) { }if (!React) {throw new Error("Unable to find the 'React' module.");}}if (!React.Component) {throw new Error(`Unable to find the "Component" class, please either:1. Upgrade to a newer version of React Native that supports it, or2. Call the codePush.sync API in your component instead of using the @codePush decorator`);}var decorator = (RootComponent) => {const extended = class CodePushComponent extends React.Component {componentDidMount() {if (options.checkFrequency === CodePush.CheckFrequency.MANUAL) {CodePush.notifyAppReady();} else {let rootComponentInstance = this.refs.rootComponent;let syncStatusCallback;if (rootComponentInstance && rootComponentInstance.codePushStatusDidChange) {syncStatusCallback = rootComponentInstance.codePushStatusDidChange;if (rootComponentInstance instanceof React.Component) {syncStatusCallback = syncStatusCallback.bind(rootComponentInstance);}}let downloadProgressCallback;if (rootComponentInstance && rootComponentInstance.codePushDownloadDidProgress) {downloadProgressCallback = rootComponentInstance.codePushDownloadDidProgress;if (rootComponentInstance instanceof React.Component) {downloadProgressCallback = downloadProgressCallback.bind(rootComponentInstance);}}let handleBinaryVersionMismatchCallback;if (rootComponentInstance && rootComponentInstance.codePushOnBinaryVersionMismatch) {handleBinaryVersionMismatchCallback = rootComponentInstance.codePushOnBinaryVersionMismatch;if (rootComponentInstance instanceof React.Component) {handleBinaryVersionMismatchCallback = handleBinaryVersionMismatchCallback.bind(rootComponentInstance);}}CodePush.sync(options, syncStatusCallback, downloadProgressCallback, handleBinaryVersionMismatchCallback);if (options.checkFrequency === CodePush.CheckFrequency.ON_APP_RESUME) {ReactNative.AppState.addEventListener("change", (newState) => {newState === "active" && CodePush.sync(options, syncStatusCallback, downloadProgressCallback);});}}}render() {const props = {...this.props};// we can set ref property on class components only (not stateless)// check it by render methodif (RootComponent.prototype.render) {props.ref = "rootComponent";}return <RootComponent {...props} />}}return hoistStatics(extended, RootComponent);}if (typeof options === "function") {// Infer that the root component was directly passed to us.return decorator(options);} else {return decorator;}}// If the "NativeCodePush" variable isn't defined, then// the app didn't properly install the native module,// and therefore, it doesn't make sense initializing// the JS interface when it wouldn't work anyways.if (NativeCodePush) {CodePush = codePushify;Object.assign(CodePush, {AcquisitionSdk: Sdk,checkForUpdate,getConfiguration,getCurrentPackage,getUpdateMetadata,log,notifyAppReady: notifyApplicationReady,notifyApplicationReady,restartApp: RestartManager.restartApp,setUpTestDependencies,sync,disallowRestart: RestartManager.disallow,allowRestart: RestartManager.allow,clearUpdates: NativeCodePush.clearUpdates,InstallMode: {IMMEDIATE: NativeCodePush.codePushInstallModeImmediate, // Restart the app immediatelyON_NEXT_RESTART: NativeCodePush.codePushInstallModeOnNextRestart, // Don't artificially restart the app. Allow the update to be "picked up" on the next app restartON_NEXT_RESUME: NativeCodePush.codePushInstallModeOnNextResume, // Restart the app the next time it is resumed from the backgroundON_NEXT_SUSPEND: NativeCodePush.codePushInstallModeOnNextSuspend // Restart the app _while_ it is in the background,// but only after it has been in the background for "minimumBackgroundDuration" seconds (0 by default),// so that user context isn't lost unless the app suspension is long enough to not matter},SyncStatus: {UP_TO_DATE: 0, // The running app is up-to-dateUPDATE_INSTALLED: 1, // The app had an optional/mandatory update that was successfully downloaded and is about to be installed.UPDATE_IGNORED: 2, // The app had an optional update and the end-user chose to ignore itUNKNOWN_ERROR: 3,SYNC_IN_PROGRESS: 4, // There is an ongoing "sync" operation in progress.CHECKING_FOR_UPDATE: 5,AWAITING_USER_ACTION: 6,DOWNLOADING_PACKAGE: 7,INSTALLING_UPDATE: 8},CheckFrequency: {ON_APP_START: 0,ON_APP_RESUME: 1,MANUAL: 2},UpdateState: {RUNNING: NativeCodePush.codePushUpdateStateRunning,PENDING: NativeCodePush.codePushUpdateStatePending,LATEST: NativeCodePush.codePushUpdateStateLatest},DeploymentStatus: {FAILED: "DeploymentFailed",SUCCEEDED: "DeploymentSucceeded",},DEFAULT_UPDATE_DIALOG: {appendReleaseDescription: false,descriptionPrefix: " Description: ",mandatoryContinueButtonLabel: "Continue",mandatoryUpdateMessage: "An update is available that must be installed.",optionalIgnoreButtonLabel: "Ignore",optionalInstallButtonLabel: "Install",optionalUpdateMessage: "An update is available. Would you like to install it?",title: "Update available"}});} else {log("The CodePush module doesn't appear to be properly installed. Please double-check that everything is setup correctly.");}module.exports = CodePush;
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。