@appzung/react-native-code-push 10.1.0 → 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.
Files changed (136) hide show
  1. package/android/app/src/main/java/com/appzung/codepush/react/CodePush.java +3 -0
  2. package/ios/CodePush/CodePushConfig.m +4 -0
  3. package/lib/commonjs/checkForUpdates.js +23 -25
  4. package/lib/commonjs/checkForUpdates.js.map +1 -1
  5. package/lib/commonjs/index.js +10 -13
  6. package/lib/commonjs/index.js.map +1 -1
  7. package/lib/commonjs/internals/CodePushApiSdk.errors.js +26 -0
  8. package/lib/commonjs/internals/CodePushApiSdk.errors.js.map +1 -0
  9. package/lib/commonjs/internals/CodePushApiSdk.js +100 -0
  10. package/lib/commonjs/internals/CodePushApiSdk.js.map +1 -0
  11. package/lib/commonjs/{enums/DeploymentStatus.enum.js → internals/CodePushApiSdk.types.js} +3 -2
  12. package/lib/commonjs/internals/CodePushApiSdk.types.js.map +1 -0
  13. package/lib/commonjs/internals/RemotePackageImplementation.js +6 -5
  14. package/lib/commonjs/internals/RemotePackageImplementation.js.map +1 -1
  15. package/lib/commonjs/internals/utils/fetchRetry.js +59 -0
  16. package/lib/commonjs/internals/utils/fetchRetry.js.map +1 -0
  17. package/lib/commonjs/internals/utils/queryStringify.js +25 -0
  18. package/lib/commonjs/internals/utils/queryStringify.js.map +1 -0
  19. package/lib/commonjs/internals/utils/requestFetchAdapter.js +33 -0
  20. package/lib/commonjs/internals/utils/requestFetchAdapter.js.map +1 -0
  21. package/lib/commonjs/internals/version.js +1 -1
  22. package/lib/commonjs/notifyAppReady.js +9 -9
  23. package/lib/commonjs/notifyAppReady.js.map +1 -1
  24. package/lib/module/checkForUpdates.js +23 -25
  25. package/lib/module/checkForUpdates.js.map +1 -1
  26. package/lib/module/index.js +1 -1
  27. package/lib/module/index.js.map +1 -1
  28. package/lib/module/internals/CodePushApiSdk.errors.js +20 -0
  29. package/lib/module/internals/CodePushApiSdk.errors.js.map +1 -0
  30. package/lib/module/internals/CodePushApiSdk.js +96 -0
  31. package/lib/module/internals/CodePushApiSdk.js.map +1 -0
  32. package/lib/module/{enums/DeploymentStatus.enum.js → internals/CodePushApiSdk.types.js} +2 -1
  33. package/lib/module/internals/CodePushApiSdk.types.js.map +1 -0
  34. package/lib/module/internals/RemotePackageImplementation.js +6 -5
  35. package/lib/module/internals/RemotePackageImplementation.js.map +1 -1
  36. package/lib/module/internals/utils/fetchRetry.js +55 -0
  37. package/lib/module/internals/utils/fetchRetry.js.map +1 -0
  38. package/lib/module/internals/utils/queryStringify.js +21 -0
  39. package/lib/module/internals/utils/queryStringify.js.map +1 -0
  40. package/lib/module/internals/utils/requestFetchAdapter.js +29 -0
  41. package/lib/module/internals/utils/requestFetchAdapter.js.map +1 -0
  42. package/lib/module/internals/version.js +1 -1
  43. package/lib/module/notifyAppReady.js +9 -9
  44. package/lib/module/notifyAppReady.js.map +1 -1
  45. package/lib/typescript/commonjs/src/checkForUpdates.d.ts.map +1 -1
  46. package/lib/typescript/commonjs/src/index.d.ts +1 -1
  47. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  48. package/lib/typescript/commonjs/src/internals/CodePushApiSdk.d.ts +13 -0
  49. package/lib/typescript/commonjs/src/internals/CodePushApiSdk.d.ts.map +1 -0
  50. package/lib/typescript/commonjs/src/internals/CodePushApiSdk.errors.d.ts +9 -0
  51. package/lib/typescript/commonjs/src/internals/CodePushApiSdk.errors.d.ts.map +1 -0
  52. package/lib/typescript/commonjs/src/internals/CodePushApiSdk.types.d.ts +101 -0
  53. package/lib/typescript/commonjs/src/internals/CodePushApiSdk.types.d.ts.map +1 -0
  54. package/lib/typescript/commonjs/src/internals/RemotePackageImplementation.d.ts +2 -2
  55. package/lib/typescript/commonjs/src/internals/RemotePackageImplementation.d.ts.map +1 -1
  56. package/lib/typescript/commonjs/src/internals/types.d.ts +2 -2
  57. package/lib/typescript/commonjs/src/internals/types.d.ts.map +1 -1
  58. package/lib/typescript/commonjs/src/internals/utils/fetchRetry.d.ts +9 -0
  59. package/lib/typescript/commonjs/src/internals/utils/fetchRetry.d.ts.map +1 -0
  60. package/lib/typescript/commonjs/src/internals/utils/queryStringify.d.ts +4 -0
  61. package/lib/typescript/commonjs/src/internals/utils/queryStringify.d.ts.map +1 -0
  62. package/lib/typescript/commonjs/src/internals/utils/requestFetchAdapter.d.ts +3 -0
  63. package/lib/typescript/commonjs/src/internals/utils/requestFetchAdapter.d.ts.map +1 -0
  64. package/lib/typescript/commonjs/src/internals/version.d.ts +1 -1
  65. package/lib/typescript/commonjs/src/types.d.ts +4 -3
  66. package/lib/typescript/commonjs/src/types.d.ts.map +1 -1
  67. package/lib/typescript/module/src/checkForUpdates.d.ts.map +1 -1
  68. package/lib/typescript/module/src/index.d.ts +1 -1
  69. package/lib/typescript/module/src/index.d.ts.map +1 -1
  70. package/lib/typescript/module/src/internals/CodePushApiSdk.d.ts +13 -0
  71. package/lib/typescript/module/src/internals/CodePushApiSdk.d.ts.map +1 -0
  72. package/lib/typescript/module/src/internals/CodePushApiSdk.errors.d.ts +9 -0
  73. package/lib/typescript/module/src/internals/CodePushApiSdk.errors.d.ts.map +1 -0
  74. package/lib/typescript/module/src/internals/CodePushApiSdk.types.d.ts +101 -0
  75. package/lib/typescript/module/src/internals/CodePushApiSdk.types.d.ts.map +1 -0
  76. package/lib/typescript/module/src/internals/RemotePackageImplementation.d.ts +2 -2
  77. package/lib/typescript/module/src/internals/RemotePackageImplementation.d.ts.map +1 -1
  78. package/lib/typescript/module/src/internals/types.d.ts +2 -2
  79. package/lib/typescript/module/src/internals/types.d.ts.map +1 -1
  80. package/lib/typescript/module/src/internals/utils/fetchRetry.d.ts +9 -0
  81. package/lib/typescript/module/src/internals/utils/fetchRetry.d.ts.map +1 -0
  82. package/lib/typescript/module/src/internals/utils/queryStringify.d.ts +4 -0
  83. package/lib/typescript/module/src/internals/utils/queryStringify.d.ts.map +1 -0
  84. package/lib/typescript/module/src/internals/utils/requestFetchAdapter.d.ts +3 -0
  85. package/lib/typescript/module/src/internals/utils/requestFetchAdapter.d.ts.map +1 -0
  86. package/lib/typescript/module/src/internals/version.d.ts +1 -1
  87. package/lib/typescript/module/src/types.d.ts +4 -3
  88. package/lib/typescript/module/src/types.d.ts.map +1 -1
  89. package/package.json +3 -3
  90. package/src/checkForUpdates.ts +24 -23
  91. package/src/index.ts +1 -1
  92. package/src/internals/CodePushApiSdk.errors.ts +22 -0
  93. package/src/internals/CodePushApiSdk.ts +133 -0
  94. package/src/internals/CodePushApiSdk.types.ts +115 -0
  95. package/src/internals/RemotePackageImplementation.ts +8 -7
  96. package/src/internals/types.ts +2 -2
  97. package/src/internals/utils/fetchRetry.ts +72 -0
  98. package/src/internals/utils/queryStringify.ts +22 -0
  99. package/src/internals/utils/requestFetchAdapter.ts +28 -0
  100. package/src/internals/version.ts +1 -1
  101. package/src/notifyAppReady.ts +10 -13
  102. package/src/types.ts +2 -3
  103. package/lib/commonjs/enums/DeploymentStatus.enum.js.map +0 -1
  104. package/lib/commonjs/internals/AcquisitionSdk.js +0 -9
  105. package/lib/commonjs/internals/AcquisitionSdk.js.map +0 -1
  106. package/lib/commonjs/internals/getPromisifiedSdk.js +0 -49
  107. package/lib/commonjs/internals/getPromisifiedSdk.js.map +0 -1
  108. package/lib/commonjs/internals/utils/request-fetch-adapter.js +0 -50
  109. package/lib/commonjs/internals/utils/request-fetch-adapter.js.map +0 -1
  110. package/lib/module/enums/DeploymentStatus.enum.js.map +0 -1
  111. package/lib/module/internals/AcquisitionSdk.js +0 -5
  112. package/lib/module/internals/AcquisitionSdk.js.map +0 -1
  113. package/lib/module/internals/getPromisifiedSdk.js +0 -45
  114. package/lib/module/internals/getPromisifiedSdk.js.map +0 -1
  115. package/lib/module/internals/utils/request-fetch-adapter.js +0 -46
  116. package/lib/module/internals/utils/request-fetch-adapter.js.map +0 -1
  117. package/lib/typescript/commonjs/src/enums/DeploymentStatus.enum.d.ts +0 -14
  118. package/lib/typescript/commonjs/src/enums/DeploymentStatus.enum.d.ts.map +0 -1
  119. package/lib/typescript/commonjs/src/internals/AcquisitionSdk.d.ts +0 -3
  120. package/lib/typescript/commonjs/src/internals/AcquisitionSdk.d.ts.map +0 -1
  121. package/lib/typescript/commonjs/src/internals/getPromisifiedSdk.d.ts +0 -13
  122. package/lib/typescript/commonjs/src/internals/getPromisifiedSdk.d.ts.map +0 -1
  123. package/lib/typescript/commonjs/src/internals/utils/request-fetch-adapter.d.ts +0 -3
  124. package/lib/typescript/commonjs/src/internals/utils/request-fetch-adapter.d.ts.map +0 -1
  125. package/lib/typescript/module/src/enums/DeploymentStatus.enum.d.ts +0 -14
  126. package/lib/typescript/module/src/enums/DeploymentStatus.enum.d.ts.map +0 -1
  127. package/lib/typescript/module/src/internals/AcquisitionSdk.d.ts +0 -3
  128. package/lib/typescript/module/src/internals/AcquisitionSdk.d.ts.map +0 -1
  129. package/lib/typescript/module/src/internals/getPromisifiedSdk.d.ts +0 -13
  130. package/lib/typescript/module/src/internals/getPromisifiedSdk.d.ts.map +0 -1
  131. package/lib/typescript/module/src/internals/utils/request-fetch-adapter.d.ts +0 -3
  132. package/lib/typescript/module/src/internals/utils/request-fetch-adapter.d.ts.map +0 -1
  133. package/src/enums/DeploymentStatus.enum.ts +0 -14
  134. package/src/internals/AcquisitionSdk.ts +0 -3
  135. package/src/internals/getPromisifiedSdk.ts +0 -72
  136. package/src/internals/utils/request-fetch-adapter.ts +0 -58
@@ -0,0 +1,22 @@
1
+ export class CodePushError extends Error {
2
+ constructor(message: string) {
3
+ super(message);
4
+ this.name = 'CodePushError';
5
+ }
6
+ }
7
+
8
+ export class CodePushHttpError extends CodePushError {
9
+ constructor(
10
+ readonly url: string,
11
+ readonly statusCode: number,
12
+ message: string,
13
+ ) {
14
+ super(message);
15
+
16
+ if (statusCode === 0) {
17
+ this.message = `Couldn't send request to ${url}, xhr.statusCode = 0 was returned. One of the possible reasons for that might be connection problems. Please, check your internet connection.`;
18
+ }
19
+
20
+ this.name = 'CodePushHttpError';
21
+ }
22
+ }
@@ -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?: (downloadedPackage: Package) => Promise<void>,
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
- reportStatusDownload({
42
- ...this,
43
- deploymentKey: this.releaseChannelPublicId,
44
- }).catch((err) => {
45
- log(`Report download status failed: ${err}`);
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);
@@ -1,6 +1,6 @@
1
- import type { Configuration as BaseConfiguration } from 'code-push/script/acquisition-sdk';
1
+ import type { ApiSdkConfiguration } from './CodePushApiSdk.types';
2
2
 
3
- export interface Configuration extends BaseConfiguration {
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
+ };
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '10.1.0';
2
+ export const version = '10.1.1';
@@ -1,9 +1,9 @@
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/request-fetch-adapter';
6
+ import { requestFetchAdapter } from './internals/utils/requestFetchAdapter';
7
7
  import type { StatusReport } from './types';
8
8
 
9
9
  /**
@@ -35,7 +35,7 @@ async function notifyApplicationReadyInternal() {
35
35
 
36
36
  async function tryReportStatus(statusReport: StatusReport, retryOnAppResume?: NativeEventSubscription) {
37
37
  const config = await getConfiguration();
38
- const previousLabelOrAppVersion = statusReport.previousLabelOrAppVersion;
38
+ const previousLabelOrAppVersion = statusReport.previousLabelOrAppVersion ?? null;
39
39
  const previousReleaseChannelPublicId = statusReport.previousReleaseChannelPublicId || config.releaseChannelPublicId;
40
40
  try {
41
41
  if (statusReport.appVersion) {
@@ -45,13 +45,8 @@ async function tryReportStatus(statusReport: StatusReport, retryOnAppResume?: Na
45
45
  throw new Error('Release channel is missing');
46
46
  }
47
47
 
48
- const sdk = getPromisifiedSdk(requestFetchAdapter, config);
49
- await sdk.reportStatusDeploy(
50
- /* deployedPackage */ undefined,
51
- /* status */ undefined,
52
- previousLabelOrAppVersion,
53
- previousReleaseChannelPublicId,
54
- );
48
+ const sdk = new CodePushApiSdk(requestFetchAdapter, config);
49
+ await sdk.reportStatusDeploy(null, previousLabelOrAppVersion, previousReleaseChannelPublicId);
55
50
  } else {
56
51
  if (!statusReport.package) {
57
52
  throw new Error('Missing package in status report');
@@ -66,10 +61,12 @@ async function tryReportStatus(statusReport: StatusReport, retryOnAppResume?: Na
66
61
  }
67
62
 
68
63
  config.releaseChannelPublicId = statusReport.package.releaseChannelPublicId;
69
- const sdk = getPromisifiedSdk(requestFetchAdapter, config);
64
+ const sdk = new CodePushApiSdk(requestFetchAdapter, config);
70
65
  await sdk.reportStatusDeploy(
71
- { ...statusReport.package, deploymentKey: statusReport.package.releaseChannelPublicId },
72
- statusReport.status,
66
+ {
67
+ package: statusReport.package,
68
+ status: statusReport.status,
69
+ },
73
70
  previousLabelOrAppVersion,
74
71
  previousReleaseChannelPublicId,
75
72
  );
package/src/types.ts CHANGED
@@ -1,7 +1,6 @@
1
- import type { NativeUpdateNotification } from 'code-push/script/acquisition-sdk';
2
- import type { DeploymentStatus } from './enums/DeploymentStatus.enum';
3
1
  import type { InstallMode } from './enums/InstallMode.enum';
4
2
  import type { SyncStatus } from './enums/SyncStatus.enum';
3
+ import { DeploymentStatus } from './internals/CodePushApiSdk.types';
5
4
 
6
5
  export interface UpdateDialog {
7
6
  /**
@@ -78,7 +77,7 @@ export type SyncStatusChangedCallback = (status: SyncStatus) => void;
78
77
  /**
79
78
  * Called when there are any binary update available.
80
79
  */
81
- export type HandleBinaryVersionMismatchCallback = (update: NativeUpdateNotification) => void;
80
+ export type HandleBinaryVersionMismatchCallback = (update: { appVersion: string }) => void;
82
81
 
83
82
  export interface DownloadProgress {
84
83
  /**
@@ -1 +0,0 @@
1
- {"version":3,"names":["DeploymentStatus","exports"],"sourceRoot":"../../../src","sources":["enums/DeploymentStatus.enum.ts"],"mappings":";;;;;;AAAA;AACA;AACA;AAFA,IAGYA,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,0BAAhBA,gBAAgB;EAC1B;AACF;AACA;EAHYA,gBAAgB;EAM1B;AACF;AACA;EARYA,gBAAgB;EAAA,OAAhBA,gBAAgB;AAAA","ignoreList":[]}
@@ -1,9 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.AcquisitionSdk = void 0;
7
- var _acquisitionSdk = require("code-push/script/acquisition-sdk");
8
- const AcquisitionSdk = exports.AcquisitionSdk = _acquisitionSdk.AcquisitionManager;
9
- //# sourceMappingURL=AcquisitionSdk.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_acquisitionSdk","require","AcquisitionSdk","exports","AcquisitionManager"],"sourceRoot":"../../../src","sources":["internals/AcquisitionSdk.ts"],"mappings":";;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AAEO,MAAMC,cAAc,GAAAC,OAAA,CAAAD,cAAA,GAAGE,kCAAkB","ignoreList":[]}
@@ -1,49 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.getPromisifiedSdk = getPromisifiedSdk;
7
- var _AcquisitionSdk = require("./AcquisitionSdk.js");
8
- function getPromisifiedSdk(requestFetchAdapter, config) {
9
- // TODO MIGRATION Temporary retro-compat while we still use code-push module
10
- config.deploymentKey = config.releaseChannelPublicId;
11
- const sdk = new _AcquisitionSdk.AcquisitionSdk(requestFetchAdapter, config);
12
- return {
13
- queryUpdateWithCurrentPackage: queryPackage => {
14
- return new Promise((resolve, reject) => {
15
- // @ts-expect-error sdk typing is wrong
16
- _AcquisitionSdk.AcquisitionSdk.prototype.queryUpdateWithCurrentPackage.call(sdk, queryPackage, (err, update) => {
17
- if (err) {
18
- reject(err);
19
- return;
20
- }
21
- resolve(update);
22
- });
23
- });
24
- },
25
- reportStatusDeploy: (deployedPackage, status, previousLabelOrAppVersion, previousReleaseChannelPublicId) => {
26
- return new Promise((resolve, reject) => {
27
- _AcquisitionSdk.AcquisitionSdk.prototype.reportStatusDeploy.call(sdk, deployedPackage, status, previousLabelOrAppVersion, previousReleaseChannelPublicId, err => {
28
- if (err) {
29
- reject(err);
30
- return;
31
- }
32
- resolve();
33
- });
34
- });
35
- },
36
- reportStatusDownload: downloadedPackage => {
37
- return new Promise((resolve, reject) => {
38
- _AcquisitionSdk.AcquisitionSdk.prototype.reportStatusDownload.call(sdk, downloadedPackage, err => {
39
- if (err) {
40
- reject(err);
41
- return;
42
- }
43
- resolve();
44
- });
45
- });
46
- }
47
- };
48
- }
49
- //# sourceMappingURL=getPromisifiedSdk.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_AcquisitionSdk","require","getPromisifiedSdk","requestFetchAdapter","config","deploymentKey","releaseChannelPublicId","sdk","AcquisitionSdk","queryUpdateWithCurrentPackage","queryPackage","Promise","resolve","reject","prototype","call","err","update","reportStatusDeploy","deployedPackage","status","previousLabelOrAppVersion","previousReleaseChannelPublicId","reportStatusDownload","downloadedPackage"],"sourceRoot":"../../../src","sources":["internals/getPromisifiedSdk.ts"],"mappings":";;;;;;AACA,IAAAA,eAAA,GAAAC,OAAA;AAkBO,SAASC,iBAAiBA,CAACC,mBAAmC,EAAEC,MAAqB,EAAkB;EAC5G;EACAA,MAAM,CAACC,aAAa,GAAGD,MAAM,CAACE,sBAAsB;EAEpD,MAAMC,GAAG,GAAG,IAAIC,8BAAc,CAACL,mBAAmB,EAAEC,MAAM,CAAC;EAE3D,OAAO;IACLK,6BAA6B,EAAGC,YAAY,IAAK;MAC/C,OAAO,IAAIC,OAAO,CAA2C,CAACC,OAAO,EAAEC,MAAM,KAAK;QAChF;QACAL,8BAAc,CAACM,SAAS,CAACL,6BAA6B,CAACM,IAAI,CAACR,GAAG,EAAEG,YAAY,EAAE,CAACM,GAAG,EAAEC,MAAM,KAAK;UAC9F,IAAID,GAAG,EAAE;YACPH,MAAM,CAACG,GAAG,CAAC;YACX;UACF;UAEAJ,OAAO,CAACK,MAAM,CAAC;QACjB,CAAC,CAAC;MACJ,CAAC,CAAC;IACJ,CAAC;IACDC,kBAAkB,EAAEA,CAACC,eAAe,EAAEC,MAAM,EAAEC,yBAAyB,EAAEC,8BAA8B,KAAK;MAC1G,OAAO,IAAIX,OAAO,CAAO,CAACC,OAAO,EAAEC,MAAM,KAAK;QAC5CL,8BAAc,CAACM,SAAS,CAACI,kBAAkB,CAACH,IAAI,CAC9CR,GAAG,EACHY,eAAe,EACfC,MAAM,EACNC,yBAAyB,EACzBC,8BAA8B,EAC7BN,GAAG,IAAK;UACP,IAAIA,GAAG,EAAE;YACPH,MAAM,CAACG,GAAG,CAAC;YACX;UACF;UAEAJ,OAAO,CAAC,CAAC;QACX,CACF,CAAC;MACH,CAAC,CAAC;IACJ,CAAC;IACDW,oBAAoB,EAAGC,iBAAiB,IAAK;MAC3C,OAAO,IAAIb,OAAO,CAAO,CAACC,OAAO,EAAEC,MAAM,KAAK;QAC5CL,8BAAc,CAACM,SAAS,CAACS,oBAAoB,CAACR,IAAI,CAACR,GAAG,EAAEiB,iBAAiB,EAAGR,GAAG,IAAK;UAClF,IAAIA,GAAG,EAAE;YACPH,MAAM,CAACG,GAAG,CAAC;YACX;UACF;UAEAJ,OAAO,CAAC,CAAC;QACX,CAAC,CAAC;MACJ,CAAC,CAAC;IACJ;EACF,CAAC;AACH","ignoreList":[]}
@@ -1,50 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.requestFetchAdapter = void 0;
7
- var _version = require("../version.js");
8
- const requestFetchAdapter = exports.requestFetchAdapter = {
9
- // @ts-expect-error SDK typing is wrong about error callback
10
- async request(verb, url, requestBody, callback) {
11
- if (typeof requestBody === 'function') {
12
- callback = requestBody;
13
- requestBody = null;
14
- }
15
- const headers = {
16
- Accept: 'application/json',
17
- 'Content-Type': 'application/json',
18
- 'X-CodePush-Plugin-Name': '@appzung/react-native-code-push',
19
- 'X-CodePush-Plugin-Version': _version.version
20
- };
21
- if (requestBody && typeof requestBody === 'object') {
22
- requestBody = JSON.stringify(requestBody);
23
- }
24
- try {
25
- const response = await fetch(url, {
26
- method: getHttpMethodName(verb),
27
- headers: headers,
28
- body: requestBody
29
- });
30
- const statusCode = response.status;
31
- const body = await response.text();
32
- callback(null, {
33
- statusCode,
34
- body
35
- });
36
- } catch (err) {
37
- callback(err);
38
- }
39
- }
40
- };
41
- function getHttpMethodName(verb) {
42
- // Note: This should stay in sync with the enum definition in
43
- // https://github.com/microsoft/code-push/blob/master/sdk/script/acquisition-sdk.ts#L6
44
- const methodName = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'OPTIONS', 'CONNECT', 'PATCH'][verb];
45
- if (!methodName) {
46
- throw new Error('Invalid method name verb');
47
- }
48
- return methodName;
49
- }
50
- //# sourceMappingURL=request-fetch-adapter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_version","require","requestFetchAdapter","exports","request","verb","url","requestBody","callback","headers","Accept","version","JSON","stringify","response","fetch","method","getHttpMethodName","body","statusCode","status","text","err","methodName","Error"],"sourceRoot":"../../../../src","sources":["internals/utils/request-fetch-adapter.ts"],"mappings":";;;;;;AACA,IAAAA,QAAA,GAAAC,OAAA;AAMO,MAAMC,mBAAmC,GAAAC,OAAA,CAAAD,mBAAA,GAAG;EACjD;EACA,MAAME,OAAOA,CACXC,IAAe,EACfC,GAAW,EACXC,WAAmC,EACnCC,QAA2B,EACZ;IACf,IAAI,OAAOD,WAAW,KAAK,UAAU,EAAE;MACrCC,QAAQ,GAAGD,WAAW;MACtBA,WAAW,GAAG,IAAI;IACpB;IAEA,MAAME,OAAO,GAAG;MACdC,MAAM,EAAE,kBAAkB;MAC1B,cAAc,EAAE,kBAAkB;MAClC,wBAAwB,EAAE,iCAAiC;MAC3D,2BAA2B,EAAEC;IAC/B,CAAC;IAED,IAAIJ,WAAW,IAAI,OAAOA,WAAW,KAAK,QAAQ,EAAE;MAClDA,WAAW,GAAGK,IAAI,CAACC,SAAS,CAACN,WAAW,CAAC;IAC3C;IAEA,IAAI;MACF,MAAMO,QAAQ,GAAG,MAAMC,KAAK,CAACT,GAAG,EAAE;QAChCU,MAAM,EAAEC,iBAAiB,CAACZ,IAAI,CAAC;QAC/BI,OAAO,EAAEA,OAAO;QAChBS,IAAI,EAAEX;MACR,CAAC,CAAC;MAEF,MAAMY,UAAU,GAAGL,QAAQ,CAACM,MAAM;MAClC,MAAMF,IAAI,GAAG,MAAMJ,QAAQ,CAACO,IAAI,CAAC,CAAC;MAClCb,QAAQ,CAAE,IAAI,EAAE;QAAEW,UAAU;QAAED;MAAK,CAAC,CAAC;IACvC,CAAC,CAAC,OAAOI,GAAG,EAAE;MACZd,QAAQ,CAAEc,GAAY,CAAC;IACzB;EACF;AACF,CAAC;AAED,SAASL,iBAAiBA,CAACZ,IAAe,EAAU;EAClD;EACA;EACA,MAAMkB,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,CAAClB,IAAI,CAAC;EAEzG,IAAI,CAACkB,UAAU,EAAE;IACf,MAAM,IAAIC,KAAK,CAAC,0BAA0B,CAAC;EAC7C;EAEA,OAAOD,UAAU;AACnB","ignoreList":[]}
@@ -1 +0,0 @@
1
- {"version":3,"names":["DeploymentStatus"],"sourceRoot":"../../../src","sources":["enums/DeploymentStatus.enum.ts"],"mappings":";;AAAA;AACA;AACA;AACA,WAAYA,gBAAgB,0BAAhBA,gBAAgB;EAC1B;AACF;AACA;EAHYA,gBAAgB;EAM1B;AACF;AACA;EARYA,gBAAgB;EAAA,OAAhBA,gBAAgB;AAAA","ignoreList":[]}
@@ -1,5 +0,0 @@
1
- "use strict";
2
-
3
- import { AcquisitionManager } from 'code-push/script/acquisition-sdk';
4
- export const AcquisitionSdk = AcquisitionManager;
5
- //# sourceMappingURL=AcquisitionSdk.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["AcquisitionManager","AcquisitionSdk"],"sourceRoot":"../../../src","sources":["internals/AcquisitionSdk.ts"],"mappings":";;AAAA,SAASA,kBAAkB,QAAQ,kCAAkC;AAErE,OAAO,MAAMC,cAAc,GAAGD,kBAAkB","ignoreList":[]}