@algocare/react-native-code-push 9.0.0-beta.3

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 (190) hide show
  1. package/AlertAdapter.js +24 -0
  2. package/CONTRIBUTING.md +134 -0
  3. package/CodePush.js +778 -0
  4. package/CodePush.podspec +27 -0
  5. package/LICENSE.md +13 -0
  6. package/README.md +491 -0
  7. package/SECURITY.md +41 -0
  8. package/android/app/build.gradle +31 -0
  9. package/android/app/proguard-rules.pro +25 -0
  10. package/android/app/src/main/AndroidManifest.xml +6 -0
  11. package/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +441 -0
  12. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushBuilder.java +37 -0
  13. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushConstants.java +35 -0
  14. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushDialog.java +102 -0
  15. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushInstallMode.java +16 -0
  16. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushInvalidPublicKeyException.java +12 -0
  17. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushInvalidUpdateException.java +7 -0
  18. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushMalformedDataException.java +12 -0
  19. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java +714 -0
  20. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushNotInitializedException.java +12 -0
  21. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushTelemetryManager.java +175 -0
  22. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUnknownException.java +12 -0
  23. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateManager.java +383 -0
  24. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateState.java +15 -0
  25. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateUtils.java +268 -0
  26. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUtils.java +238 -0
  27. package/android/app/src/main/java/com/microsoft/codepush/react/DownloadProgress.java +30 -0
  28. package/android/app/src/main/java/com/microsoft/codepush/react/DownloadProgressCallback.java +5 -0
  29. package/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java +203 -0
  30. package/android/app/src/main/java/com/microsoft/codepush/react/ReactInstanceHolder.java +17 -0
  31. package/android/app/src/main/java/com/microsoft/codepush/react/SettingsManager.java +173 -0
  32. package/android/app/src/main/java/com/microsoft/codepush/react/TLSSocketFactory.java +72 -0
  33. package/android/build.gradle +21 -0
  34. package/android/codepush.gradle +162 -0
  35. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  36. package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  37. package/android/gradle.properties +20 -0
  38. package/android/gradlew +164 -0
  39. package/android/gradlew.bat +90 -0
  40. package/android/settings.gradle +1 -0
  41. package/babel.config.js +3 -0
  42. package/cli/commands/bundleCommand/bundleCodePush.js +57 -0
  43. package/cli/commands/bundleCommand/index.js +29 -0
  44. package/cli/commands/createHistoryCommand/createReleaseHistory.js +53 -0
  45. package/cli/commands/createHistoryCommand/index.js +29 -0
  46. package/cli/commands/releaseCommand/addToReleaseHistory.js +75 -0
  47. package/cli/commands/releaseCommand/index.js +66 -0
  48. package/cli/commands/releaseCommand/release.js +109 -0
  49. package/cli/commands/showHistoryCommand/index.js +29 -0
  50. package/cli/commands/updateHistoryCommand/index.js +50 -0
  51. package/cli/commands/updateHistoryCommand/updateReleaseHistory.js +62 -0
  52. package/cli/constant.js +6 -0
  53. package/cli/functions/getReactTempDir.js +16 -0
  54. package/cli/functions/makeCodePushBundle.js +28 -0
  55. package/cli/functions/prepareToBundleJS.js +12 -0
  56. package/cli/functions/runHermesEmitBinaryCommand.js +213 -0
  57. package/cli/functions/runReactNativeBundleCommand.js +59 -0
  58. package/cli/index.js +43 -0
  59. package/cli/utils/file-utils.js +42 -0
  60. package/cli/utils/fsUtils.js +49 -0
  61. package/cli/utils/hash-utils.js +227 -0
  62. package/cli/utils/promisfied-fs.js +29 -0
  63. package/cli/utils/showLogo.js +23 -0
  64. package/cli/utils/zip.js +89 -0
  65. package/code-push.config.example.supabase.ts +114 -0
  66. package/docs/api-android.md +83 -0
  67. package/docs/api-ios.md +31 -0
  68. package/docs/api-js.md +592 -0
  69. package/docs/multi-deployment-testing-android.md +148 -0
  70. package/docs/multi-deployment-testing-ios.md +59 -0
  71. package/docs/setup-android.md +482 -0
  72. package/docs/setup-ios.md +280 -0
  73. package/eslint.config.mjs +32 -0
  74. package/ios/CodePush/Base64/Base64/MF_Base64Additions.h +34 -0
  75. package/ios/CodePush/Base64/Base64/MF_Base64Additions.m +252 -0
  76. package/ios/CodePush/Base64/README.md +47 -0
  77. package/ios/CodePush/CodePush.h +235 -0
  78. package/ios/CodePush/CodePush.m +1121 -0
  79. package/ios/CodePush/CodePushConfig.m +116 -0
  80. package/ios/CodePush/CodePushDownloadHandler.m +130 -0
  81. package/ios/CodePush/CodePushErrorUtils.m +20 -0
  82. package/ios/CodePush/CodePushPackage.m +602 -0
  83. package/ios/CodePush/CodePushTelemetryManager.m +175 -0
  84. package/ios/CodePush/CodePushUpdateUtils.m +376 -0
  85. package/ios/CodePush/CodePushUtils.m +9 -0
  86. package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithm.h +69 -0
  87. package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmFactory.h +16 -0
  88. package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmFactory.m +51 -0
  89. package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmNone.h +15 -0
  90. package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmNone.m +55 -0
  91. package/ios/CodePush/JWT/Core/Algorithms/ESFamily/JWTAlgorithmESBase.h +24 -0
  92. package/ios/CodePush/JWT/Core/Algorithms/ESFamily/JWTAlgorithmESBase.m +41 -0
  93. package/ios/CodePush/JWT/Core/Algorithms/HSFamily/JWTAlgorithmHSBase.h +28 -0
  94. package/ios/CodePush/JWT/Core/Algorithms/HSFamily/JWTAlgorithmHSBase.m +205 -0
  95. package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolder.h +103 -0
  96. package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolder.m +322 -0
  97. package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolderChain.h +37 -0
  98. package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolderChain.m +145 -0
  99. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTAlgorithmRSBase.h +35 -0
  100. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTAlgorithmRSBase.m +551 -0
  101. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTRSAlgorithm.h +23 -0
  102. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKey.h +43 -0
  103. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKey.m +230 -0
  104. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKeyExtractor.h +31 -0
  105. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKeyExtractor.m +113 -0
  106. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoSecurity.h +38 -0
  107. package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoSecurity.m +500 -0
  108. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaim.h +18 -0
  109. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaim.m +214 -0
  110. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSet.h +23 -0
  111. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSet.m +29 -0
  112. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetSerializer.h +19 -0
  113. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetSerializer.m +68 -0
  114. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetVerifier.h +18 -0
  115. package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetVerifier.m +72 -0
  116. package/ios/CodePush/JWT/Core/Coding/JWTCoding+ResultTypes.h +67 -0
  117. package/ios/CodePush/JWT/Core/Coding/JWTCoding+ResultTypes.m +111 -0
  118. package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionOne.h +119 -0
  119. package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionOne.m +307 -0
  120. package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionThree.h +94 -0
  121. package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionThree.m +619 -0
  122. package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionTwo.h +164 -0
  123. package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionTwo.m +514 -0
  124. package/ios/CodePush/JWT/Core/Coding/JWTCoding.h +24 -0
  125. package/ios/CodePush/JWT/Core/Coding/JWTCoding.m +11 -0
  126. package/ios/CodePush/JWT/Core/FrameworkSupplement/JWT.h +52 -0
  127. package/ios/CodePush/JWT/Core/FrameworkSupplement/Map.modulemap +5 -0
  128. package/ios/CodePush/JWT/Core/Supplement/JWTBase64Coder.h +28 -0
  129. package/ios/CodePush/JWT/Core/Supplement/JWTBase64Coder.m +70 -0
  130. package/ios/CodePush/JWT/Core/Supplement/JWTDeprecations.h +22 -0
  131. package/ios/CodePush/JWT/Core/Supplement/JWTErrorDescription.h +34 -0
  132. package/ios/CodePush/JWT/Core/Supplement/JWTErrorDescription.m +73 -0
  133. package/ios/CodePush/JWT/LICENSE +19 -0
  134. package/ios/CodePush/JWT/README.md +489 -0
  135. package/ios/CodePush/RCTConvert+CodePushInstallMode.m +20 -0
  136. package/ios/CodePush/RCTConvert+CodePushUpdateState.m +20 -0
  137. package/ios/CodePush/SSZipArchive/Common.h +81 -0
  138. package/ios/CodePush/SSZipArchive/README.md +1 -0
  139. package/ios/CodePush/SSZipArchive/SSZipArchive.h +76 -0
  140. package/ios/CodePush/SSZipArchive/SSZipArchive.m +691 -0
  141. package/ios/CodePush/SSZipArchive/aes/aes.h +198 -0
  142. package/ios/CodePush/SSZipArchive/aes/aes_via_ace.h +541 -0
  143. package/ios/CodePush/SSZipArchive/aes/aescrypt.c +294 -0
  144. package/ios/CodePush/SSZipArchive/aes/aeskey.c +548 -0
  145. package/ios/CodePush/SSZipArchive/aes/aesopt.h +739 -0
  146. package/ios/CodePush/SSZipArchive/aes/aestab.c +391 -0
  147. package/ios/CodePush/SSZipArchive/aes/aestab.h +173 -0
  148. package/ios/CodePush/SSZipArchive/aes/brg_endian.h +126 -0
  149. package/ios/CodePush/SSZipArchive/aes/brg_types.h +219 -0
  150. package/ios/CodePush/SSZipArchive/aes/entropy.c +54 -0
  151. package/ios/CodePush/SSZipArchive/aes/entropy.h +16 -0
  152. package/ios/CodePush/SSZipArchive/aes/fileenc.c +144 -0
  153. package/ios/CodePush/SSZipArchive/aes/fileenc.h +121 -0
  154. package/ios/CodePush/SSZipArchive/aes/hmac.c +145 -0
  155. package/ios/CodePush/SSZipArchive/aes/hmac.h +103 -0
  156. package/ios/CodePush/SSZipArchive/aes/prng.c +155 -0
  157. package/ios/CodePush/SSZipArchive/aes/prng.h +82 -0
  158. package/ios/CodePush/SSZipArchive/aes/pwd2key.c +103 -0
  159. package/ios/CodePush/SSZipArchive/aes/pwd2key.h +57 -0
  160. package/ios/CodePush/SSZipArchive/aes/sha1.c +258 -0
  161. package/ios/CodePush/SSZipArchive/aes/sha1.h +73 -0
  162. package/ios/CodePush/SSZipArchive/minizip/crypt.h +130 -0
  163. package/ios/CodePush/SSZipArchive/minizip/ioapi.c +369 -0
  164. package/ios/CodePush/SSZipArchive/minizip/ioapi.h +175 -0
  165. package/ios/CodePush/SSZipArchive/minizip/mztools.c +284 -0
  166. package/ios/CodePush/SSZipArchive/minizip/mztools.h +31 -0
  167. package/ios/CodePush/SSZipArchive/minizip/unzip.c +1839 -0
  168. package/ios/CodePush/SSZipArchive/minizip/unzip.h +248 -0
  169. package/ios/CodePush/SSZipArchive/minizip/zip.c +1910 -0
  170. package/ios/CodePush/SSZipArchive/minizip/zip.h +202 -0
  171. package/ios/CodePush.xcodeproj/project.pbxproj +937 -0
  172. package/ios/CodePush.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  173. package/ios/CodePush.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  174. package/logging.js +6 -0
  175. package/package-mixins.js +61 -0
  176. package/package.json +84 -0
  177. package/react-native.config.js +12 -0
  178. package/scripts/generateBundledResourcesHash.js +125 -0
  179. package/scripts/getFilesInFolder.js +19 -0
  180. package/scripts/recordFilesBeforeBundleCommand.js +41 -0
  181. package/tsconfig.json +14 -0
  182. package/tslint.json +32 -0
  183. package/typings/react-native-code-push.d.ts +589 -0
  184. package/versioning/BaseVersioning.js +126 -0
  185. package/versioning/BaseVersioning.test.js +15 -0
  186. package/versioning/IncrementalVersioning.js +9 -0
  187. package/versioning/IncrementalVersioning.test.js +186 -0
  188. package/versioning/SemverVersioning.js +10 -0
  189. package/versioning/SemverVersioning.test.js +205 -0
  190. package/versioning/index.js +7 -0
@@ -0,0 +1,126 @@
1
+ /**
2
+ * @type {BaseVersioning}
3
+ */
4
+ class BaseVersioning {
5
+ /**
6
+ * @param {ReleaseHistoryInterface} releaseHistory
7
+ * @param {SortingMethod} sortingMethod
8
+ */
9
+ constructor(releaseHistory, sortingMethod) {
10
+ if (this.constructor == BaseVersioning) {
11
+ throw new Error("Abstract classes can't be instantiated.");
12
+ }
13
+ if (releaseHistory == null || sortingMethod == null) {
14
+ throw new Error("param releaseHistory and sortingMethod is needed");
15
+ }
16
+
17
+ /** @type {SortingMethod} */
18
+ this.sortingMethod = sortingMethod;
19
+
20
+ /** @type {ReleaseHistoryInterface} */
21
+ this.originalReleaseHistory = releaseHistory;
22
+
23
+ /** @type {[ReleaseVersion, ReleaseInfo][]} */
24
+ this.sortedReleaseHistory = Object.entries(releaseHistory).sort(
25
+ ([a], [b]) => this.sortingMethod(a, b)
26
+ );
27
+ }
28
+
29
+ /**
30
+ * @return {[ReleaseVersion, ReleaseInfo][]}
31
+ */
32
+ get sortedEnabledReleaseHistory() {
33
+ return this.sortedReleaseHistory.filter(([_, bundle]) => bundle.enabled);
34
+ }
35
+
36
+ /**
37
+ * @return {[ReleaseVersion, ReleaseInfo][]}
38
+ */
39
+ get sortedMandatoryReleaseHistory() {
40
+ return this.sortedEnabledReleaseHistory.filter(
41
+ ([_, bundle]) => bundle.mandatory
42
+ );
43
+ }
44
+
45
+ /**
46
+ * find latest release in releaseHistory
47
+ * @return {[ReleaseVersion, ReleaseInfo]}
48
+ */
49
+ findLatestRelease() {
50
+ const latestReleaseInfo = this.sortedEnabledReleaseHistory.at(0);
51
+
52
+ if (!latestReleaseInfo) {
53
+ throw new Error("There is no latest release.");
54
+ }
55
+
56
+ return latestReleaseInfo;
57
+ }
58
+
59
+ /**
60
+ * check if the update is mandatory
61
+ * @param {ReleaseVersion|undefined} runtimeVersion
62
+ * @return {boolean}
63
+ */
64
+ checkIsMandatory(runtimeVersion) {
65
+ if (this.shouldRollback(runtimeVersion)) {
66
+ // rollback is always mandatory
67
+ return true;
68
+ }
69
+
70
+ if (this.sortedMandatoryReleaseHistory.length === 0) {
71
+ return false;
72
+ }
73
+
74
+ if (!runtimeVersion) {
75
+ // This means that there is at least one mandatory update, but the update has not been installed yet.
76
+ // So, the update is mandatory.
77
+ return true;
78
+ }
79
+
80
+ const [latestMandatoryVersion, _] = this.sortedMandatoryReleaseHistory[0];
81
+ const [larger] = [latestMandatoryVersion, runtimeVersion].sort(this.sortingMethod);
82
+
83
+ return runtimeVersion !== latestMandatoryVersion && larger === latestMandatoryVersion;
84
+ }
85
+
86
+ /**
87
+ * determine whether to rollback and execute it
88
+ * @param {ReleaseVersion|undefined} runtimeVersion
89
+ * @return {boolean}
90
+ */
91
+ shouldRollback(runtimeVersion) {
92
+ if (!runtimeVersion) {
93
+ // Rollback is not possible because no updates have been installed.
94
+ return false;
95
+ }
96
+
97
+ const [latestRelease] = this.findLatestRelease();
98
+ const [larger] = [latestRelease, runtimeVersion].sort(this.sortingMethod);
99
+
100
+ return runtimeVersion !== latestRelease && larger === runtimeVersion;
101
+ }
102
+
103
+ /**
104
+ * Determine whether to clear the currently running bundle.
105
+ * If it returns true, the CodePush bundle will be erased, and the app will restart.
106
+ * @param {ReleaseVersion} runtimeVersion
107
+ * @return {boolean}
108
+ */
109
+ shouldRollbackToBinary(runtimeVersion) {
110
+ if (!runtimeVersion) {
111
+ // Rollback is not possible because no updates have been installed.
112
+ return false;
113
+ }
114
+
115
+ const [latestReleaseVersion] = this.findLatestRelease();
116
+ const [binaryAppVersion] = this.sortedReleaseHistory.at(-1);
117
+
118
+ return (
119
+ runtimeVersion !== latestReleaseVersion &&
120
+ this.shouldRollback(runtimeVersion) &&
121
+ latestReleaseVersion === binaryAppVersion
122
+ );
123
+ }
124
+ }
125
+
126
+ module.exports = { BaseVersioning: BaseVersioning };
@@ -0,0 +1,15 @@
1
+ import { BaseVersioning } from "./BaseVersioning"
2
+
3
+ describe('BaseVersioning', () => {
4
+ describe('constructor', () => {
5
+ it('should throw an error if it is directly instantiated', () => {
6
+ expect(() => new BaseVersioning({})).toThrow("Abstract classes can't be instantiated.")
7
+ })
8
+
9
+ it('should throw an error if releaseHistory is not defined', () => {
10
+ class TestVersioning extends BaseVersioning {}
11
+ expect(() => new TestVersioning()).toThrow("param releaseHistory and sortingMethod is needed")
12
+ expect(() => new TestVersioning({}, () => {})).not.toThrow("param releaseHistory and sortingMethod is needed")
13
+ })
14
+ })
15
+ })
@@ -0,0 +1,9 @@
1
+ const { BaseVersioning } = require("./BaseVersioning");
2
+
3
+ class IncrementalVersioning extends BaseVersioning {
4
+ constructor(releaseHistory) {
5
+ super(releaseHistory, (v1, v2) => Number(v2) - Number(v1));
6
+ }
7
+ }
8
+
9
+ module.exports = { IncrementalVersioning };
@@ -0,0 +1,186 @@
1
+ import { IncrementalVersioning } from "./IncrementalVersioning"
2
+
3
+ describe('Incremental Versioning Test', () => {
4
+ const MOCK_INFOS = { downloadUrl: '', packageHash: '' }
5
+
6
+ // When major version is released, it must be considered like below
7
+ const FIRST_RELEASE_INFO = { enabled: true, mandatory: false, ...MOCK_INFOS };
8
+
9
+ describe('findLatestRelease', () => {
10
+ it('should throw error when there is no releases', () => {
11
+ const RELEASED_BUNDLES_1 = {}
12
+ const RELEASED_BUNDLES_2 = {'1': { enabled: false, mandatory: false, downloadUrl: 'R1', packageHash: 'P1' }}
13
+ expect(() => new IncrementalVersioning(RELEASED_BUNDLES_1).findLatestRelease())
14
+ .toThrow("There is no latest release.")
15
+ expect(() => new IncrementalVersioning(RELEASED_BUNDLES_2).findLatestRelease())
16
+ .toThrow("There is no latest release.")
17
+ })
18
+
19
+ it('should return latest release', () => {
20
+ const RELEASED_BUNDLES = {
21
+ '1': { enabled: true, mandatory: false, downloadUrl: 'R1', packageHash: 'P1' },
22
+ '2': { enabled: true, mandatory: false, downloadUrl: 'R2', packageHash: 'P2' },
23
+ '3': { enabled: true, mandatory: true, downloadUrl: 'R3', packageHash: 'P3' },
24
+ };
25
+
26
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).findLatestRelease()).toEqual([
27
+ '3',
28
+ { enabled: true, mandatory: true, downloadUrl: 'R3', packageHash: 'P3' }
29
+ ])
30
+ })
31
+
32
+ it('should ignore not-enabled bundles and return latest release', () => {
33
+ const RELEASED_BUNDLES_1 = {
34
+ '1': { enabled: true, mandatory: false, downloadUrl: 'R1', packageHash: 'P1' },
35
+ '2': { enabled: false, mandatory: false, downloadUrl: 'R2', packageHash: 'P2' },
36
+ };
37
+
38
+ const RELEASED_BUNDLES_2 = {
39
+ '1': { enabled: true, mandatory: false, downloadUrl: 'R1', packageHash: 'P1' },
40
+ '2': { enabled: false, mandatory: false, downloadUrl: 'R2', packageHash: 'P2' },
41
+ '3': { enabled: true, mandatory: true, downloadUrl: 'R3', packageHash: 'P3' },
42
+ };
43
+
44
+ expect(new IncrementalVersioning(RELEASED_BUNDLES_1).findLatestRelease()).toEqual([
45
+ '1',
46
+ { enabled: true, mandatory: false, downloadUrl: 'R1', packageHash: 'P1' }
47
+ ])
48
+
49
+ expect(new IncrementalVersioning(RELEASED_BUNDLES_2).findLatestRelease()).toEqual([
50
+ '3',
51
+ { enabled: true, mandatory: true, downloadUrl: 'R3', packageHash: 'P3' }
52
+ ])
53
+ })
54
+ })
55
+
56
+ describe('checkIsMandatory', () => {
57
+ describe('not-mandatory cases', () => {
58
+ it('should consider not-mandatory when the first major version is released', () => {
59
+ const RUNTIME_VERSION = '1';
60
+ const RELEASED_BUNDLES = {
61
+ '1': FIRST_RELEASE_INFO,
62
+ };
63
+
64
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(false);
65
+ });
66
+
67
+ it('should consider not-mandatory when latest version is running', () => {
68
+ const RUNTIME_VERSION = '3';
69
+ const RELEASED_BUNDLES = {
70
+ '1': FIRST_RELEASE_INFO,
71
+ '2': { enabled: true, mandatory: false, ...MOCK_INFOS },
72
+ '3': { enabled: true, mandatory: true, ...MOCK_INFOS },
73
+ };
74
+
75
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(false);
76
+ });
77
+
78
+ it('should consider not-mandatory when only not-mandatory version is released', () => {
79
+ const RUNTIME_VERSION = '1';
80
+ const RELEASED_BUNDLES = {
81
+ '1': FIRST_RELEASE_INFO,
82
+ '2': { enabled: true, mandatory: false, ...MOCK_INFOS },
83
+ };
84
+
85
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(false);
86
+ });
87
+
88
+ it('should consider not-mandatory when only not-mandatory version is released after current runtime version', () => {
89
+ const RUNTIME_VERSION = '2';
90
+ const RELEASED_BUNDLES = {
91
+ '1': FIRST_RELEASE_INFO,
92
+ '2': { enabled: true, mandatory: true, ...MOCK_INFOS },
93
+ '3': { enabled: true, mandatory: false, ...MOCK_INFOS },
94
+ };
95
+
96
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(false);
97
+ });
98
+ })
99
+
100
+ describe('mandatory cases', () => {
101
+ it('should consider mandatory when mandatory release exists', () => {
102
+ const RUNTIME_VERSION = '1';
103
+ const RELEASED_BUNDLES = {
104
+ '1': FIRST_RELEASE_INFO,
105
+ '2': { enabled: true, mandatory: true, ...MOCK_INFOS },
106
+ };
107
+
108
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(true);
109
+ });
110
+
111
+ it("should consider mandatory if there's a mandatory release between the runtime version and the latest", () => {
112
+ const RUNTIME_VERSION = '1'
113
+ const RELEASED_BUNDLES = {
114
+ '1': FIRST_RELEASE_INFO,
115
+ '2': { enabled: true, mandatory: true, ...MOCK_INFOS },
116
+ '3': { enabled: true, mandatory: false, ...MOCK_INFOS },
117
+ }
118
+
119
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(true);
120
+ })
121
+
122
+ it('should consider mandatory when latest version < current runtime version (ROLLBACK)', () => {
123
+ const RELEASED_BUNDLES = {
124
+ '1': FIRST_RELEASE_INFO,
125
+ };
126
+ const currentVersion = '2'
127
+
128
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).shouldRollback(currentVersion)).toBe(true)
129
+ })
130
+ })
131
+
132
+ describe('scenario test', () => {
133
+ it('Major Release > Mandatory > Not-mandatory > Mandatory > Not-mandatory', () => {
134
+ const RELEASED_BUNDLES = {
135
+ '1': FIRST_RELEASE_INFO,
136
+ '2': { enabled: true, mandatory: true, ...MOCK_INFOS },
137
+ '3': { enabled: true, mandatory: false, ...MOCK_INFOS },
138
+ '4': { enabled: true, mandatory: true, ...MOCK_INFOS },
139
+ '5': { enabled: true, mandatory: false, ...MOCK_INFOS },
140
+ };
141
+
142
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('1')).toBe(true);
143
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('2')).toBe(true);
144
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('3')).toBe(true);
145
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('4')).toBe(false);
146
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('5')).toBe(false);
147
+ });
148
+
149
+ it('When having not-enabled releases', () => {
150
+ const RELEASED_BUNDLES = {
151
+ '1': FIRST_RELEASE_INFO,
152
+ '2': { enabled: true, mandatory: true, ...MOCK_INFOS },
153
+ '3': { enabled: false, mandatory: false, ...MOCK_INFOS },
154
+ '4': { enabled: true, mandatory: true, ...MOCK_INFOS },
155
+ '5': { enabled: false, mandatory: false, ...MOCK_INFOS },
156
+ };
157
+
158
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('1')).toBe(true);
159
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('2')).toBe(true);
160
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('3')).toBe(true);
161
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('4')).toBe(false);
162
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).checkIsMandatory('5')).toBe(true);
163
+ });
164
+ })
165
+ })
166
+
167
+ describe('shouldRollbackToBinary', () => {
168
+ it('should return true when destination version is the first major version', () => {
169
+ const RELEASED_BUNDLES = {
170
+ '1': FIRST_RELEASE_INFO,
171
+ '2': { enabled: false, mandatory: true, ...MOCK_INFOS },
172
+ };
173
+
174
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).shouldRollbackToBinary('2')).toBe(true)
175
+ })
176
+
177
+ it('should return false when runtime version is the same as destination version', () => {
178
+ const RELEASED_BUNDLES = {
179
+ '1': FIRST_RELEASE_INFO,
180
+ '2': { enabled: false, mandatory: true, ...MOCK_INFOS },
181
+ };
182
+
183
+ expect(new IncrementalVersioning(RELEASED_BUNDLES).shouldRollbackToBinary('1')).toBe(false)
184
+ })
185
+ })
186
+ })
@@ -0,0 +1,10 @@
1
+ const Semver = require("semver");
2
+ const { BaseVersioning } = require("./BaseVersioning");
3
+
4
+ class SemverVersioning extends BaseVersioning {
5
+ constructor(releaseHistory) {
6
+ super(releaseHistory, (v1, v2) => (Semver.gt(v1, v2) ? -1 : 1));
7
+ }
8
+ }
9
+
10
+ module.exports = { SemverVersioning };
@@ -0,0 +1,205 @@
1
+ import { SemverVersioning } from "./SemverVersioning";
2
+
3
+ describe('Semver Versioning Test', () => {
4
+ const MOCK_INFOS = { downloadUrl: '', packageHash: '' }
5
+
6
+ // When major version is released, it must be considered like below
7
+ const FIRST_RELEASE_INFO = { enabled: true, mandatory: false, ...MOCK_INFOS };
8
+
9
+ describe('findLatestRelease', () => {
10
+ it('should throw error when there is no releases', () => {
11
+ const RELEASED_BUNDLES = {}
12
+ expect(() => new SemverVersioning(RELEASED_BUNDLES).findLatestRelease())
13
+ .toThrow("There is no latest release.")
14
+ })
15
+
16
+ it('should return latest release', () => {
17
+ const RELEASED_BUNDLES = {
18
+ '1.0.0': { enabled: true, mandatory: false, downloadUrl: 'R1', packageHash: 'P1' },
19
+ '1.1.0': { enabled: true, mandatory: false, downloadUrl: 'R2', packageHash: 'P2' },
20
+ '1.1.1': { enabled: true, mandatory: true, downloadUrl: 'R3', packageHash: 'P3' },
21
+ };
22
+
23
+ expect(new SemverVersioning(RELEASED_BUNDLES).findLatestRelease()).toEqual([
24
+ '1.1.1',
25
+ { enabled: true, mandatory: true, downloadUrl: 'R3', packageHash: 'P3' }
26
+ ])
27
+ })
28
+
29
+ it('should ignore not-enabled bundles and return latest release', () => {
30
+ const RELEASED_BUNDLES_1 = {
31
+ '1.0.0': { enabled: true, mandatory: false, downloadUrl: 'R1', packageHash: 'P1' },
32
+ '1.1.0': { enabled: false, mandatory: false, downloadUrl: 'R2', packageHash: 'P2' },
33
+ };
34
+
35
+ const RELEASED_BUNDLES_2 = {
36
+ '1.0.0': { enabled: true, mandatory: false, downloadUrl: 'R1', packageHash: 'P1' },
37
+ '1.1.0': { enabled: false, mandatory: false, downloadUrl: 'R2', packageHash: 'P2' },
38
+ '1.1.1': { enabled: true, mandatory: true, downloadUrl: 'R3', packageHash: 'P3' },
39
+ };
40
+
41
+ expect(new SemverVersioning(RELEASED_BUNDLES_1).findLatestRelease()).toEqual([
42
+ '1.0.0',
43
+ { enabled: true, mandatory: false, downloadUrl: 'R1', packageHash: 'P1' }
44
+ ])
45
+
46
+ expect(new SemverVersioning(RELEASED_BUNDLES_2).findLatestRelease()).toEqual([
47
+ '1.1.1',
48
+ { enabled: true, mandatory: true, downloadUrl: 'R3', packageHash: 'P3' }
49
+ ])
50
+ })
51
+ })
52
+
53
+ describe('checkIsMandatory', () => {
54
+ describe('not-mandatory cases', () => {
55
+ it('should consider not-mandatory when the first major version is released', () => {
56
+ const RUNTIME_VERSION = '1.0.0';
57
+ const RELEASED_BUNDLES = {
58
+ '1.0.0': FIRST_RELEASE_INFO,
59
+ };
60
+
61
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(false);
62
+ });
63
+
64
+ it('should consider not-mandatory when latest version is running', () => {
65
+ const RUNTIME_VERSION = '1.1.1';
66
+ const RELEASED_BUNDLES = {
67
+ '1.0.0': FIRST_RELEASE_INFO,
68
+ '1.1.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
69
+ '1.1.1': { enabled: true, mandatory: true, ...MOCK_INFOS },
70
+ };
71
+
72
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(false);
73
+ });
74
+
75
+ it('should consider not-mandatory when only not-mandatory version is released', () => {
76
+ const RUNTIME_VERSION = '1.0.0';
77
+ const RELEASED_BUNDLES = {
78
+ '1.0.0': FIRST_RELEASE_INFO,
79
+ '1.1.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
80
+ };
81
+
82
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(false);
83
+ });
84
+
85
+ it('should consider not-mandatory when only not-mandatory version is released after current runtime version', () => {
86
+ const RUNTIME_VERSION = '1.0.1';
87
+ const RELEASED_BUNDLES = {
88
+ '1.0.0': FIRST_RELEASE_INFO,
89
+ '1.0.1': { enabled: true, mandatory: true, ...MOCK_INFOS },
90
+ '1.1.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
91
+ };
92
+
93
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(false);
94
+ });
95
+ })
96
+
97
+ describe('mandatory cases', () => {
98
+ it('should consider mandatory when mandatory release exists', () => {
99
+ const RUNTIME_VERSION = '1.0.0';
100
+ const RELEASED_BUNDLES = {
101
+ '1.0.0': FIRST_RELEASE_INFO,
102
+ '1.0.1': { enabled: true, mandatory: true, ...MOCK_INFOS },
103
+ };
104
+
105
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(true);
106
+ });
107
+
108
+ it("should consider mandatory if there's a mandatory release between the runtime version and the latest", () => {
109
+ const RUNTIME_VERSION = '1.0.0'
110
+ const RELEASED_BUNDLES = {
111
+ '1.0.0': FIRST_RELEASE_INFO,
112
+ '1.2.0': { enabled: true, mandatory: true, ...MOCK_INFOS },
113
+ '1.3.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
114
+ }
115
+
116
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory(RUNTIME_VERSION)).toBe(true);
117
+ })
118
+
119
+ it('should consider mandatory when latest version < current runtime version (ROLLBACK)', () => {
120
+ const RELEASED_BUNDLES = {
121
+ '1.1.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
122
+ };
123
+ const currentVersion = '1.2.0'
124
+
125
+ expect(new SemverVersioning(RELEASED_BUNDLES).shouldRollback(currentVersion)).toBe(true)
126
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory(currentVersion)).toBe(true)
127
+ })
128
+ })
129
+
130
+ describe('scenario test', () => {
131
+ it('Major Release > Mandatory > Not-mandatory > Mandatory > Not-mandatory', () => {
132
+ const RELEASED_BUNDLES = {
133
+ '1.0.0': FIRST_RELEASE_INFO,
134
+ '1.0.1': { enabled: true, mandatory: true, ...MOCK_INFOS },
135
+ '1.1.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
136
+ '1.1.1': { enabled: true, mandatory: true, ...MOCK_INFOS },
137
+ '1.2.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
138
+ };
139
+
140
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory('1.0.0')).toBe(true);
141
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory('1.0.1')).toBe(true);
142
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory('1.1.0')).toBe(true);
143
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory('1.1.1')).toBe(false);
144
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory('1.2.0')).toBe(false);
145
+ });
146
+
147
+ it('When having not-enabled releases', () => {
148
+ const RELEASED_BUNDLES = {
149
+ '1.0.0': FIRST_RELEASE_INFO,
150
+ '1.0.1': { enabled: true, mandatory: true, ...MOCK_INFOS },
151
+ '1.1.0': { enabled: false, mandatory: false, ...MOCK_INFOS },
152
+ '1.1.1': { enabled: true, mandatory: true, ...MOCK_INFOS },
153
+ '1.2.0': { enabled: false, mandatory: false, ...MOCK_INFOS },
154
+ };
155
+
156
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory('1.0.0')).toBe(true);
157
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory('1.0.1')).toBe(true);
158
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory('1.1.0')).toBe(true);
159
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory('1.1.1')).toBe(false);
160
+ expect(new SemverVersioning(RELEASED_BUNDLES).checkIsMandatory('1.2.0')).toBe(true);
161
+ });
162
+ })
163
+ })
164
+
165
+ describe('shouldRollbackToBinary', () => {
166
+ it('should return false if it is not required to rollback', () => {
167
+ const RELEASED_BUNDLES_1 = {
168
+ '1.0.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
169
+ };
170
+ const RELEASED_BUNDLES_2 = {
171
+ '1.0.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
172
+ '1.1.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
173
+ '1.2.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
174
+ };
175
+ expect(new SemverVersioning(RELEASED_BUNDLES_1).shouldRollbackToBinary('1.0.0')).toBe(false)
176
+ expect(new SemverVersioning(RELEASED_BUNDLES_2).shouldRollbackToBinary('1.1.0')).toBe(false)
177
+ })
178
+
179
+ it('should return true if the destination version is the latest major version', () => {
180
+ const RELEASED_BUNDLES_1 = {
181
+ '1.0.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
182
+ '1.1.0': { enabled: false, mandatory: false, ...MOCK_INFOS },
183
+ '1.2.0': { enabled: false, mandatory: false, ...MOCK_INFOS },
184
+ };
185
+ const RELEASED_BUNDLES_2 = {
186
+ '1.2.0-rc.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
187
+ };
188
+ expect(new SemverVersioning(RELEASED_BUNDLES_1).shouldRollbackToBinary('1.2.0')).toBe(true)
189
+ expect(new SemverVersioning(RELEASED_BUNDLES_2).shouldRollbackToBinary('1.2.0-rc.2')).toBe(true)
190
+ })
191
+
192
+ it('should return false if the destination version is not the latest major version', () => {
193
+ const RELEASED_BUNDLES_1 = {
194
+ '1.0.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
195
+ '1.1.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
196
+ };
197
+ const RELEASED_BUNDLES_2 = {
198
+ '1.2.0-rc.0': { enabled: true, mandatory: false, ...MOCK_INFOS },
199
+ '1.2.0-rc.1': { enabled: true, mandatory: false, ...MOCK_INFOS },
200
+ };
201
+ expect(new SemverVersioning(RELEASED_BUNDLES_1).shouldRollbackToBinary('1.2.0')).toBe(false)
202
+ expect(new SemverVersioning(RELEASED_BUNDLES_2).shouldRollbackToBinary('1.2.0-rc.2')).toBe(false)
203
+ })
204
+ })
205
+ })
@@ -0,0 +1,7 @@
1
+ const { BaseVersioning } = require("./BaseVersioning");
2
+ const { SemverVersioning } = require("./SemverVersioning");
3
+
4
+ module.exports = {
5
+ SemverVersioning,
6
+ BaseVersioning,
7
+ };