@appzung/react-native-code-push 10.0.1 → 10.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/android/app/src/main/java/com/appzung/codepush/react/CodePush.java +3 -0
- package/android/app/src/main/java/com/appzung/codepush/react/CodePushNativeModule.java +14 -0
- package/ios/CodePush/CodePush.h +1 -0
- package/ios/CodePush/CodePush.m +64 -13
- package/ios/CodePush/CodePushConfig.m +4 -0
- package/lib/commonjs/CodePush.js +6 -2
- package/lib/commonjs/CodePush.js.map +1 -1
- package/lib/commonjs/allowRestart.js +2 -0
- package/lib/commonjs/allowRestart.js.map +1 -1
- package/lib/commonjs/checkForUpdates.js +23 -25
- package/lib/commonjs/checkForUpdates.js.map +1 -1
- package/lib/commonjs/clearUpdates.js +2 -1
- package/lib/commonjs/clearUpdates.js.map +1 -1
- package/lib/commonjs/disallowRestart.js +2 -0
- package/lib/commonjs/disallowRestart.js.map +1 -1
- package/lib/commonjs/enums/CheckFrequency.enum.js +2 -2
- package/lib/commonjs/enums/InstallMode.enum.js +7 -3
- package/lib/commonjs/enums/InstallMode.enum.js.map +1 -1
- package/lib/commonjs/enums/SyncStatus.enum.js +7 -7
- package/lib/commonjs/enums/UpdateState.enum.js +7 -6
- package/lib/commonjs/enums/UpdateState.enum.js.map +1 -1
- package/lib/commonjs/getClientUniqueId.js +16 -0
- package/lib/commonjs/getClientUniqueId.js.map +1 -0
- package/lib/commonjs/index.js +34 -13
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/internals/CodePushApiSdk.errors.js +26 -0
- package/lib/commonjs/internals/CodePushApiSdk.errors.js.map +1 -0
- package/lib/commonjs/internals/CodePushApiSdk.js +100 -0
- package/lib/commonjs/internals/CodePushApiSdk.js.map +1 -0
- package/lib/commonjs/{enums/DeploymentStatus.enum.js → internals/CodePushApiSdk.types.js} +3 -2
- package/lib/commonjs/internals/CodePushApiSdk.types.js.map +1 -0
- package/lib/commonjs/internals/RemotePackageImplementation.js +6 -5
- package/lib/commonjs/internals/RemotePackageImplementation.js.map +1 -1
- package/lib/commonjs/internals/getConfiguration.js +4 -0
- package/lib/commonjs/internals/getConfiguration.js.map +1 -1
- package/lib/commonjs/internals/utils/fetchRetry.js +59 -0
- package/lib/commonjs/internals/utils/fetchRetry.js.map +1 -0
- package/lib/commonjs/internals/utils/queryStringify.js +25 -0
- package/lib/commonjs/internals/utils/queryStringify.js.map +1 -0
- package/lib/commonjs/internals/utils/requestFetchAdapter.js +33 -0
- package/lib/commonjs/internals/utils/requestFetchAdapter.js.map +1 -0
- package/lib/commonjs/internals/version.js +1 -1
- package/lib/commonjs/notifyAppReady.js +11 -9
- package/lib/commonjs/notifyAppReady.js.map +1 -1
- package/lib/commonjs/resetClientUniqueId.js +18 -0
- package/lib/commonjs/resetClientUniqueId.js.map +1 -0
- package/lib/commonjs/restartApp.js +2 -0
- package/lib/commonjs/restartApp.js.map +1 -1
- package/lib/commonjs/sync.js +5 -3
- package/lib/commonjs/sync.js.map +1 -1
- package/lib/module/CodePush.js +6 -2
- package/lib/module/CodePush.js.map +1 -1
- package/lib/module/allowRestart.js +2 -0
- package/lib/module/allowRestart.js.map +1 -1
- package/lib/module/checkForUpdates.js +23 -25
- package/lib/module/checkForUpdates.js.map +1 -1
- package/lib/module/clearUpdates.js +2 -1
- package/lib/module/clearUpdates.js.map +1 -1
- package/lib/module/disallowRestart.js +2 -0
- package/lib/module/disallowRestart.js.map +1 -1
- package/lib/module/enums/CheckFrequency.enum.js +2 -2
- package/lib/module/enums/InstallMode.enum.js +7 -3
- package/lib/module/enums/InstallMode.enum.js.map +1 -1
- package/lib/module/enums/SyncStatus.enum.js +7 -7
- package/lib/module/enums/UpdateState.enum.js +7 -6
- package/lib/module/enums/UpdateState.enum.js.map +1 -1
- package/lib/module/getClientUniqueId.js +12 -0
- package/lib/module/getClientUniqueId.js.map +1 -0
- package/lib/module/index.js +3 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/internals/CodePushApiSdk.errors.js +20 -0
- package/lib/module/internals/CodePushApiSdk.errors.js.map +1 -0
- package/lib/module/internals/CodePushApiSdk.js +96 -0
- package/lib/module/internals/CodePushApiSdk.js.map +1 -0
- package/lib/module/{enums/DeploymentStatus.enum.js → internals/CodePushApiSdk.types.js} +2 -1
- package/lib/module/internals/CodePushApiSdk.types.js.map +1 -0
- package/lib/module/internals/RemotePackageImplementation.js +6 -5
- package/lib/module/internals/RemotePackageImplementation.js.map +1 -1
- package/lib/module/internals/getConfiguration.js +3 -0
- package/lib/module/internals/getConfiguration.js.map +1 -1
- package/lib/module/internals/utils/fetchRetry.js +55 -0
- package/lib/module/internals/utils/fetchRetry.js.map +1 -0
- package/lib/module/internals/utils/queryStringify.js +21 -0
- package/lib/module/internals/utils/queryStringify.js.map +1 -0
- package/lib/module/internals/utils/requestFetchAdapter.js +29 -0
- package/lib/module/internals/utils/requestFetchAdapter.js.map +1 -0
- package/lib/module/internals/version.js +1 -1
- package/lib/module/notifyAppReady.js +11 -9
- package/lib/module/notifyAppReady.js.map +1 -1
- package/lib/module/resetClientUniqueId.js +14 -0
- package/lib/module/resetClientUniqueId.js.map +1 -0
- package/lib/module/restartApp.js +2 -0
- package/lib/module/restartApp.js.map +1 -1
- package/lib/module/sync.js +5 -3
- package/lib/module/sync.js.map +1 -1
- package/lib/typescript/commonjs/src/CodePush.d.ts +10 -5
- package/lib/typescript/commonjs/src/CodePush.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/allowRestart.d.ts +2 -0
- package/lib/typescript/commonjs/src/allowRestart.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/checkForUpdates.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/clearUpdates.d.ts +2 -1
- package/lib/typescript/commonjs/src/clearUpdates.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/disallowRestart.d.ts +2 -0
- package/lib/typescript/commonjs/src/disallowRestart.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/enums/CheckFrequency.enum.d.ts +2 -2
- package/lib/typescript/commonjs/src/enums/InstallMode.enum.d.ts +7 -3
- package/lib/typescript/commonjs/src/enums/InstallMode.enum.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/enums/SyncStatus.enum.d.ts +7 -7
- package/lib/typescript/commonjs/src/enums/UpdateState.enum.d.ts +7 -6
- package/lib/typescript/commonjs/src/enums/UpdateState.enum.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/getClientUniqueId.d.ts +5 -0
- package/lib/typescript/commonjs/src/getClientUniqueId.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/index.d.ts +3 -1
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/internals/CodePushApiSdk.d.ts +13 -0
- package/lib/typescript/commonjs/src/internals/CodePushApiSdk.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/internals/CodePushApiSdk.errors.d.ts +9 -0
- package/lib/typescript/commonjs/src/internals/CodePushApiSdk.errors.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/internals/CodePushApiSdk.types.d.ts +101 -0
- package/lib/typescript/commonjs/src/internals/CodePushApiSdk.types.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/internals/RNAppZungCodePushModuleSpec.d.ts +1 -0
- package/lib/typescript/commonjs/src/internals/RNAppZungCodePushModuleSpec.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/internals/RemotePackageImplementation.d.ts +2 -2
- package/lib/typescript/commonjs/src/internals/RemotePackageImplementation.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/internals/getConfiguration.d.ts +1 -0
- package/lib/typescript/commonjs/src/internals/getConfiguration.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/internals/types.d.ts +2 -2
- package/lib/typescript/commonjs/src/internals/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/internals/utils/fetchRetry.d.ts +9 -0
- package/lib/typescript/commonjs/src/internals/utils/fetchRetry.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/internals/utils/queryStringify.d.ts +4 -0
- package/lib/typescript/commonjs/src/internals/utils/queryStringify.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/internals/utils/requestFetchAdapter.d.ts +3 -0
- package/lib/typescript/commonjs/src/internals/utils/requestFetchAdapter.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/internals/version.d.ts +1 -1
- package/lib/typescript/commonjs/src/notifyAppReady.d.ts +2 -0
- package/lib/typescript/commonjs/src/notifyAppReady.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/resetClientUniqueId.d.ts +5 -0
- package/lib/typescript/commonjs/src/resetClientUniqueId.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/restartApp.d.ts +2 -0
- package/lib/typescript/commonjs/src/restartApp.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/sync.d.ts +3 -1
- package/lib/typescript/commonjs/src/sync.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/types.d.ts +72 -29
- package/lib/typescript/commonjs/src/types.d.ts.map +1 -1
- package/lib/typescript/module/src/CodePush.d.ts +10 -5
- package/lib/typescript/module/src/CodePush.d.ts.map +1 -1
- package/lib/typescript/module/src/allowRestart.d.ts +2 -0
- package/lib/typescript/module/src/allowRestart.d.ts.map +1 -1
- package/lib/typescript/module/src/checkForUpdates.d.ts.map +1 -1
- package/lib/typescript/module/src/clearUpdates.d.ts +2 -1
- package/lib/typescript/module/src/clearUpdates.d.ts.map +1 -1
- package/lib/typescript/module/src/disallowRestart.d.ts +2 -0
- package/lib/typescript/module/src/disallowRestart.d.ts.map +1 -1
- package/lib/typescript/module/src/enums/CheckFrequency.enum.d.ts +2 -2
- package/lib/typescript/module/src/enums/InstallMode.enum.d.ts +7 -3
- package/lib/typescript/module/src/enums/InstallMode.enum.d.ts.map +1 -1
- package/lib/typescript/module/src/enums/SyncStatus.enum.d.ts +7 -7
- package/lib/typescript/module/src/enums/UpdateState.enum.d.ts +7 -6
- package/lib/typescript/module/src/enums/UpdateState.enum.d.ts.map +1 -1
- package/lib/typescript/module/src/getClientUniqueId.d.ts +5 -0
- package/lib/typescript/module/src/getClientUniqueId.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +3 -1
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/internals/CodePushApiSdk.d.ts +13 -0
- package/lib/typescript/module/src/internals/CodePushApiSdk.d.ts.map +1 -0
- package/lib/typescript/module/src/internals/CodePushApiSdk.errors.d.ts +9 -0
- package/lib/typescript/module/src/internals/CodePushApiSdk.errors.d.ts.map +1 -0
- package/lib/typescript/module/src/internals/CodePushApiSdk.types.d.ts +101 -0
- package/lib/typescript/module/src/internals/CodePushApiSdk.types.d.ts.map +1 -0
- package/lib/typescript/module/src/internals/RNAppZungCodePushModuleSpec.d.ts +1 -0
- package/lib/typescript/module/src/internals/RNAppZungCodePushModuleSpec.d.ts.map +1 -1
- package/lib/typescript/module/src/internals/RemotePackageImplementation.d.ts +2 -2
- package/lib/typescript/module/src/internals/RemotePackageImplementation.d.ts.map +1 -1
- package/lib/typescript/module/src/internals/getConfiguration.d.ts +1 -0
- package/lib/typescript/module/src/internals/getConfiguration.d.ts.map +1 -1
- package/lib/typescript/module/src/internals/types.d.ts +2 -2
- package/lib/typescript/module/src/internals/types.d.ts.map +1 -1
- package/lib/typescript/module/src/internals/utils/fetchRetry.d.ts +9 -0
- package/lib/typescript/module/src/internals/utils/fetchRetry.d.ts.map +1 -0
- package/lib/typescript/module/src/internals/utils/queryStringify.d.ts +4 -0
- package/lib/typescript/module/src/internals/utils/queryStringify.d.ts.map +1 -0
- package/lib/typescript/module/src/internals/utils/requestFetchAdapter.d.ts +3 -0
- package/lib/typescript/module/src/internals/utils/requestFetchAdapter.d.ts.map +1 -0
- package/lib/typescript/module/src/internals/version.d.ts +1 -1
- package/lib/typescript/module/src/notifyAppReady.d.ts +2 -0
- package/lib/typescript/module/src/notifyAppReady.d.ts.map +1 -1
- package/lib/typescript/module/src/resetClientUniqueId.d.ts +5 -0
- package/lib/typescript/module/src/resetClientUniqueId.d.ts.map +1 -0
- package/lib/typescript/module/src/restartApp.d.ts +2 -0
- package/lib/typescript/module/src/restartApp.d.ts.map +1 -1
- package/lib/typescript/module/src/sync.d.ts +3 -1
- package/lib/typescript/module/src/sync.d.ts.map +1 -1
- package/lib/typescript/module/src/types.d.ts +72 -29
- package/lib/typescript/module/src/types.d.ts.map +1 -1
- package/package.json +6 -4
- package/src/CodePush.tsx +12 -5
- package/src/allowRestart.ts +2 -0
- package/src/checkForUpdates.ts +24 -23
- package/src/clearUpdates.ts +2 -1
- package/src/disallowRestart.ts +2 -0
- package/src/enums/CheckFrequency.enum.ts +2 -2
- package/src/enums/InstallMode.enum.ts +7 -3
- package/src/enums/SyncStatus.enum.ts +7 -7
- package/src/enums/UpdateState.enum.ts +7 -6
- package/src/getClientUniqueId.ts +9 -0
- package/src/index.ts +3 -1
- package/src/internals/CodePushApiSdk.errors.ts +22 -0
- package/src/internals/CodePushApiSdk.ts +133 -0
- package/src/internals/CodePushApiSdk.types.ts +115 -0
- package/src/internals/RNAppZungCodePushModuleSpec.ts +1 -0
- package/src/internals/RemotePackageImplementation.ts +8 -7
- package/src/internals/getConfiguration.ts +4 -0
- package/src/internals/types.ts +2 -2
- package/src/internals/utils/fetchRetry.ts +72 -0
- package/src/internals/utils/queryStringify.ts +22 -0
- package/src/internals/utils/requestFetchAdapter.ts +28 -0
- package/src/internals/version.ts +1 -1
- package/src/notifyAppReady.ts +12 -13
- package/src/resetClientUniqueId.ts +11 -0
- package/src/restartApp.ts +2 -0
- package/src/sync.ts +5 -3
- package/src/types.ts +72 -29
- package/typedoc.json +9 -0
- package/docs/advanced-usage.md +0 -56
- package/docs/api-android.md +0 -22
- package/docs/api-ios.md +0 -19
- package/docs/api-js.md +0 -557
- package/docs/code-signing.md +0 -62
- package/docs/migrating-to-v10.md +0 -31
- package/docs/setup-android.md +0 -81
- package/docs/setup-ios.md +0 -108
- package/docs/setup-windows.md +0 -55
- package/lib/commonjs/enums/DeploymentStatus.enum.js.map +0 -1
- package/lib/commonjs/internals/AcquisitionSdk.js +0 -9
- package/lib/commonjs/internals/AcquisitionSdk.js.map +0 -1
- package/lib/commonjs/internals/getPromisifiedSdk.js +0 -49
- package/lib/commonjs/internals/getPromisifiedSdk.js.map +0 -1
- package/lib/commonjs/internals/utils/request-fetch-adapter.js +0 -50
- package/lib/commonjs/internals/utils/request-fetch-adapter.js.map +0 -1
- package/lib/module/enums/DeploymentStatus.enum.js.map +0 -1
- package/lib/module/internals/AcquisitionSdk.js +0 -5
- package/lib/module/internals/AcquisitionSdk.js.map +0 -1
- package/lib/module/internals/getPromisifiedSdk.js +0 -45
- package/lib/module/internals/getPromisifiedSdk.js.map +0 -1
- package/lib/module/internals/utils/request-fetch-adapter.js +0 -46
- package/lib/module/internals/utils/request-fetch-adapter.js.map +0 -1
- package/lib/typescript/commonjs/src/enums/DeploymentStatus.enum.d.ts +0 -14
- package/lib/typescript/commonjs/src/enums/DeploymentStatus.enum.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/internals/AcquisitionSdk.d.ts +0 -3
- package/lib/typescript/commonjs/src/internals/AcquisitionSdk.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/internals/getPromisifiedSdk.d.ts +0 -13
- package/lib/typescript/commonjs/src/internals/getPromisifiedSdk.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/internals/utils/request-fetch-adapter.d.ts +0 -3
- package/lib/typescript/commonjs/src/internals/utils/request-fetch-adapter.d.ts.map +0 -1
- package/lib/typescript/module/src/enums/DeploymentStatus.enum.d.ts +0 -14
- package/lib/typescript/module/src/enums/DeploymentStatus.enum.d.ts.map +0 -1
- package/lib/typescript/module/src/internals/AcquisitionSdk.d.ts +0 -3
- package/lib/typescript/module/src/internals/AcquisitionSdk.d.ts.map +0 -1
- package/lib/typescript/module/src/internals/getPromisifiedSdk.d.ts +0 -13
- package/lib/typescript/module/src/internals/getPromisifiedSdk.d.ts.map +0 -1
- package/lib/typescript/module/src/internals/utils/request-fetch-adapter.d.ts +0 -3
- package/lib/typescript/module/src/internals/utils/request-fetch-adapter.d.ts.map +0 -1
- package/src/enums/DeploymentStatus.enum.ts +0 -14
- package/src/internals/AcquisitionSdk.ts +0 -3
- package/src/internals/getPromisifiedSdk.ts +0 -72
- package/src/internals/utils/request-fetch-adapter.ts +0 -58
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { CodePushError, CodePushHttpError } from './CodePushApiSdk.errors';
|
|
2
|
+
import {
|
|
3
|
+
type ApiSdkConfiguration,
|
|
4
|
+
type ApiSdkDeployReportPackageInfo,
|
|
5
|
+
type ApiSdkDownloadReportPackageInfo,
|
|
6
|
+
type ApiSdkNativeUpdateNotification,
|
|
7
|
+
type ApiSdkQueryUpdatePackageInfo,
|
|
8
|
+
type ApiSdkRemotePackage,
|
|
9
|
+
type CheckUpdateRequestInput,
|
|
10
|
+
type CheckUpdateResponse,
|
|
11
|
+
DeploymentStatus,
|
|
12
|
+
type Http,
|
|
13
|
+
type ReportDeployInput,
|
|
14
|
+
type ReportDownloadInput,
|
|
15
|
+
} from './CodePushApiSdk.types';
|
|
16
|
+
import { queryStringify } from './utils/queryStringify';
|
|
17
|
+
|
|
18
|
+
// TODO move this to @appzung/code-push-api-sdk
|
|
19
|
+
|
|
20
|
+
export class CodePushApiSdk {
|
|
21
|
+
private configuration: ApiSdkConfiguration;
|
|
22
|
+
|
|
23
|
+
constructor(
|
|
24
|
+
private readonly httpRequester: Http.Requester,
|
|
25
|
+
configuration: ApiSdkConfiguration,
|
|
26
|
+
) {
|
|
27
|
+
this.configuration = { ...configuration };
|
|
28
|
+
if (this.configuration.serverUrl.slice(-1) !== '/') {
|
|
29
|
+
this.configuration.serverUrl += '/';
|
|
30
|
+
}
|
|
31
|
+
this.configuration.serverUrl += 'v0.1/public/codepush';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async queryUpdateWithCurrentPackage(
|
|
35
|
+
currentPackageInfo: ApiSdkQueryUpdatePackageInfo,
|
|
36
|
+
): Promise<ApiSdkRemotePackage | ApiSdkNativeUpdateNotification | null> {
|
|
37
|
+
const query: CheckUpdateRequestInput = {
|
|
38
|
+
deployment_key: this.configuration.releaseChannelPublicId,
|
|
39
|
+
app_version: currentPackageInfo.appVersion,
|
|
40
|
+
package_hash: currentPackageInfo.packageHash,
|
|
41
|
+
is_companion: this.configuration.ignoreAppVersion,
|
|
42
|
+
label: currentPackageInfo.label,
|
|
43
|
+
client_unique_id: this.configuration.clientUniqueId,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const url = `${this.configuration.serverUrl}/update_check?${queryStringify(query)}`;
|
|
47
|
+
|
|
48
|
+
const response = await this.httpRequester.request('GET', url);
|
|
49
|
+
|
|
50
|
+
if (response.statusCode < 200 || response.statusCode >= 300) {
|
|
51
|
+
throw new CodePushHttpError(url, response.statusCode, response.body || 'No body');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const responseObject: CheckUpdateResponse | Record<string, never> = JSON.parse(response.body || '{}');
|
|
55
|
+
if (!responseObject.update_info) {
|
|
56
|
+
throw new CodePushError('Missing update info in response');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const { update_info: updateInfo } = responseObject;
|
|
60
|
+
|
|
61
|
+
if (updateInfo.update_app_version) {
|
|
62
|
+
return {
|
|
63
|
+
updateAppVersion: true,
|
|
64
|
+
appVersion: responseObject.update_info.target_binary_range,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (!updateInfo.is_available) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
releaseChannelPublicId: this.configuration.releaseChannelPublicId,
|
|
74
|
+
description: updateInfo.description,
|
|
75
|
+
label: updateInfo.label,
|
|
76
|
+
appVersion: updateInfo.target_binary_range,
|
|
77
|
+
isMandatory: updateInfo.is_mandatory,
|
|
78
|
+
packageHash: updateInfo.package_hash,
|
|
79
|
+
packageSize: updateInfo.package_size,
|
|
80
|
+
downloadUrl: updateInfo.download_url,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async reportStatusDeploy(
|
|
85
|
+
deployedPackageInfo: { package: ApiSdkDeployReportPackageInfo; status: DeploymentStatus } | null,
|
|
86
|
+
previousLabelOrAppVersion: string | null,
|
|
87
|
+
previousDeploymentKey: string | null,
|
|
88
|
+
): Promise<void> {
|
|
89
|
+
const requestBody: ReportDeployInput = {
|
|
90
|
+
app_version: this.configuration.appVersion,
|
|
91
|
+
deployment_key: this.configuration.releaseChannelPublicId,
|
|
92
|
+
client_unique_id: this.configuration.clientUniqueId,
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
if (deployedPackageInfo) {
|
|
96
|
+
requestBody.label = deployedPackageInfo.package.label;
|
|
97
|
+
requestBody.app_version = deployedPackageInfo.package.appVersion;
|
|
98
|
+
requestBody.status = deployedPackageInfo.status;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (previousLabelOrAppVersion) {
|
|
102
|
+
requestBody.previous_label_or_app_version = previousLabelOrAppVersion;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (previousDeploymentKey) {
|
|
106
|
+
requestBody.previous_deployment_key = previousDeploymentKey;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const url = `${this.configuration.serverUrl}/report_status/deploy`;
|
|
110
|
+
|
|
111
|
+
const response = await this.httpRequester.request('POST', url, JSON.stringify(requestBody));
|
|
112
|
+
|
|
113
|
+
if (response.statusCode < 200 || response.statusCode >= 300) {
|
|
114
|
+
throw new CodePushHttpError(url, response.statusCode, response.body || 'No body');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async reportStatusDownload(downloadedPackage: ApiSdkDownloadReportPackageInfo): Promise<void> {
|
|
119
|
+
const requestBody: ReportDownloadInput = {
|
|
120
|
+
client_unique_id: this.configuration.clientUniqueId,
|
|
121
|
+
deployment_key: this.configuration.releaseChannelPublicId,
|
|
122
|
+
label: downloadedPackage.label,
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const url = `${this.configuration.serverUrl}/report_status/download`;
|
|
126
|
+
|
|
127
|
+
const response = await this.httpRequester.request('POST', url, JSON.stringify(requestBody));
|
|
128
|
+
|
|
129
|
+
if (response.statusCode < 200 || response.statusCode >= 300) {
|
|
130
|
+
throw new CodePushHttpError(url, response.statusCode, response.body || 'No body');
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
export interface ApiSdkQueryUpdatePackageInfo {
|
|
2
|
+
appVersion: string;
|
|
3
|
+
label?: string;
|
|
4
|
+
packageHash?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface ApiSdkDeployReportPackageInfo {
|
|
8
|
+
label: string;
|
|
9
|
+
appVersion: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ApiSdkDownloadReportPackageInfo {
|
|
13
|
+
label: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ApiSdkRemotePackage {
|
|
17
|
+
releaseChannelPublicId: string;
|
|
18
|
+
label: string;
|
|
19
|
+
appVersion: string;
|
|
20
|
+
description: string;
|
|
21
|
+
isMandatory: boolean;
|
|
22
|
+
packageSize: number;
|
|
23
|
+
packageHash: string;
|
|
24
|
+
downloadUrl: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ApiSdkNativeUpdateNotification {
|
|
28
|
+
updateAppVersion: true;
|
|
29
|
+
appVersion: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export namespace Http {
|
|
33
|
+
export interface Response {
|
|
34
|
+
statusCode: number;
|
|
35
|
+
body?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface Requester {
|
|
39
|
+
request(verb: 'GET' | 'POST', url: string, requestBody?: string | object | null): Promise<Response>;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface ApiSdkConfiguration {
|
|
44
|
+
appVersion: string;
|
|
45
|
+
clientUniqueId: string;
|
|
46
|
+
releaseChannelPublicId: string;
|
|
47
|
+
serverUrl: string;
|
|
48
|
+
ignoreAppVersion?: boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Indicates the status of a deployment (after installing and restarting).
|
|
53
|
+
*/
|
|
54
|
+
export enum DeploymentStatus {
|
|
55
|
+
/**
|
|
56
|
+
* The deployment failed (and was rolled back).
|
|
57
|
+
*/
|
|
58
|
+
FAILED = 'DeploymentFailed',
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The deployment succeeded.
|
|
62
|
+
*/
|
|
63
|
+
SUCCEEDED = 'DeploymentSucceeded',
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface ReportDeployInput {
|
|
67
|
+
deployment_key: string;
|
|
68
|
+
app_version: string;
|
|
69
|
+
status?: DeploymentStatus;
|
|
70
|
+
label?: string;
|
|
71
|
+
client_unique_id?: string;
|
|
72
|
+
previous_label_or_app_version?: string;
|
|
73
|
+
previous_deployment_key?: string;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface ReportDownloadInput {
|
|
77
|
+
deployment_key: string;
|
|
78
|
+
label: string;
|
|
79
|
+
client_unique_id?: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface CheckUpdateRequestInput {
|
|
83
|
+
deployment_key: string;
|
|
84
|
+
app_version: string;
|
|
85
|
+
package_hash?: string;
|
|
86
|
+
label?: string;
|
|
87
|
+
client_unique_id?: string;
|
|
88
|
+
is_companion?: boolean;
|
|
89
|
+
previous_label_or_app_version?: string;
|
|
90
|
+
previous_deployment_key?: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface CheckUpdateResponse {
|
|
94
|
+
update_info:
|
|
95
|
+
| {
|
|
96
|
+
is_available: true;
|
|
97
|
+
target_binary_range: string;
|
|
98
|
+
description: string;
|
|
99
|
+
is_disabled: boolean;
|
|
100
|
+
is_mandatory: boolean;
|
|
101
|
+
rollout: number;
|
|
102
|
+
download_url: string;
|
|
103
|
+
package_size: number;
|
|
104
|
+
package_hash: string;
|
|
105
|
+
label: string;
|
|
106
|
+
should_run_binary_version: boolean;
|
|
107
|
+
update_app_version: boolean;
|
|
108
|
+
}
|
|
109
|
+
| {
|
|
110
|
+
is_available: false;
|
|
111
|
+
should_run_binary_version: boolean;
|
|
112
|
+
target_binary_range: string;
|
|
113
|
+
update_app_version?: boolean;
|
|
114
|
+
};
|
|
115
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Package } from 'code-push/script/acquisition-sdk';
|
|
2
1
|
import { NativeEventEmitter } from 'react-native';
|
|
3
2
|
import type { DownloadProgressCallback, LocalPackage, RemotePackage } from '../types';
|
|
3
|
+
import type { ApiSdkDownloadReportPackageInfo } from './CodePushApiSdk.types';
|
|
4
4
|
import { LocalPackageImplementation } from './LocalPackageImplementation';
|
|
5
5
|
import { NativeRNAppZungCodePushModule } from './NativeRNAppZungCodePushModule';
|
|
6
6
|
import { log } from './utils/log';
|
|
@@ -8,7 +8,7 @@ import { log } from './utils/log';
|
|
|
8
8
|
export class RemotePackageImpl implements RemotePackage {
|
|
9
9
|
constructor(
|
|
10
10
|
remotePackageData: Omit<RemotePackage, 'download'>,
|
|
11
|
-
reportStatusDownload
|
|
11
|
+
reportStatusDownload: (downloadedPackage: ApiSdkDownloadReportPackageInfo) => Promise<void>,
|
|
12
12
|
) {
|
|
13
13
|
Object.assign(this, remotePackageData);
|
|
14
14
|
|
|
@@ -38,12 +38,13 @@ export class RemotePackageImpl implements RemotePackage {
|
|
|
38
38
|
);
|
|
39
39
|
|
|
40
40
|
if (reportStatusDownload) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}).catch((
|
|
45
|
-
log(`Report download status failed: ${
|
|
41
|
+
const timeoutPromise = new Promise<void>((resolve) => setTimeout(resolve, 250));
|
|
42
|
+
const reportPromise = reportStatusDownload({
|
|
43
|
+
label: this.label,
|
|
44
|
+
}).catch((error) => {
|
|
45
|
+
log(`Report download status failed: ${error}`);
|
|
46
46
|
});
|
|
47
|
+
await Promise.race([timeoutPromise, reportPromise]);
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
return new LocalPackageImplementation(downloadedPackage);
|
package/src/internals/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ApiSdkConfiguration } from './CodePushApiSdk.types';
|
|
2
2
|
|
|
3
|
-
export interface Configuration extends
|
|
3
|
+
export interface Configuration extends ApiSdkConfiguration {
|
|
4
4
|
releaseChannelPublicId: string;
|
|
5
5
|
packageHash?: string;
|
|
6
6
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export async function fetchRetry(url: string, options: FetchRetryOptions = {}, attempt = 0): Promise<Response> {
|
|
2
|
+
const {
|
|
3
|
+
maxRetries = 3,
|
|
4
|
+
initialBackoff = 1000,
|
|
5
|
+
backoffMultiplier = 2,
|
|
6
|
+
maxRetryDelay = 30000,
|
|
7
|
+
...fetchOptions
|
|
8
|
+
} = options;
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
const response = await fetch(url, fetchOptions);
|
|
12
|
+
if (response.ok || !(response.status === 429 || response.status >= 500)) {
|
|
13
|
+
return response;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (attempt >= maxRetries) {
|
|
17
|
+
return response;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const retryAfter = parseRetryAfterHeader(response);
|
|
21
|
+
if (retryAfter && retryAfter > maxRetryDelay) {
|
|
22
|
+
return response;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const delay = retryAfter ?? addJitter(initialBackoff * Math.pow(backoffMultiplier, attempt));
|
|
26
|
+
|
|
27
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
28
|
+
|
|
29
|
+
return fetchRetry(url, options, attempt + 1);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
if (attempt >= maxRetries) {
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const delay = addJitter(initialBackoff * Math.pow(backoffMultiplier, attempt));
|
|
36
|
+
|
|
37
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
38
|
+
|
|
39
|
+
return fetchRetry(url, options, attempt + 1);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface FetchRetryOptions extends RequestInit {
|
|
44
|
+
maxRetries?: number;
|
|
45
|
+
initialBackoff?: number;
|
|
46
|
+
backoffMultiplier?: number;
|
|
47
|
+
maxRetryDelay?: number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function parseRetryAfterHeader(response: Response): number | null {
|
|
51
|
+
const retryAfter = response.headers.get('Retry-After');
|
|
52
|
+
if (!retryAfter) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!isNaN(Number(retryAfter))) {
|
|
57
|
+
return parseInt(retryAfter, 10) * 1000;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const retryDate = new Date(retryAfter).getTime();
|
|
62
|
+
const now = Date.now();
|
|
63
|
+
return retryDate > now ? retryDate - now : 0;
|
|
64
|
+
} catch (e) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function addJitter(delay: number): number {
|
|
70
|
+
const jitterFactor = 0.5 + Math.random() * 0.5;
|
|
71
|
+
return Math.floor(delay * jitterFactor);
|
|
72
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function queryStringify(object: { [key: string]: any }): string {
|
|
2
|
+
let queryString = '';
|
|
3
|
+
let isFirst = true;
|
|
4
|
+
|
|
5
|
+
for (const property in object) {
|
|
6
|
+
if (object.hasOwnProperty(property)) {
|
|
7
|
+
const value = object[property];
|
|
8
|
+
if (value !== null && typeof value !== 'undefined') {
|
|
9
|
+
if (!isFirst) {
|
|
10
|
+
queryString += '&';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
queryString += encodeURIComponent(property) + '=';
|
|
14
|
+
queryString += encodeURIComponent(value);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
isFirst = false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return queryString;
|
|
22
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Http } from '../CodePushApiSdk.types';
|
|
2
|
+
import { version } from '../version';
|
|
3
|
+
import { fetchRetry } from './fetchRetry';
|
|
4
|
+
|
|
5
|
+
export const requestFetchAdapter: Http.Requester = {
|
|
6
|
+
async request(method, url, requestBody) {
|
|
7
|
+
const headers = {
|
|
8
|
+
Accept: 'application/json',
|
|
9
|
+
'Content-Type': 'application/json',
|
|
10
|
+
'X-CodePush-Plugin-Name': '@appzung/react-native-code-push',
|
|
11
|
+
'X-CodePush-Plugin-Version': version,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
if (requestBody && typeof requestBody === 'object') {
|
|
15
|
+
requestBody = JSON.stringify(requestBody);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const response = await fetchRetry(url, {
|
|
19
|
+
method,
|
|
20
|
+
headers,
|
|
21
|
+
body: requestBody,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const statusCode = response.status;
|
|
25
|
+
const body = await response.text();
|
|
26
|
+
return { statusCode, body };
|
|
27
|
+
},
|
|
28
|
+
};
|
package/src/internals/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '10.
|
|
2
|
+
export const version = '10.1.1';
|
package/src/notifyAppReady.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { AppState, type NativeEventSubscription } from 'react-native';
|
|
2
|
+
import { CodePushApiSdk } from './internals/CodePushApiSdk';
|
|
2
3
|
import { NativeRNAppZungCodePushModule } from './internals/NativeRNAppZungCodePushModule';
|
|
3
4
|
import { getConfiguration } from './internals/getConfiguration';
|
|
4
|
-
import { getPromisifiedSdk } from './internals/getPromisifiedSdk';
|
|
5
5
|
import { log } from './internals/utils/log';
|
|
6
|
-
import { requestFetchAdapter } from './internals/utils/
|
|
6
|
+
import { requestFetchAdapter } from './internals/utils/requestFetchAdapter';
|
|
7
7
|
import type { StatusReport } from './types';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Notifies the CodePush runtime that an installed update is considered successful.
|
|
11
|
+
*
|
|
12
|
+
* If you are manually checking for and installing updates (i.e. not using the `sync` method to handle it all for you), then this method **MUST** be called; otherwise CodePush will treat the update as failed and rollback to the previous version when the app next restarts.
|
|
11
13
|
*/
|
|
12
14
|
export const notifyAppReady = (() => {
|
|
13
15
|
// This ensures that notifyApplicationReadyInternal is only called once
|
|
@@ -33,7 +35,7 @@ async function notifyApplicationReadyInternal() {
|
|
|
33
35
|
|
|
34
36
|
async function tryReportStatus(statusReport: StatusReport, retryOnAppResume?: NativeEventSubscription) {
|
|
35
37
|
const config = await getConfiguration();
|
|
36
|
-
const previousLabelOrAppVersion = statusReport.previousLabelOrAppVersion;
|
|
38
|
+
const previousLabelOrAppVersion = statusReport.previousLabelOrAppVersion ?? null;
|
|
37
39
|
const previousReleaseChannelPublicId = statusReport.previousReleaseChannelPublicId || config.releaseChannelPublicId;
|
|
38
40
|
try {
|
|
39
41
|
if (statusReport.appVersion) {
|
|
@@ -43,13 +45,8 @@ async function tryReportStatus(statusReport: StatusReport, retryOnAppResume?: Na
|
|
|
43
45
|
throw new Error('Release channel is missing');
|
|
44
46
|
}
|
|
45
47
|
|
|
46
|
-
const sdk =
|
|
47
|
-
await sdk.reportStatusDeploy(
|
|
48
|
-
/* deployedPackage */ undefined,
|
|
49
|
-
/* status */ undefined,
|
|
50
|
-
previousLabelOrAppVersion,
|
|
51
|
-
previousReleaseChannelPublicId,
|
|
52
|
-
);
|
|
48
|
+
const sdk = new CodePushApiSdk(requestFetchAdapter, config);
|
|
49
|
+
await sdk.reportStatusDeploy(null, previousLabelOrAppVersion, previousReleaseChannelPublicId);
|
|
53
50
|
} else {
|
|
54
51
|
if (!statusReport.package) {
|
|
55
52
|
throw new Error('Missing package in status report');
|
|
@@ -64,10 +61,12 @@ async function tryReportStatus(statusReport: StatusReport, retryOnAppResume?: Na
|
|
|
64
61
|
}
|
|
65
62
|
|
|
66
63
|
config.releaseChannelPublicId = statusReport.package.releaseChannelPublicId;
|
|
67
|
-
const sdk =
|
|
64
|
+
const sdk = new CodePushApiSdk(requestFetchAdapter, config);
|
|
68
65
|
await sdk.reportStatusDeploy(
|
|
69
|
-
{
|
|
70
|
-
|
|
66
|
+
{
|
|
67
|
+
package: statusReport.package,
|
|
68
|
+
status: statusReport.status,
|
|
69
|
+
},
|
|
71
70
|
previousLabelOrAppVersion,
|
|
72
71
|
previousReleaseChannelPublicId,
|
|
73
72
|
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { NativeRNAppZungCodePushModule } from './internals/NativeRNAppZungCodePushModule';
|
|
2
|
+
import { reloadCachedConfiguration } from './internals/getConfiguration';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resets the client's unique ID. You may use this in some GDPR compliance scenarios. Note that this will create a new MAU if a new request is sent later.
|
|
6
|
+
*/
|
|
7
|
+
export const resetClientUniqueId = async () => {
|
|
8
|
+
const newId = await NativeRNAppZungCodePushModule.resetClientUniqueId();
|
|
9
|
+
await reloadCachedConfiguration();
|
|
10
|
+
return newId;
|
|
11
|
+
};
|
package/src/restartApp.ts
CHANGED
|
@@ -3,6 +3,8 @@ import { NativeRNAppZungCodePushModule } from './internals/NativeRNAppZungCodePu
|
|
|
3
3
|
/**
|
|
4
4
|
* Immediately restarts the app.
|
|
5
5
|
*
|
|
6
|
+
* If there is an update pending, it will be immediately displayed to the end user. Otherwise, calling this method simply has the same behavior as the end user killing and restarting the process.
|
|
7
|
+
*
|
|
6
8
|
* @param onlyIfUpdateIsPending Indicates whether you want the restart to no-op if there isn't currently a pending update.
|
|
7
9
|
*/
|
|
8
10
|
export async function restartApp(onlyIfUpdateIsPending = false) {
|
package/src/sync.ts
CHANGED
|
@@ -206,6 +206,8 @@ async function syncInternal(
|
|
|
206
206
|
/**
|
|
207
207
|
* Allows checking for an update, downloading it and installing it, all with a single call.
|
|
208
208
|
*
|
|
209
|
+
* Unless you need custom UI and/or behavior, we recommend most developers to use this method when integrating CodePush into their apps, if they are not using the `withCodePush` HOC.
|
|
210
|
+
*
|
|
209
211
|
* @param options Options used to configure the end-user update experience (e.g. show a prompt?, install the update immediately?).
|
|
210
212
|
* @param syncStatusChangedCallback An optional callback that allows tracking the status of the sync operation, as opposed to simply checking the resolved state via the returned Promise.
|
|
211
213
|
* @param downloadProgressCallback An optional callback that allows tracking the progress of an update while it is being downloaded.
|
|
@@ -222,17 +224,17 @@ export const sync = (() => {
|
|
|
222
224
|
|
|
223
225
|
return (
|
|
224
226
|
options?: SyncOptions,
|
|
225
|
-
|
|
227
|
+
syncStatusChangedCallback?: SyncStatusChangedCallback,
|
|
226
228
|
downloadProgressCallback?: DownloadProgressCallback,
|
|
227
229
|
handleBinaryVersionMismatchCallback?: HandleBinaryVersionMismatchCallback,
|
|
228
230
|
): Promise<SyncStatus> => {
|
|
229
231
|
let syncStatusCallbackWithTryCatch: SyncStatusChangedCallback | undefined;
|
|
230
232
|
let downloadProgressCallbackWithTryCatch: DownloadProgressCallback | undefined;
|
|
231
233
|
|
|
232
|
-
if (typeof
|
|
234
|
+
if (typeof syncStatusChangedCallback === 'function') {
|
|
233
235
|
syncStatusCallbackWithTryCatch = (...args) => {
|
|
234
236
|
try {
|
|
235
|
-
|
|
237
|
+
syncStatusChangedCallback(...args);
|
|
236
238
|
} catch (error) {
|
|
237
239
|
log(`An error has occurred : ${error instanceof Error ? error.stack : 'unknown'}`);
|
|
238
240
|
}
|