@rs-native-kit/version-check 0.1.2

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 (371) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +256 -0
  3. package/VersionCheck.podspec +20 -0
  4. package/android/build.gradle +56 -0
  5. package/android/src/main/AndroidManifest.xml +9 -0
  6. package/android/src/main/java/com/rsnativekit/versioncheck/SecureStorageCipher.kt +57 -0
  7. package/android/src/main/java/com/rsnativekit/versioncheck/VersionCheckHeadlessTaskService.kt +31 -0
  8. package/android/src/main/java/com/rsnativekit/versioncheck/VersionCheckModule.kt +215 -0
  9. package/android/src/main/java/com/rsnativekit/versioncheck/VersionCheckPackage.kt +31 -0
  10. package/android/src/main/java/com/rsnativekit/versioncheck/VersionCheckWorker.kt +29 -0
  11. package/ios/PlatformBridge/Ed25519Verifier.swift +19 -0
  12. package/ios/VersionCheck.h +5 -0
  13. package/ios/VersionCheck.mm +278 -0
  14. package/lib/module/data/cache/MemoryCacheStore.js +30 -0
  15. package/lib/module/data/cache/MemoryCacheStore.js.map +1 -0
  16. package/lib/module/data/cache/PersistentCacheStore.js +56 -0
  17. package/lib/module/data/cache/PersistentCacheStore.js.map +1 -0
  18. package/lib/module/data/config/ConfigCache.js +29 -0
  19. package/lib/module/data/config/ConfigCache.js.map +1 -0
  20. package/lib/module/data/config/ConfigDocumentValidator.js +185 -0
  21. package/lib/module/data/config/ConfigDocumentValidator.js.map +1 -0
  22. package/lib/module/data/config/ConfigLoader.js +82 -0
  23. package/lib/module/data/config/ConfigLoader.js.map +1 -0
  24. package/lib/module/data/config/ConfigProvider.js +58 -0
  25. package/lib/module/data/config/ConfigProvider.js.map +1 -0
  26. package/lib/module/data/config/ConfigResolutionPipeline.js +268 -0
  27. package/lib/module/data/config/ConfigResolutionPipeline.js.map +1 -0
  28. package/lib/module/data/config/ConfigValidator.js +69 -0
  29. package/lib/module/data/config/ConfigValidator.js.map +1 -0
  30. package/lib/module/data/config/SignatureVerifier.js +80 -0
  31. package/lib/module/data/config/SignatureVerifier.js.map +1 -0
  32. package/lib/module/data/config/canonicalize.js +88 -0
  33. package/lib/module/data/config/canonicalize.js.map +1 -0
  34. package/lib/module/data/config/sources/EnvironmentOverrideSource.js +20 -0
  35. package/lib/module/data/config/sources/EnvironmentOverrideSource.js.map +1 -0
  36. package/lib/module/data/config/sources/LocalConfigSource.js +22 -0
  37. package/lib/module/data/config/sources/LocalConfigSource.js.map +1 -0
  38. package/lib/module/data/config/sources/RemoteConfigSource.js +38 -0
  39. package/lib/module/data/config/sources/RemoteConfigSource.js.map +1 -0
  40. package/lib/module/data/providers/amazon/AmazonAppstoreProvider.js +13 -0
  41. package/lib/module/data/providers/amazon/AmazonAppstoreProvider.js.map +1 -0
  42. package/lib/module/data/providers/apple/AppleStoreProvider.js +67 -0
  43. package/lib/module/data/providers/apple/AppleStoreProvider.js.map +1 -0
  44. package/lib/module/data/providers/custom-api/CustomApiProvider.js +51 -0
  45. package/lib/module/data/providers/custom-api/CustomApiProvider.js.map +1 -0
  46. package/lib/module/data/providers/firebase-remote-config/FirebaseRemoteConfigProvider.js +13 -0
  47. package/lib/module/data/providers/firebase-remote-config/FirebaseRemoteConfigProvider.js.map +1 -0
  48. package/lib/module/data/providers/google-play/GooglePlayProvider.js +62 -0
  49. package/lib/module/data/providers/google-play/GooglePlayProvider.js.map +1 -0
  50. package/lib/module/data/providers/huawei/HuaweiAppGalleryProvider.js +18 -0
  51. package/lib/module/data/providers/huawei/HuaweiAppGalleryProvider.js.map +1 -0
  52. package/lib/module/data/repositories/VersionRepositoryImpl.js +69 -0
  53. package/lib/module/data/repositories/VersionRepositoryImpl.js.map +1 -0
  54. package/lib/module/di/container.js +80 -0
  55. package/lib/module/di/container.js.map +1 -0
  56. package/lib/module/domain/IVersionManagerCore.js +4 -0
  57. package/lib/module/domain/IVersionManagerCore.js.map +1 -0
  58. package/lib/module/domain/VersionManagerCore.js +276 -0
  59. package/lib/module/domain/VersionManagerCore.js.map +1 -0
  60. package/lib/module/domain/engines/decision/DecisionEngine.js +40 -0
  61. package/lib/module/domain/engines/decision/DecisionEngine.js.map +1 -0
  62. package/lib/module/domain/engines/policy/IUpdatePolicyEngine.js +4 -0
  63. package/lib/module/domain/engines/policy/IUpdatePolicyEngine.js.map +1 -0
  64. package/lib/module/domain/engines/policy/PolicyEngine.js +42 -0
  65. package/lib/module/domain/engines/policy/PolicyEngine.js.map +1 -0
  66. package/lib/module/domain/engines/semver/IVersionComparator.js +4 -0
  67. package/lib/module/domain/engines/semver/IVersionComparator.js.map +1 -0
  68. package/lib/module/domain/engines/semver/SemVerEngine.js +176 -0
  69. package/lib/module/domain/engines/semver/SemVerEngine.js.map +1 -0
  70. package/lib/module/domain/errors/VersionManagerException.js +104 -0
  71. package/lib/module/domain/errors/VersionManagerException.js.map +1 -0
  72. package/lib/module/domain/models/ActionPlan.js +9 -0
  73. package/lib/module/domain/models/ActionPlan.js.map +1 -0
  74. package/lib/module/domain/models/ConfigDocument.js +4 -0
  75. package/lib/module/domain/models/ConfigDocument.js.map +1 -0
  76. package/lib/module/domain/models/Events.js +4 -0
  77. package/lib/module/domain/models/Events.js.map +1 -0
  78. package/lib/module/domain/models/LifecycleState.js +29 -0
  79. package/lib/module/domain/models/LifecycleState.js.map +1 -0
  80. package/lib/module/domain/models/ParsedVersion.js +2 -0
  81. package/lib/module/domain/models/ParsedVersion.js.map +1 -0
  82. package/lib/module/domain/models/PlatformId.js +2 -0
  83. package/lib/module/domain/models/PlatformId.js.map +1 -0
  84. package/lib/module/domain/models/PublicApiOptions.js +2 -0
  85. package/lib/module/domain/models/PublicApiOptions.js.map +1 -0
  86. package/lib/module/domain/models/RemoteVersionInfo.js +4 -0
  87. package/lib/module/domain/models/RemoteVersionInfo.js.map +1 -0
  88. package/lib/module/domain/models/StoreLookup.js +2 -0
  89. package/lib/module/domain/models/StoreLookup.js.map +1 -0
  90. package/lib/module/domain/models/Unsubscribe.js +2 -0
  91. package/lib/module/domain/models/Unsubscribe.js.map +1 -0
  92. package/lib/module/domain/models/UpdateInfo.js +4 -0
  93. package/lib/module/domain/models/UpdateInfo.js.map +1 -0
  94. package/lib/module/domain/models/VersionManagerOptions.js +4 -0
  95. package/lib/module/domain/models/VersionManagerOptions.js.map +1 -0
  96. package/lib/module/domain/ports/ICacheStore.js +2 -0
  97. package/lib/module/domain/ports/ICacheStore.js.map +1 -0
  98. package/lib/module/domain/ports/IClock.js +2 -0
  99. package/lib/module/domain/ports/IClock.js.map +1 -0
  100. package/lib/module/domain/ports/IConfigProvider.js +4 -0
  101. package/lib/module/domain/ports/IConfigProvider.js.map +1 -0
  102. package/lib/module/domain/ports/IConfigSources.js +4 -0
  103. package/lib/module/domain/ports/IConfigSources.js.map +1 -0
  104. package/lib/module/domain/ports/IPlatformBridge.js +4 -0
  105. package/lib/module/domain/ports/IPlatformBridge.js.map +1 -0
  106. package/lib/module/domain/ports/IStoreProvider.js +4 -0
  107. package/lib/module/domain/ports/IStoreProvider.js.map +1 -0
  108. package/lib/module/domain/ports/IVersionRepository.js +4 -0
  109. package/lib/module/domain/ports/IVersionRepository.js.map +1 -0
  110. package/lib/module/domain/statemachine/LifecycleStateMachine.js +55 -0
  111. package/lib/module/domain/statemachine/LifecycleStateMachine.js.map +1 -0
  112. package/lib/module/domain/usecases/CheckForUpdatesUseCase.js +31 -0
  113. package/lib/module/domain/usecases/CheckForUpdatesUseCase.js.map +1 -0
  114. package/lib/module/domain/usecases/ForceTriggerUpdateUseCase.js +20 -0
  115. package/lib/module/domain/usecases/ForceTriggerUpdateUseCase.js.map +1 -0
  116. package/lib/module/domain/usecases/ResetIgnoredVersionsUseCase.js +24 -0
  117. package/lib/module/domain/usecases/ResetIgnoredVersionsUseCase.js.map +1 -0
  118. package/lib/module/index.js +10 -0
  119. package/lib/module/index.js.map +1 -0
  120. package/lib/module/package.json +1 -0
  121. package/lib/module/platform/contracts/IPlatformBridge.js +2 -0
  122. package/lib/module/platform/contracts/IPlatformBridge.js.map +1 -0
  123. package/lib/module/platform/createPlatformBridge.js +17 -0
  124. package/lib/module/platform/createPlatformBridge.js.map +1 -0
  125. package/lib/module/platform/createPlatformBridge.native.js +9 -0
  126. package/lib/module/platform/createPlatformBridge.native.js.map +1 -0
  127. package/lib/module/platform/native/NativePlatformBridge.js +143 -0
  128. package/lib/module/platform/native/NativePlatformBridge.js.map +1 -0
  129. package/lib/module/platform/native/NativeVersionCheck.js +33 -0
  130. package/lib/module/platform/native/NativeVersionCheck.js.map +1 -0
  131. package/lib/module/platform/web/WebPlatformBridge.js +228 -0
  132. package/lib/module/platform/web/WebPlatformBridge.js.map +1 -0
  133. package/lib/module/presentation/components/ForceUpdateScreen.js +68 -0
  134. package/lib/module/presentation/components/ForceUpdateScreen.js.map +1 -0
  135. package/lib/module/presentation/components/OptionalUpdateBanner.js +69 -0
  136. package/lib/module/presentation/components/OptionalUpdateBanner.js.map +1 -0
  137. package/lib/module/presentation/components/SoftUpdateDialog.js +101 -0
  138. package/lib/module/presentation/components/SoftUpdateDialog.js.map +1 -0
  139. package/lib/module/presentation/hooks/VersionManagerProvider.js +18 -0
  140. package/lib/module/presentation/hooks/VersionManagerProvider.js.map +1 -0
  141. package/lib/module/presentation/hooks/context.js +5 -0
  142. package/lib/module/presentation/hooks/context.js.map +1 -0
  143. package/lib/module/presentation/hooks/useUpdateState.js +26 -0
  144. package/lib/module/presentation/hooks/useUpdateState.js.map +1 -0
  145. package/lib/module/presentation/hooks/useVersionManager.js +33 -0
  146. package/lib/module/presentation/hooks/useVersionManager.js.map +1 -0
  147. package/lib/module/presentation/state/VersionManagerStore.js +47 -0
  148. package/lib/module/presentation/state/VersionManagerStore.js.map +1 -0
  149. package/lib/module/publicApi.js +114 -0
  150. package/lib/module/publicApi.js.map +1 -0
  151. package/lib/module/shared/eventbus/EventBus.js +34 -0
  152. package/lib/module/shared/eventbus/EventBus.js.map +1 -0
  153. package/lib/module/shared/logging/Logger.js +56 -0
  154. package/lib/module/shared/logging/Logger.js.map +1 -0
  155. package/lib/module/ui.js +13 -0
  156. package/lib/module/ui.js.map +1 -0
  157. package/lib/typescript/package.json +1 -0
  158. package/lib/typescript/src/data/cache/MemoryCacheStore.d.ts +12 -0
  159. package/lib/typescript/src/data/cache/MemoryCacheStore.d.ts.map +1 -0
  160. package/lib/typescript/src/data/cache/PersistentCacheStore.d.ts +14 -0
  161. package/lib/typescript/src/data/cache/PersistentCacheStore.d.ts.map +1 -0
  162. package/lib/typescript/src/data/config/ConfigCache.d.ts +15 -0
  163. package/lib/typescript/src/data/config/ConfigCache.d.ts.map +1 -0
  164. package/lib/typescript/src/data/config/ConfigDocumentValidator.d.ts +20 -0
  165. package/lib/typescript/src/data/config/ConfigDocumentValidator.d.ts.map +1 -0
  166. package/lib/typescript/src/data/config/ConfigLoader.d.ts +28 -0
  167. package/lib/typescript/src/data/config/ConfigLoader.d.ts.map +1 -0
  168. package/lib/typescript/src/data/config/ConfigProvider.d.ts +30 -0
  169. package/lib/typescript/src/data/config/ConfigProvider.d.ts.map +1 -0
  170. package/lib/typescript/src/data/config/ConfigResolutionPipeline.d.ts +49 -0
  171. package/lib/typescript/src/data/config/ConfigResolutionPipeline.d.ts.map +1 -0
  172. package/lib/typescript/src/data/config/ConfigValidator.d.ts +10 -0
  173. package/lib/typescript/src/data/config/ConfigValidator.d.ts.map +1 -0
  174. package/lib/typescript/src/data/config/SignatureVerifier.d.ts +16 -0
  175. package/lib/typescript/src/data/config/SignatureVerifier.d.ts.map +1 -0
  176. package/lib/typescript/src/data/config/canonicalize.d.ts +13 -0
  177. package/lib/typescript/src/data/config/canonicalize.d.ts.map +1 -0
  178. package/lib/typescript/src/data/config/sources/EnvironmentOverrideSource.d.ts +17 -0
  179. package/lib/typescript/src/data/config/sources/EnvironmentOverrideSource.d.ts.map +1 -0
  180. package/lib/typescript/src/data/config/sources/LocalConfigSource.d.ts +19 -0
  181. package/lib/typescript/src/data/config/sources/LocalConfigSource.d.ts.map +1 -0
  182. package/lib/typescript/src/data/config/sources/RemoteConfigSource.d.ts +10 -0
  183. package/lib/typescript/src/data/config/sources/RemoteConfigSource.d.ts.map +1 -0
  184. package/lib/typescript/src/data/providers/amazon/AmazonAppstoreProvider.d.ts +9 -0
  185. package/lib/typescript/src/data/providers/amazon/AmazonAppstoreProvider.d.ts.map +1 -0
  186. package/lib/typescript/src/data/providers/apple/AppleStoreProvider.d.ts +19 -0
  187. package/lib/typescript/src/data/providers/apple/AppleStoreProvider.d.ts.map +1 -0
  188. package/lib/typescript/src/data/providers/custom-api/CustomApiProvider.d.ts +14 -0
  189. package/lib/typescript/src/data/providers/custom-api/CustomApiProvider.d.ts.map +1 -0
  190. package/lib/typescript/src/data/providers/firebase-remote-config/FirebaseRemoteConfigProvider.d.ts +9 -0
  191. package/lib/typescript/src/data/providers/firebase-remote-config/FirebaseRemoteConfigProvider.d.ts.map +1 -0
  192. package/lib/typescript/src/data/providers/google-play/GooglePlayProvider.d.ts +22 -0
  193. package/lib/typescript/src/data/providers/google-play/GooglePlayProvider.d.ts.map +1 -0
  194. package/lib/typescript/src/data/providers/huawei/HuaweiAppGalleryProvider.d.ts +14 -0
  195. package/lib/typescript/src/data/providers/huawei/HuaweiAppGalleryProvider.d.ts.map +1 -0
  196. package/lib/typescript/src/data/repositories/VersionRepositoryImpl.d.ts +23 -0
  197. package/lib/typescript/src/data/repositories/VersionRepositoryImpl.d.ts.map +1 -0
  198. package/lib/typescript/src/di/container.d.ts +12 -0
  199. package/lib/typescript/src/di/container.d.ts.map +1 -0
  200. package/lib/typescript/src/domain/IVersionManagerCore.d.ts +30 -0
  201. package/lib/typescript/src/domain/IVersionManagerCore.d.ts.map +1 -0
  202. package/lib/typescript/src/domain/VersionManagerCore.d.ts +94 -0
  203. package/lib/typescript/src/domain/VersionManagerCore.d.ts.map +1 -0
  204. package/lib/typescript/src/domain/engines/decision/DecisionEngine.d.ts +16 -0
  205. package/lib/typescript/src/domain/engines/decision/DecisionEngine.d.ts.map +1 -0
  206. package/lib/typescript/src/domain/engines/policy/IUpdatePolicyEngine.d.ts +17 -0
  207. package/lib/typescript/src/domain/engines/policy/IUpdatePolicyEngine.d.ts.map +1 -0
  208. package/lib/typescript/src/domain/engines/policy/PolicyEngine.d.ts +16 -0
  209. package/lib/typescript/src/domain/engines/policy/PolicyEngine.d.ts.map +1 -0
  210. package/lib/typescript/src/domain/engines/semver/IVersionComparator.d.ts +7 -0
  211. package/lib/typescript/src/domain/engines/semver/IVersionComparator.d.ts.map +1 -0
  212. package/lib/typescript/src/domain/engines/semver/SemVerEngine.d.ts +11 -0
  213. package/lib/typescript/src/domain/engines/semver/SemVerEngine.d.ts.map +1 -0
  214. package/lib/typescript/src/domain/errors/VersionManagerException.d.ts +97 -0
  215. package/lib/typescript/src/domain/errors/VersionManagerException.d.ts.map +1 -0
  216. package/lib/typescript/src/domain/models/ActionPlan.d.ts +15 -0
  217. package/lib/typescript/src/domain/models/ActionPlan.d.ts.map +1 -0
  218. package/lib/typescript/src/domain/models/ConfigDocument.d.ts +86 -0
  219. package/lib/typescript/src/domain/models/ConfigDocument.d.ts.map +1 -0
  220. package/lib/typescript/src/domain/models/Events.d.ts +39 -0
  221. package/lib/typescript/src/domain/models/Events.d.ts.map +1 -0
  222. package/lib/typescript/src/domain/models/LifecycleState.d.ts +18 -0
  223. package/lib/typescript/src/domain/models/LifecycleState.d.ts.map +1 -0
  224. package/lib/typescript/src/domain/models/ParsedVersion.d.ts +9 -0
  225. package/lib/typescript/src/domain/models/ParsedVersion.d.ts.map +1 -0
  226. package/lib/typescript/src/domain/models/PlatformId.d.ts +3 -0
  227. package/lib/typescript/src/domain/models/PlatformId.d.ts.map +1 -0
  228. package/lib/typescript/src/domain/models/PublicApiOptions.d.ts +13 -0
  229. package/lib/typescript/src/domain/models/PublicApiOptions.d.ts.map +1 -0
  230. package/lib/typescript/src/domain/models/RemoteVersionInfo.d.ts +21 -0
  231. package/lib/typescript/src/domain/models/RemoteVersionInfo.d.ts.map +1 -0
  232. package/lib/typescript/src/domain/models/StoreLookup.d.ts +12 -0
  233. package/lib/typescript/src/domain/models/StoreLookup.d.ts.map +1 -0
  234. package/lib/typescript/src/domain/models/Unsubscribe.d.ts +2 -0
  235. package/lib/typescript/src/domain/models/Unsubscribe.d.ts.map +1 -0
  236. package/lib/typescript/src/domain/models/UpdateInfo.d.ts +11 -0
  237. package/lib/typescript/src/domain/models/UpdateInfo.d.ts.map +1 -0
  238. package/lib/typescript/src/domain/models/VersionManagerOptions.d.ts +149 -0
  239. package/lib/typescript/src/domain/models/VersionManagerOptions.d.ts.map +1 -0
  240. package/lib/typescript/src/domain/ports/ICacheStore.d.ts +6 -0
  241. package/lib/typescript/src/domain/ports/ICacheStore.d.ts.map +1 -0
  242. package/lib/typescript/src/domain/ports/IClock.d.ts +4 -0
  243. package/lib/typescript/src/domain/ports/IClock.d.ts.map +1 -0
  244. package/lib/typescript/src/domain/ports/IConfigProvider.d.ts +11 -0
  245. package/lib/typescript/src/domain/ports/IConfigProvider.d.ts.map +1 -0
  246. package/lib/typescript/src/domain/ports/IConfigSources.d.ts +25 -0
  247. package/lib/typescript/src/domain/ports/IConfigSources.d.ts.map +1 -0
  248. package/lib/typescript/src/domain/ports/IPlatformBridge.d.ts +77 -0
  249. package/lib/typescript/src/domain/ports/IPlatformBridge.d.ts.map +1 -0
  250. package/lib/typescript/src/domain/ports/IStoreProvider.d.ts +7 -0
  251. package/lib/typescript/src/domain/ports/IStoreProvider.d.ts.map +1 -0
  252. package/lib/typescript/src/domain/ports/IVersionRepository.d.ts +8 -0
  253. package/lib/typescript/src/domain/ports/IVersionRepository.d.ts.map +1 -0
  254. package/lib/typescript/src/domain/statemachine/LifecycleStateMachine.d.ts +25 -0
  255. package/lib/typescript/src/domain/statemachine/LifecycleStateMachine.d.ts.map +1 -0
  256. package/lib/typescript/src/domain/usecases/CheckForUpdatesUseCase.d.ts +30 -0
  257. package/lib/typescript/src/domain/usecases/CheckForUpdatesUseCase.d.ts.map +1 -0
  258. package/lib/typescript/src/domain/usecases/ForceTriggerUpdateUseCase.d.ts +17 -0
  259. package/lib/typescript/src/domain/usecases/ForceTriggerUpdateUseCase.d.ts.map +1 -0
  260. package/lib/typescript/src/domain/usecases/ResetIgnoredVersionsUseCase.d.ts +7 -0
  261. package/lib/typescript/src/domain/usecases/ResetIgnoredVersionsUseCase.d.ts.map +1 -0
  262. package/lib/typescript/src/index.d.ts +17 -0
  263. package/lib/typescript/src/index.d.ts.map +1 -0
  264. package/lib/typescript/src/platform/contracts/IPlatformBridge.d.ts +2 -0
  265. package/lib/typescript/src/platform/contracts/IPlatformBridge.d.ts.map +1 -0
  266. package/lib/typescript/src/platform/createPlatformBridge.d.ts +12 -0
  267. package/lib/typescript/src/platform/createPlatformBridge.d.ts.map +1 -0
  268. package/lib/typescript/src/platform/createPlatformBridge.native.d.ts +4 -0
  269. package/lib/typescript/src/platform/createPlatformBridge.native.d.ts.map +1 -0
  270. package/lib/typescript/src/platform/native/NativePlatformBridge.d.ts +17 -0
  271. package/lib/typescript/src/platform/native/NativePlatformBridge.d.ts.map +1 -0
  272. package/lib/typescript/src/platform/native/NativeVersionCheck.d.ts +45 -0
  273. package/lib/typescript/src/platform/native/NativeVersionCheck.d.ts.map +1 -0
  274. package/lib/typescript/src/platform/web/WebPlatformBridge.d.ts +17 -0
  275. package/lib/typescript/src/platform/web/WebPlatformBridge.d.ts.map +1 -0
  276. package/lib/typescript/src/presentation/components/ForceUpdateScreen.d.ts +12 -0
  277. package/lib/typescript/src/presentation/components/ForceUpdateScreen.d.ts.map +1 -0
  278. package/lib/typescript/src/presentation/components/OptionalUpdateBanner.d.ts +12 -0
  279. package/lib/typescript/src/presentation/components/OptionalUpdateBanner.d.ts.map +1 -0
  280. package/lib/typescript/src/presentation/components/SoftUpdateDialog.d.ts +14 -0
  281. package/lib/typescript/src/presentation/components/SoftUpdateDialog.d.ts.map +1 -0
  282. package/lib/typescript/src/presentation/hooks/VersionManagerProvider.d.ts +9 -0
  283. package/lib/typescript/src/presentation/hooks/VersionManagerProvider.d.ts.map +1 -0
  284. package/lib/typescript/src/presentation/hooks/context.d.ts +3 -0
  285. package/lib/typescript/src/presentation/hooks/context.d.ts.map +1 -0
  286. package/lib/typescript/src/presentation/hooks/useUpdateState.d.ts +17 -0
  287. package/lib/typescript/src/presentation/hooks/useUpdateState.d.ts.map +1 -0
  288. package/lib/typescript/src/presentation/hooks/useVersionManager.d.ts +22 -0
  289. package/lib/typescript/src/presentation/hooks/useVersionManager.d.ts.map +1 -0
  290. package/lib/typescript/src/presentation/state/VersionManagerStore.d.ts +28 -0
  291. package/lib/typescript/src/presentation/state/VersionManagerStore.d.ts.map +1 -0
  292. package/lib/typescript/src/publicApi.d.ts +24 -0
  293. package/lib/typescript/src/publicApi.d.ts.map +1 -0
  294. package/lib/typescript/src/shared/eventbus/EventBus.d.ts +21 -0
  295. package/lib/typescript/src/shared/eventbus/EventBus.d.ts.map +1 -0
  296. package/lib/typescript/src/shared/logging/Logger.d.ts +17 -0
  297. package/lib/typescript/src/shared/logging/Logger.d.ts.map +1 -0
  298. package/lib/typescript/src/ui.d.ts +15 -0
  299. package/lib/typescript/src/ui.d.ts.map +1 -0
  300. package/package.json +192 -0
  301. package/src/data/cache/MemoryCacheStore.ts +36 -0
  302. package/src/data/cache/PersistentCacheStore.ts +63 -0
  303. package/src/data/config/ConfigCache.ts +30 -0
  304. package/src/data/config/ConfigDocumentValidator.ts +309 -0
  305. package/src/data/config/ConfigLoader.ts +105 -0
  306. package/src/data/config/ConfigProvider.ts +84 -0
  307. package/src/data/config/ConfigResolutionPipeline.ts +424 -0
  308. package/src/data/config/ConfigValidator.ts +79 -0
  309. package/src/data/config/SignatureVerifier.ts +90 -0
  310. package/src/data/config/canonicalize.ts +111 -0
  311. package/src/data/config/sources/EnvironmentOverrideSource.ts +22 -0
  312. package/src/data/config/sources/LocalConfigSource.ts +24 -0
  313. package/src/data/config/sources/RemoteConfigSource.ts +41 -0
  314. package/src/data/providers/amazon/AmazonAppstoreProvider.ts +16 -0
  315. package/src/data/providers/apple/AppleStoreProvider.ts +94 -0
  316. package/src/data/providers/custom-api/CustomApiProvider.ts +75 -0
  317. package/src/data/providers/firebase-remote-config/FirebaseRemoteConfigProvider.ts +16 -0
  318. package/src/data/providers/google-play/GooglePlayProvider.ts +75 -0
  319. package/src/data/providers/huawei/HuaweiAppGalleryProvider.ts +21 -0
  320. package/src/data/repositories/VersionRepositoryImpl.ts +90 -0
  321. package/src/di/container.ts +128 -0
  322. package/src/domain/IVersionManagerCore.ts +54 -0
  323. package/src/domain/VersionManagerCore.ts +425 -0
  324. package/src/domain/engines/decision/DecisionEngine.ts +47 -0
  325. package/src/domain/engines/policy/IUpdatePolicyEngine.ts +18 -0
  326. package/src/domain/engines/policy/PolicyEngine.ts +60 -0
  327. package/src/domain/engines/semver/IVersionComparator.ts +7 -0
  328. package/src/domain/engines/semver/SemVerEngine.ts +200 -0
  329. package/src/domain/errors/VersionManagerException.ts +166 -0
  330. package/src/domain/models/ActionPlan.ts +17 -0
  331. package/src/domain/models/ConfigDocument.ts +97 -0
  332. package/src/domain/models/Events.ts +48 -0
  333. package/src/domain/models/LifecycleState.ts +50 -0
  334. package/src/domain/models/ParsedVersion.ts +8 -0
  335. package/src/domain/models/PlatformId.ts +9 -0
  336. package/src/domain/models/PublicApiOptions.ts +14 -0
  337. package/src/domain/models/RemoteVersionInfo.ts +23 -0
  338. package/src/domain/models/StoreLookup.ts +12 -0
  339. package/src/domain/models/Unsubscribe.ts +1 -0
  340. package/src/domain/models/UpdateInfo.ts +11 -0
  341. package/src/domain/models/VersionManagerOptions.ts +150 -0
  342. package/src/domain/ports/ICacheStore.ts +5 -0
  343. package/src/domain/ports/IClock.ts +3 -0
  344. package/src/domain/ports/IConfigProvider.ts +18 -0
  345. package/src/domain/ports/IConfigSources.ts +44 -0
  346. package/src/domain/ports/IPlatformBridge.ts +97 -0
  347. package/src/domain/ports/IStoreProvider.ts +12 -0
  348. package/src/domain/ports/IVersionRepository.ts +14 -0
  349. package/src/domain/statemachine/LifecycleStateMachine.ts +76 -0
  350. package/src/domain/usecases/CheckForUpdatesUseCase.ts +63 -0
  351. package/src/domain/usecases/ForceTriggerUpdateUseCase.ts +35 -0
  352. package/src/domain/usecases/ResetIgnoredVersionsUseCase.ts +26 -0
  353. package/src/index.tsx +84 -0
  354. package/src/platform/contracts/IPlatformBridge.ts +14 -0
  355. package/src/platform/createPlatformBridge.native.ts +7 -0
  356. package/src/platform/createPlatformBridge.ts +15 -0
  357. package/src/platform/native/NativePlatformBridge.ts +179 -0
  358. package/src/platform/native/NativeVersionCheck.ts +64 -0
  359. package/src/platform/web/WebPlatformBridge.ts +347 -0
  360. package/src/presentation/components/ForceUpdateScreen.tsx +64 -0
  361. package/src/presentation/components/OptionalUpdateBanner.tsx +53 -0
  362. package/src/presentation/components/SoftUpdateDialog.tsx +84 -0
  363. package/src/presentation/hooks/VersionManagerProvider.tsx +23 -0
  364. package/src/presentation/hooks/context.ts +6 -0
  365. package/src/presentation/hooks/useUpdateState.ts +50 -0
  366. package/src/presentation/hooks/useVersionManager.ts +68 -0
  367. package/src/presentation/state/VersionManagerStore.ts +72 -0
  368. package/src/publicApi.ts +126 -0
  369. package/src/shared/eventbus/EventBus.ts +56 -0
  370. package/src/shared/logging/Logger.ts +70 -0
  371. package/src/ui.tsx +19 -0
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+
3
+ import { parseVersion } from "../../domain/engines/semver/SemVerEngine.js";
4
+ import { InvalidConfigException } from "../../domain/errors/VersionManagerException.js";
5
+ /**
6
+ * Boundary validation (Prompt 3 §2.2) for the "default fallback" config tier — the
7
+ * VersionManagerOptions object passed to configure(). Full JSON-Schema structural
8
+ * validation and signature verification for local/remote config documents (Prompt 3
9
+ * §2.1, §3) are scoped to the not-yet-built config-document pipeline; see
10
+ * docs/architecture/03-configuration-system.md.
11
+ */
12
+ export function validateOptions(options) {
13
+ if (!options.stores || Object.keys(options.stores).length === 0) {
14
+ throw new InvalidConfigException({
15
+ message: 'VersionManagerOptions.stores must configure at least one store (ios/android/huawei/amazon/custom)'
16
+ });
17
+ }
18
+ if (options.appVersion !== undefined) {
19
+ try {
20
+ parseVersion(options.appVersion);
21
+ } catch (error) {
22
+ throw new InvalidConfigException({
23
+ message: `options.appVersion "${options.appVersion}" is not a valid SemVer string`,
24
+ cause: error
25
+ });
26
+ }
27
+ }
28
+ if (options.policy?.forceUpdateBelow !== undefined) {
29
+ try {
30
+ parseVersion(options.policy.forceUpdateBelow);
31
+ } catch (error) {
32
+ throw new InvalidConfigException({
33
+ message: `options.policy.forceUpdateBelow "${options.policy.forceUpdateBelow}" is not a valid SemVer string`,
34
+ cause: error
35
+ });
36
+ }
37
+ }
38
+ const timeoutMs = options.fallback?.requestTimeoutMs;
39
+ if (timeoutMs !== undefined && timeoutMs <= 0) {
40
+ throw new InvalidConfigException({
41
+ message: 'options.fallback.requestTimeoutMs must be greater than 0'
42
+ });
43
+ }
44
+ const ttlMs = options.cache?.ttlMs;
45
+ if (ttlMs !== undefined && ttlMs < 0) {
46
+ throw new InvalidConfigException({
47
+ message: 'options.cache.ttlMs must be >= 0'
48
+ });
49
+ }
50
+ const maxAttempts = options.fallback?.retry?.maxAttempts;
51
+ if (maxAttempts !== undefined && (maxAttempts < 0 || maxAttempts > 10)) {
52
+ throw new InvalidConfigException({
53
+ message: 'options.fallback.retry.maxAttempts must be between 0 and 10'
54
+ });
55
+ }
56
+ const baseDelayMs = options.fallback?.retry?.baseDelayMs;
57
+ if (baseDelayMs !== undefined && baseDelayMs <= 0) {
58
+ throw new InvalidConfigException({
59
+ message: 'options.fallback.retry.baseDelayMs must be greater than 0'
60
+ });
61
+ }
62
+ const rolloutPercentage = options.policy?.rolloutPercentage;
63
+ if (rolloutPercentage !== undefined && (rolloutPercentage < 0 || rolloutPercentage > 100)) {
64
+ throw new InvalidConfigException({
65
+ message: 'options.policy.rolloutPercentage must be between 0 and 100'
66
+ });
67
+ }
68
+ }
69
+ //# sourceMappingURL=ConfigValidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["parseVersion","InvalidConfigException","validateOptions","options","stores","Object","keys","length","message","appVersion","undefined","error","cause","policy","forceUpdateBelow","timeoutMs","fallback","requestTimeoutMs","ttlMs","cache","maxAttempts","retry","baseDelayMs","rolloutPercentage"],"sourceRoot":"../../../../src","sources":["data/config/ConfigValidator.ts"],"mappings":";;AAAA,SAASA,YAAY,QAAQ,6CAA0C;AACvE,SAASC,sBAAsB,QAAQ,gDAA6C;AAGpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAACC,OAA8B,EAAQ;EACpE,IAAI,CAACA,OAAO,CAACC,MAAM,IAAIC,MAAM,CAACC,IAAI,CAACH,OAAO,CAACC,MAAM,CAAC,CAACG,MAAM,KAAK,CAAC,EAAE;IAC/D,MAAM,IAAIN,sBAAsB,CAAC;MAC/BO,OAAO,EACL;IACJ,CAAC,CAAC;EACJ;EAEA,IAAIL,OAAO,CAACM,UAAU,KAAKC,SAAS,EAAE;IACpC,IAAI;MACFV,YAAY,CAACG,OAAO,CAACM,UAAU,CAAC;IAClC,CAAC,CAAC,OAAOE,KAAK,EAAE;MACd,MAAM,IAAIV,sBAAsB,CAAC;QAC/BO,OAAO,EAAE,uBAAuBL,OAAO,CAACM,UAAU,gCAAgC;QAClFG,KAAK,EAAED;MACT,CAAC,CAAC;IACJ;EACF;EAEA,IAAIR,OAAO,CAACU,MAAM,EAAEC,gBAAgB,KAAKJ,SAAS,EAAE;IAClD,IAAI;MACFV,YAAY,CAACG,OAAO,CAACU,MAAM,CAACC,gBAAgB,CAAC;IAC/C,CAAC,CAAC,OAAOH,KAAK,EAAE;MACd,MAAM,IAAIV,sBAAsB,CAAC;QAC/BO,OAAO,EAAE,oCAAoCL,OAAO,CAACU,MAAM,CAACC,gBAAgB,gCAAgC;QAC5GF,KAAK,EAAED;MACT,CAAC,CAAC;IACJ;EACF;EAEA,MAAMI,SAAS,GAAGZ,OAAO,CAACa,QAAQ,EAAEC,gBAAgB;EACpD,IAAIF,SAAS,KAAKL,SAAS,IAAIK,SAAS,IAAI,CAAC,EAAE;IAC7C,MAAM,IAAId,sBAAsB,CAAC;MAC/BO,OAAO,EAAE;IACX,CAAC,CAAC;EACJ;EAEA,MAAMU,KAAK,GAAGf,OAAO,CAACgB,KAAK,EAAED,KAAK;EAClC,IAAIA,KAAK,KAAKR,SAAS,IAAIQ,KAAK,GAAG,CAAC,EAAE;IACpC,MAAM,IAAIjB,sBAAsB,CAAC;MAC/BO,OAAO,EAAE;IACX,CAAC,CAAC;EACJ;EAEA,MAAMY,WAAW,GAAGjB,OAAO,CAACa,QAAQ,EAAEK,KAAK,EAAED,WAAW;EACxD,IAAIA,WAAW,KAAKV,SAAS,KAAKU,WAAW,GAAG,CAAC,IAAIA,WAAW,GAAG,EAAE,CAAC,EAAE;IACtE,MAAM,IAAInB,sBAAsB,CAAC;MAC/BO,OAAO,EAAE;IACX,CAAC,CAAC;EACJ;EAEA,MAAMc,WAAW,GAAGnB,OAAO,CAACa,QAAQ,EAAEK,KAAK,EAAEC,WAAW;EACxD,IAAIA,WAAW,KAAKZ,SAAS,IAAIY,WAAW,IAAI,CAAC,EAAE;IACjD,MAAM,IAAIrB,sBAAsB,CAAC;MAC/BO,OAAO,EAAE;IACX,CAAC,CAAC;EACJ;EAEA,MAAMe,iBAAiB,GAAGpB,OAAO,CAACU,MAAM,EAAEU,iBAAiB;EAC3D,IACEA,iBAAiB,KAAKb,SAAS,KAC9Ba,iBAAiB,GAAG,CAAC,IAAIA,iBAAiB,GAAG,GAAG,CAAC,EAClD;IACA,MAAM,IAAItB,sBAAsB,CAAC;MAC/BO,OAAO,EAAE;IACX,CAAC,CAAC;EACJ;AACF","ignoreList":[]}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+
3
+ import { canonicalize, utf8ToBase64 } from "./canonicalize.js";
4
+ function isDev() {
5
+ return typeof __DEV__ !== 'undefined' && __DEV__ === true;
6
+ }
7
+
8
+ /**
9
+ * Doc 03 §3.2/§3.4 — verification calls are implemented using OS-provided cryptography
10
+ * exclusively (iOS CryptoKit/Security.framework, Android java.security), reached through
11
+ * IPlatformBridge.crypto (ICryptoProvider) so this class never itself hand-rolls
12
+ * cryptographic primitives (Prompt 1 §9.3's zero-external-dependency constraint extends
13
+ * to "don't implement crypto in JS either" — only OS APIs are trusted for this).
14
+ */
15
+ export class SignatureVerifier {
16
+ constructor(crypto) {
17
+ this.crypto = crypto;
18
+ }
19
+ async verify(envelope, trustedKeys) {
20
+ const {
21
+ algorithm,
22
+ keyId,
23
+ value
24
+ } = envelope.signature;
25
+
26
+ // §3.1: algorithm "none" is permitted only for the local bundled document in
27
+ // development builds — rejected for any remote fetch and for release builds,
28
+ // enforced here regardless of what security.signatureAlgorithm claims (a
29
+ // compromised document cannot downgrade its own algorithm to "none" and be
30
+ // believed). The pipeline is responsible for only calling verify() with a "none"
31
+ // envelope on the local-dev path in the first place; this is a defense-in-depth
32
+ // second check.
33
+ if (algorithm === 'none') {
34
+ if (!isDev()) {
35
+ return {
36
+ valid: false,
37
+ reason: 'signature.algorithm "none" is rejected outside development builds'
38
+ };
39
+ }
40
+ return {
41
+ valid: true
42
+ };
43
+ }
44
+ if (trustedKeys.algorithm !== algorithm) {
45
+ return {
46
+ valid: false,
47
+ reason: `Envelope algorithm "${algorithm}" does not match configured security.signatureAlgorithm "${trustedKeys.algorithm}"`
48
+ };
49
+ }
50
+ if (!trustedKeys.keys.has(keyId)) {
51
+ return {
52
+ valid: false,
53
+ reason: `keyId "${keyId}" is not present in security.trustedKeyIds`
54
+ };
55
+ }
56
+ if (!this.crypto) {
57
+ return {
58
+ valid: false,
59
+ reason: 'No ICryptoProvider available on the active IPlatformBridge — cannot verify signatures on this target'
60
+ };
61
+ }
62
+ const canonicalPayload = canonicalize(envelope.payload);
63
+ const messageBase64 = utf8ToBase64(canonicalPayload);
64
+ try {
65
+ const valid = algorithm === 'ed25519' ? await this.crypto.verifyEd25519(keyId, messageBase64, value) : await this.crypto.verifyHmacSha256(keyId, messageBase64, value);
66
+ return valid ? {
67
+ valid: true
68
+ } : {
69
+ valid: false,
70
+ reason: 'Signature mismatch'
71
+ };
72
+ } catch (error) {
73
+ return {
74
+ valid: false,
75
+ reason: `Native signature verification threw: ${String(error)}`
76
+ };
77
+ }
78
+ }
79
+ }
80
+ //# sourceMappingURL=SignatureVerifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["canonicalize","utf8ToBase64","isDev","__DEV__","SignatureVerifier","constructor","crypto","verify","envelope","trustedKeys","algorithm","keyId","value","signature","valid","reason","keys","has","canonicalPayload","payload","messageBase64","verifyEd25519","verifyHmacSha256","error","String"],"sourceRoot":"../../../../src","sources":["data/config/SignatureVerifier.ts"],"mappings":";;AAAA,SAASA,YAAY,EAAEC,YAAY,QAAQ,mBAAgB;AAW3D,SAASC,KAAKA,CAAA,EAAY;EACxB,OAAO,OAAOC,OAAO,KAAK,WAAW,IAAIA,OAAO,KAAK,IAAI;AAC3D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,iBAAiB,CAA+B;EAC3DC,WAAWA,CAAkBC,MAAwB,EAAE;IAAA,KAA1BA,MAAwB,GAAxBA,MAAwB;EAAG;EAExD,MAAMC,MAAMA,CACVC,QAA8B,EAC9BC,WAA0B,EACY;IACtC,MAAM;MAAEC,SAAS;MAAEC,KAAK;MAAEC;IAAM,CAAC,GAAGJ,QAAQ,CAACK,SAAS;;IAEtD;IACA;IACA;IACA;IACA;IACA;IACA;IACA,IAAIH,SAAS,KAAK,MAAM,EAAE;MACxB,IAAI,CAACR,KAAK,CAAC,CAAC,EAAE;QACZ,OAAO;UACLY,KAAK,EAAE,KAAK;UACZC,MAAM,EACJ;QACJ,CAAC;MACH;MACA,OAAO;QAAED,KAAK,EAAE;MAAK,CAAC;IACxB;IAEA,IAAIL,WAAW,CAACC,SAAS,KAAKA,SAAS,EAAE;MACvC,OAAO;QACLI,KAAK,EAAE,KAAK;QACZC,MAAM,EAAE,uBAAuBL,SAAS,4DAA4DD,WAAW,CAACC,SAAS;MAC3H,CAAC;IACH;IAEA,IAAI,CAACD,WAAW,CAACO,IAAI,CAACC,GAAG,CAACN,KAAK,CAAC,EAAE;MAChC,OAAO;QACLG,KAAK,EAAE,KAAK;QACZC,MAAM,EAAE,UAAUJ,KAAK;MACzB,CAAC;IACH;IAEA,IAAI,CAAC,IAAI,CAACL,MAAM,EAAE;MAChB,OAAO;QACLQ,KAAK,EAAE,KAAK;QACZC,MAAM,EACJ;MACJ,CAAC;IACH;IAEA,MAAMG,gBAAgB,GAAGlB,YAAY,CAACQ,QAAQ,CAACW,OAAO,CAAC;IACvD,MAAMC,aAAa,GAAGnB,YAAY,CAACiB,gBAAgB,CAAC;IAEpD,IAAI;MACF,MAAMJ,KAAK,GACTJ,SAAS,KAAK,SAAS,GACnB,MAAM,IAAI,CAACJ,MAAM,CAACe,aAAa,CAACV,KAAK,EAAES,aAAa,EAAER,KAAK,CAAC,GAC5D,MAAM,IAAI,CAACN,MAAM,CAACgB,gBAAgB,CAACX,KAAK,EAAES,aAAa,EAAER,KAAK,CAAC;MACrE,OAAOE,KAAK,GACR;QAAEA,KAAK,EAAE;MAAK,CAAC,GACf;QAAEA,KAAK,EAAE,KAAK;QAAEC,MAAM,EAAE;MAAqB,CAAC;IACpD,CAAC,CAAC,OAAOQ,KAAK,EAAE;MACd,OAAO;QACLT,KAAK,EAAE,KAAK;QACZC,MAAM,EAAE,wCAAwCS,MAAM,CAACD,KAAK,CAAC;MAC/D,CAAC;IACH;EACF;AACF","ignoreList":[]}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Hand-rolled canonicalizer (Prompt 1 §9.3 zero-dependency constraint), implementing the
5
+ * same principles as RFC 8785 (JSON Canonicalization Scheme) that doc 03 §3.3 calls for:
6
+ * recursive key sorting by UTF-16 code unit order, fixed number formatting, no
7
+ * insignificant whitespace. Signatures are computed/verified over this canonical byte
8
+ * form so that whitespace/key-order differences in transit never invalidate a
9
+ * legitimately signed document.
10
+ */
11
+
12
+ function canonicalizeValue(value) {
13
+ if (value === null) return 'null';
14
+ if (typeof value === 'boolean') return value ? 'true' : 'false';
15
+ if (typeof value === 'number') return canonicalizeNumber(value);
16
+ if (typeof value === 'string') return JSON.stringify(value);
17
+ if (Array.isArray(value)) {
18
+ return `[${value.map(canonicalizeValue).join(',')}]`;
19
+ }
20
+
21
+ // Recursive key sorting, UTF-16 code unit order (default JS string `<` comparison).
22
+ const keys = Object.keys(value).sort();
23
+ const members = keys.map(key => `${JSON.stringify(key)}:${canonicalizeValue(value[key])}`);
24
+ return `{${members.join(',')}}`;
25
+ }
26
+
27
+ /**
28
+ * Fixed number formatting per RFC 8785 §3.2.2.3 (simplified): integers render without a
29
+ * decimal point/exponent; this codebase's config schema (doc 03 §6) only ever contains
30
+ * integers and no fractional/exponential numeric fields, so the full ECMA-262
31
+ * Number::toString algorithm RFC 8785 mandates is unnecessary here.
32
+ */
33
+ function canonicalizeNumber(value) {
34
+ if (!Number.isFinite(value)) {
35
+ throw new Error('Cannot canonicalize a non-finite number');
36
+ }
37
+ if (Number.isInteger(value)) return String(value);
38
+ return String(value);
39
+ }
40
+
41
+ /** Canonical byte sequence (as a UTF-8 string) for the given JSON-compatible value. */
42
+ export function canonicalize(value) {
43
+ return canonicalizeValue(value);
44
+ }
45
+
46
+ /** Base64 encoding of the UTF-8 bytes of a string, without relying on Node's Buffer. */
47
+ export function utf8ToBase64(input) {
48
+ if (typeof btoa === 'function' && typeof TextEncoder !== 'undefined') {
49
+ const bytes = new TextEncoder().encode(input);
50
+ let binary = '';
51
+ for (let i = 0; i < bytes.length; i++) {
52
+ binary += String.fromCharCode(bytes[i]);
53
+ }
54
+ return btoa(binary);
55
+ }
56
+ // React Native's Hermes engine provides global Buffer via a polyfill in most RN
57
+ // setups, but not guaranteed — fall back to a minimal hand-rolled base64 encoder.
58
+ return manualUtf8ToBase64(input);
59
+ }
60
+ const BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
61
+ function manualUtf8ToBase64(input) {
62
+ const bytes = [];
63
+ for (let i = 0; i < input.length; i++) {
64
+ let code = input.codePointAt(i);
65
+ if (code > 0xffff) i++; // consumed a surrogate pair
66
+ if (code < 0x80) {
67
+ bytes.push(code);
68
+ } else if (code < 0x800) {
69
+ bytes.push(0xc0 | code >> 6, 0x80 | code & 0x3f);
70
+ } else if (code < 0x10000) {
71
+ bytes.push(0xe0 | code >> 12, 0x80 | code >> 6 & 0x3f, 0x80 | code & 0x3f);
72
+ } else {
73
+ bytes.push(0xf0 | code >> 18, 0x80 | code >> 12 & 0x3f, 0x80 | code >> 6 & 0x3f, 0x80 | code & 0x3f);
74
+ }
75
+ }
76
+ let output = '';
77
+ for (let i = 0; i < bytes.length; i += 3) {
78
+ const b0 = bytes[i];
79
+ const b1 = bytes[i + 1];
80
+ const b2 = bytes[i + 2];
81
+ output += BASE64_CHARS[b0 >> 2];
82
+ output += BASE64_CHARS[(b0 & 0x03) << 4 | (b1 ?? 0) >> 4];
83
+ output += b1 === undefined ? '=' : BASE64_CHARS[(b1 & 0x0f) << 2 | (b2 ?? 0) >> 6];
84
+ output += b2 === undefined ? '=' : BASE64_CHARS[b2 & 0x3f];
85
+ }
86
+ return output;
87
+ }
88
+ //# sourceMappingURL=canonicalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["canonicalizeValue","value","canonicalizeNumber","JSON","stringify","Array","isArray","map","join","keys","Object","sort","members","key","Number","isFinite","Error","isInteger","String","canonicalize","utf8ToBase64","input","btoa","TextEncoder","bytes","encode","binary","i","length","fromCharCode","manualUtf8ToBase64","BASE64_CHARS","code","codePointAt","push","output","b0","b1","b2","undefined"],"sourceRoot":"../../../../src","sources":["data/config/canonicalize.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Doc 03 §4 — "there is no OS process environment on a device"; this tier maps to
5
+ * build-time-injected constants and explicit runtime overrides, not `process.env` on a
6
+ * server. Build-time constants (Info.plist / BuildConfig fields) are app-specific and
7
+ * have no generic cross-platform read path from JS, so this implementation covers the
8
+ * "explicit configure({ configSources: { envOverrides } })" half of §4.1 tier 1 — the
9
+ * build-time-constant half is a per-app integration concern (documented, not a gap in
10
+ * this port's contract, which only promises "read whatever overrides are available").
11
+ */
12
+ export class EnvironmentOverrideSource {
13
+ constructor(overrides) {
14
+ this.overrides = overrides;
15
+ }
16
+ async read() {
17
+ return this.overrides ?? {};
18
+ }
19
+ }
20
+ //# sourceMappingURL=EnvironmentOverrideSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["EnvironmentOverrideSource","constructor","overrides","read"],"sourceRoot":"../../../../../src","sources":["data/config/sources/EnvironmentOverrideSource.ts"],"mappings":";;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,yBAAyB,CAAuC;EAC3EC,WAAWA,CACQC,SACkC,EACnD;IAAA,KAFiBA,SACkC,GADlCA,SACkC;EAClD;EAEH,MAAMC,IAAIA,CAAA,EAAmD;IAC3D,OAAO,IAAI,CAACD,SAAS,IAAI,CAAC,CAAC;EAC7B;AACF","ignoreList":[]}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Doc 03 §5.1 — the design calls for a native mmap reader (iOS Data(alwaysMapped),
5
+ * Android FileChannel.map) to avoid a double-copy when reading a bundled config asset.
6
+ * This implementation takes a documented, lower-risk equivalent instead: the host app
7
+ * imports its bundled config JSON via Metro/webpack's native JSON module support
8
+ * (`import localConfig from './vm-config.json'`) and passes the parsed envelope through
9
+ * `VersionManagerOptions.configSources.local`. Metro's JSON loader already avoids the
10
+ * page-cache -> native-heap -> JS-heap double copy for typical bundle sizes (the asset
11
+ * is compiled into the JS bundle itself), which satisfies §5.1's actual goal (avoid GC
12
+ * churn against the 5MB budget for a <=64KB document) without a dedicated native reader.
13
+ */
14
+ export class LocalConfigSource {
15
+ constructor(envelope) {
16
+ this.envelope = envelope;
17
+ }
18
+ async read() {
19
+ return this.envelope ?? null;
20
+ }
21
+ }
22
+ //# sourceMappingURL=LocalConfigSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["LocalConfigSource","constructor","envelope","read"],"sourceRoot":"../../../../../src","sources":["data/config/sources/LocalConfigSource.ts"],"mappings":";;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,iBAAiB,CAA+B;EAC3DC,WAAWA,CAAkBC,QAA0C,EAAE;IAAA,KAA5CA,QAA0C,GAA1CA,QAA0C;EAAG;EAE1E,MAAMC,IAAIA,CAAA,EAAsC;IAC9C,OAAO,IAAI,CAACD,QAAQ,IAAI,IAAI;EAC9B;AACF","ignoreList":[]}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ import { OfflineException, StoreResponseParseException } from "../../../domain/errors/VersionManagerException.js";
4
+ /** Doc 03 §4.3 — the remote-fetch tier, reached through the same IHttpClient port every other network call in this SDK uses. */
5
+ export class RemoteConfigSource {
6
+ constructor(http) {
7
+ this.http = http;
8
+ }
9
+ async fetch(url, options) {
10
+ const response = await this.http.request({
11
+ url,
12
+ method: 'GET',
13
+ headers: options.headers,
14
+ timeoutMs: options.timeoutMs
15
+ });
16
+ if (response.status !== 200) {
17
+ throw new OfflineException({
18
+ message: `Remote config fetch returned HTTP ${response.status}`,
19
+ metadata: {
20
+ url,
21
+ status: response.status
22
+ }
23
+ });
24
+ }
25
+ try {
26
+ return JSON.parse(response.body);
27
+ } catch (error) {
28
+ throw new StoreResponseParseException({
29
+ message: 'Remote config endpoint returned malformed JSON',
30
+ cause: error,
31
+ metadata: {
32
+ url
33
+ }
34
+ });
35
+ }
36
+ }
37
+ }
38
+ //# sourceMappingURL=RemoteConfigSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["OfflineException","StoreResponseParseException","RemoteConfigSource","constructor","http","fetch","url","options","response","request","method","headers","timeoutMs","status","message","metadata","JSON","parse","body","error","cause"],"sourceRoot":"../../../../../src","sources":["data/config/sources/RemoteConfigSource.ts"],"mappings":";;AAAA,SACEA,gBAAgB,EAChBC,2BAA2B,QACtB,mDAAgD;AAQvD;AACA,OAAO,MAAMC,kBAAkB,CAAgC;EAC7DC,WAAWA,CAAkBC,IAAiB,EAAE;IAAA,KAAnBA,IAAiB,GAAjBA,IAAiB;EAAG;EAEjD,MAAMC,KAAKA,CAACC,GAAW,EAAEC,OAAqB,EAA8B;IAC1E,MAAMC,QAAQ,GAAG,MAAM,IAAI,CAACJ,IAAI,CAACK,OAAO,CAAC;MACvCH,GAAG;MACHI,MAAM,EAAE,KAAK;MACbC,OAAO,EAAEJ,OAAO,CAACI,OAAO;MACxBC,SAAS,EAAEL,OAAO,CAACK;IACrB,CAAC,CAAC;IAEF,IAAIJ,QAAQ,CAACK,MAAM,KAAK,GAAG,EAAE;MAC3B,MAAM,IAAIb,gBAAgB,CAAC;QACzBc,OAAO,EAAE,qCAAqCN,QAAQ,CAACK,MAAM,EAAE;QAC/DE,QAAQ,EAAE;UAAET,GAAG;UAAEO,MAAM,EAAEL,QAAQ,CAACK;QAAO;MAC3C,CAAC,CAAC;IACJ;IAEA,IAAI;MACF,OAAOG,IAAI,CAACC,KAAK,CAACT,QAAQ,CAACU,IAAI,CAAC;IAClC,CAAC,CAAC,OAAOC,KAAK,EAAE;MACd,MAAM,IAAIlB,2BAA2B,CAAC;QACpCa,OAAO,EAAE,gDAAgD;QACzDM,KAAK,EAAED,KAAK;QACZJ,QAAQ,EAAE;UAAET;QAAI;MAClB,CAAC,CAAC;IACJ;EACF;AACF","ignoreList":[]}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ import { UnsupportedStoreException } from "../../../domain/errors/VersionManagerException.js";
4
+ /** Not yet implemented — see Prompt 11 in the design series. */
5
+ export class AmazonAppstoreProvider {
6
+ id = 'amazon';
7
+ async fetchLatestVersionInfo() {
8
+ throw new UnsupportedStoreException({
9
+ message: 'Amazon Appstore provider is not yet implemented — see Prompt 11 in the design series'
10
+ });
11
+ }
12
+ }
13
+ //# sourceMappingURL=AmazonAppstoreProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["UnsupportedStoreException","AmazonAppstoreProvider","id","fetchLatestVersionInfo","message"],"sourceRoot":"../../../../../src","sources":["data/providers/amazon/AmazonAppstoreProvider.ts"],"mappings":";;AAAA,SAASA,yBAAyB,QAAQ,mDAAgD;AAK1F;AACA,OAAO,MAAMC,sBAAsB,CAA2B;EACnDC,EAAE,GAAoB,QAAQ;EAEvC,MAAMC,sBAAsBA,CAAA,EAA+B;IACzD,MAAM,IAAIH,yBAAyB,CAAC;MAClCI,OAAO,EACL;IACJ,CAAC,CAAC;EACJ;AACF","ignoreList":[]}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+
3
+ import { AppNotFoundException, RateLimitException, StoreResponseParseException } from "../../../domain/errors/VersionManagerException.js";
4
+ /**
5
+ * Real implementation against the public iTunes Lookup API (Prompt 10). Accepts either
6
+ * the numeric App Store Connect id (`id=`) or, when the app developer doesn't want to
7
+ * hardcode one, falls back to looking the app up by its own bundle id (`bundleId=`) —
8
+ * the iTunes Lookup API supports both query params equivalently.
9
+ */
10
+ export class AppleStoreProvider {
11
+ id = 'apple';
12
+ constructor(http, appStoreId, region = 'us') {
13
+ this.http = http;
14
+ this.appStoreId = appStoreId;
15
+ this.region = region;
16
+ }
17
+ async fetchLatestVersionInfo(request) {
18
+ const country = request.region ?? this.region;
19
+ const identifierParam = this.appStoreId ? `id=${encodeURIComponent(this.appStoreId)}` : `bundleId=${encodeURIComponent(request.bundleId)}`;
20
+ const url = `https://itunes.apple.com/lookup?${identifierParam}&country=${encodeURIComponent(country)}`;
21
+ const response = await this.http.request({
22
+ url,
23
+ method: 'GET',
24
+ timeoutMs: request.timeoutMs
25
+ });
26
+ const identifier = this.appStoreId ?? request.bundleId;
27
+ if (response.status === 429) {
28
+ throw new RateLimitException({
29
+ message: 'Apple iTunes Lookup API rate limit exceeded (HTTP 429)'
30
+ });
31
+ }
32
+ if (response.status !== 200) {
33
+ throw new AppNotFoundException({
34
+ message: `Apple iTunes Lookup API returned HTTP ${response.status}`,
35
+ metadata: {
36
+ identifier,
37
+ status: response.status
38
+ }
39
+ });
40
+ }
41
+ let payload;
42
+ try {
43
+ payload = JSON.parse(response.body);
44
+ } catch (error) {
45
+ throw new StoreResponseParseException({
46
+ message: 'Apple iTunes Lookup API returned malformed JSON',
47
+ cause: error
48
+ });
49
+ }
50
+ const result = payload.results[0];
51
+ if (!result) {
52
+ throw new AppNotFoundException({
53
+ message: `No app found in the App Store for "${identifier}"`,
54
+ metadata: {
55
+ identifier
56
+ }
57
+ });
58
+ }
59
+ return {
60
+ latestVersion: result.version,
61
+ storeUrl: result.trackViewUrl,
62
+ releaseNotes: result.releaseNotes ?? null,
63
+ minimumOsVersion: result.minimumOsVersion ?? null
64
+ };
65
+ }
66
+ }
67
+ //# sourceMappingURL=AppleStoreProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["AppNotFoundException","RateLimitException","StoreResponseParseException","AppleStoreProvider","id","constructor","http","appStoreId","region","fetchLatestVersionInfo","request","country","identifierParam","encodeURIComponent","bundleId","url","response","method","timeoutMs","identifier","status","message","metadata","payload","JSON","parse","body","error","cause","result","results","latestVersion","version","storeUrl","trackViewUrl","releaseNotes","minimumOsVersion"],"sourceRoot":"../../../../../src","sources":["data/providers/apple/AppleStoreProvider.ts"],"mappings":";;AAAA,SACEA,oBAAoB,EACpBC,kBAAkB,EAClBC,2BAA2B,QACtB,mDAAgD;AAqBvD;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,kBAAkB,CAA2B;EAC/CC,EAAE,GAAoB,OAAO;EAEtCC,WAAWA,CACQC,IAAiB,EACjBC,UAAmB,EACnBC,MAAc,GAAG,IAAI,EACtC;IAAA,KAHiBF,IAAiB,GAAjBA,IAAiB;IAAA,KACjBC,UAAmB,GAAnBA,UAAmB;IAAA,KACnBC,MAAc,GAAdA,MAAc;EAC9B;EAEH,MAAMC,sBAAsBA,CAC1BC,OAA2B,EACC;IAC5B,MAAMC,OAAO,GAAGD,OAAO,CAACF,MAAM,IAAI,IAAI,CAACA,MAAM;IAC7C,MAAMI,eAAe,GAAG,IAAI,CAACL,UAAU,GACnC,MAAMM,kBAAkB,CAAC,IAAI,CAACN,UAAU,CAAC,EAAE,GAC3C,YAAYM,kBAAkB,CAACH,OAAO,CAACI,QAAQ,CAAC,EAAE;IACtD,MAAMC,GAAG,GAAG,mCAAmCH,eAAe,YAAYC,kBAAkB,CAACF,OAAO,CAAC,EAAE;IACvG,MAAMK,QAAQ,GAAG,MAAM,IAAI,CAACV,IAAI,CAACI,OAAO,CAAC;MACvCK,GAAG;MACHE,MAAM,EAAE,KAAK;MACbC,SAAS,EAAER,OAAO,CAACQ;IACrB,CAAC,CAAC;IAEF,MAAMC,UAAU,GAAG,IAAI,CAACZ,UAAU,IAAIG,OAAO,CAACI,QAAQ;IAEtD,IAAIE,QAAQ,CAACI,MAAM,KAAK,GAAG,EAAE;MAC3B,MAAM,IAAInB,kBAAkB,CAAC;QAC3BoB,OAAO,EAAE;MACX,CAAC,CAAC;IACJ;IACA,IAAIL,QAAQ,CAACI,MAAM,KAAK,GAAG,EAAE;MAC3B,MAAM,IAAIpB,oBAAoB,CAAC;QAC7BqB,OAAO,EAAE,yCAAyCL,QAAQ,CAACI,MAAM,EAAE;QACnEE,QAAQ,EAAE;UAAEH,UAAU;UAAEC,MAAM,EAAEJ,QAAQ,CAACI;QAAO;MAClD,CAAC,CAAC;IACJ;IAEA,IAAIG,OAA4B;IAChC,IAAI;MACFA,OAAO,GAAGC,IAAI,CAACC,KAAK,CAACT,QAAQ,CAACU,IAAI,CAAwB;IAC5D,CAAC,CAAC,OAAOC,KAAK,EAAE;MACd,MAAM,IAAIzB,2BAA2B,CAAC;QACpCmB,OAAO,EAAE,iDAAiD;QAC1DO,KAAK,EAAED;MACT,CAAC,CAAC;IACJ;IAEA,MAAME,MAAM,GAAGN,OAAO,CAACO,OAAO,CAAC,CAAC,CAAC;IACjC,IAAI,CAACD,MAAM,EAAE;MACX,MAAM,IAAI7B,oBAAoB,CAAC;QAC7BqB,OAAO,EAAE,sCAAsCF,UAAU,GAAG;QAC5DG,QAAQ,EAAE;UAAEH;QAAW;MACzB,CAAC,CAAC;IACJ;IAEA,OAAO;MACLY,aAAa,EAAEF,MAAM,CAACG,OAAO;MAC7BC,QAAQ,EAAEJ,MAAM,CAACK,YAAY;MAC7BC,YAAY,EAAEN,MAAM,CAACM,YAAY,IAAI,IAAI;MACzCC,gBAAgB,EAAEP,MAAM,CAACO,gBAAgB,IAAI;IAC/C,CAAC;EACH;AACF","ignoreList":[]}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+
3
+ import { StorePermissionException, StoreResponseParseException } from "../../../domain/errors/VersionManagerException.js";
4
+ /** Generic enterprise/private-distribution provider (Prompt 12). */
5
+ export class CustomApiProvider {
6
+ id = 'custom';
7
+ constructor(http, url, headers = {}) {
8
+ this.http = http;
9
+ this.url = url;
10
+ this.headers = headers;
11
+ }
12
+ async fetchLatestVersionInfo(request) {
13
+ const response = await this.http.request({
14
+ url: this.url,
15
+ method: 'GET',
16
+ headers: this.headers,
17
+ timeoutMs: request.timeoutMs
18
+ });
19
+ if (response.status === 401 || response.status === 403) {
20
+ throw new StorePermissionException({
21
+ message: `Custom API rejected the request (HTTP ${response.status})`
22
+ });
23
+ }
24
+ if (response.status !== 200) {
25
+ throw new StoreResponseParseException({
26
+ message: `Custom API returned HTTP ${response.status}`
27
+ });
28
+ }
29
+ let payload;
30
+ try {
31
+ payload = JSON.parse(response.body);
32
+ } catch (error) {
33
+ throw new StoreResponseParseException({
34
+ message: 'Custom API returned malformed JSON',
35
+ cause: error
36
+ });
37
+ }
38
+ if (!payload.latestVersion || !payload.storeUrl) {
39
+ throw new StoreResponseParseException({
40
+ message: 'Custom API response is missing required fields "latestVersion"/"storeUrl"'
41
+ });
42
+ }
43
+ return {
44
+ latestVersion: payload.latestVersion,
45
+ storeUrl: payload.storeUrl,
46
+ releaseNotes: payload.releaseNotes ?? null,
47
+ minimumOsVersion: payload.minimumOsVersion ?? null
48
+ };
49
+ }
50
+ }
51
+ //# sourceMappingURL=CustomApiProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["StorePermissionException","StoreResponseParseException","CustomApiProvider","id","constructor","http","url","headers","fetchLatestVersionInfo","request","response","method","timeoutMs","status","message","payload","JSON","parse","body","error","cause","latestVersion","storeUrl","releaseNotes","minimumOsVersion"],"sourceRoot":"../../../../../src","sources":["data/providers/custom-api/CustomApiProvider.ts"],"mappings":";;AAAA,SACEA,wBAAwB,EACxBC,2BAA2B,QACtB,mDAAgD;AAgBvD;AACA,OAAO,MAAMC,iBAAiB,CAA2B;EAC9CC,EAAE,GAAoB,QAAQ;EAEvCC,WAAWA,CACQC,IAAiB,EACjBC,GAAW,EACXC,OAAyC,GAAG,CAAC,CAAC,EAC/D;IAAA,KAHiBF,IAAiB,GAAjBA,IAAiB;IAAA,KACjBC,GAAW,GAAXA,GAAW;IAAA,KACXC,OAAyC,GAAzCA,OAAyC;EACzD;EAEH,MAAMC,sBAAsBA,CAC1BC,OAA2B,EACC;IAC5B,MAAMC,QAAQ,GAAG,MAAM,IAAI,CAACL,IAAI,CAACI,OAAO,CAAC;MACvCH,GAAG,EAAE,IAAI,CAACA,GAAG;MACbK,MAAM,EAAE,KAAK;MACbJ,OAAO,EAAE,IAAI,CAACA,OAAO;MACrBK,SAAS,EAAEH,OAAO,CAACG;IACrB,CAAC,CAAC;IAEF,IAAIF,QAAQ,CAACG,MAAM,KAAK,GAAG,IAAIH,QAAQ,CAACG,MAAM,KAAK,GAAG,EAAE;MACtD,MAAM,IAAIb,wBAAwB,CAAC;QACjCc,OAAO,EAAE,yCAAyCJ,QAAQ,CAACG,MAAM;MACnE,CAAC,CAAC;IACJ;IACA,IAAIH,QAAQ,CAACG,MAAM,KAAK,GAAG,EAAE;MAC3B,MAAM,IAAIZ,2BAA2B,CAAC;QACpCa,OAAO,EAAE,4BAA4BJ,QAAQ,CAACG,MAAM;MACtD,CAAC,CAAC;IACJ;IAEA,IAAIE,OAAiC;IACrC,IAAI;MACFA,OAAO,GAAGC,IAAI,CAACC,KAAK,CAACP,QAAQ,CAACQ,IAAI,CAA6B;IACjE,CAAC,CAAC,OAAOC,KAAK,EAAE;MACd,MAAM,IAAIlB,2BAA2B,CAAC;QACpCa,OAAO,EAAE,oCAAoC;QAC7CM,KAAK,EAAED;MACT,CAAC,CAAC;IACJ;IAEA,IAAI,CAACJ,OAAO,CAACM,aAAa,IAAI,CAACN,OAAO,CAACO,QAAQ,EAAE;MAC/C,MAAM,IAAIrB,2BAA2B,CAAC;QACpCa,OAAO,EACL;MACJ,CAAC,CAAC;IACJ;IAEA,OAAO;MACLO,aAAa,EAAEN,OAAO,CAACM,aAAa;MACpCC,QAAQ,EAAEP,OAAO,CAACO,QAAQ;MAC1BC,YAAY,EAAER,OAAO,CAACQ,YAAY,IAAI,IAAI;MAC1CC,gBAAgB,EAAET,OAAO,CAACS,gBAAgB,IAAI;IAChD,CAAC;EACH;AACF","ignoreList":[]}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ import { UnsupportedStoreException } from "../../../domain/errors/VersionManagerException.js";
4
+ /** Not yet implemented — see Prompt 13 in the design series. */
5
+ export class FirebaseRemoteConfigProvider {
6
+ id = 'firebase-remote-config';
7
+ async fetchLatestVersionInfo() {
8
+ throw new UnsupportedStoreException({
9
+ message: 'Firebase Remote Config provider is not yet implemented — see Prompt 13 in the design series'
10
+ });
11
+ }
12
+ }
13
+ //# sourceMappingURL=FirebaseRemoteConfigProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["UnsupportedStoreException","FirebaseRemoteConfigProvider","id","fetchLatestVersionInfo","message"],"sourceRoot":"../../../../../src","sources":["data/providers/firebase-remote-config/FirebaseRemoteConfigProvider.ts"],"mappings":";;AAAA,SAASA,yBAAyB,QAAQ,mDAAgD;AAK1F;AACA,OAAO,MAAMC,4BAA4B,CAA2B;EACzDC,EAAE,GAAoB,wBAAwB;EAEvD,MAAMC,sBAAsBA,CAAA,EAA+B;IACzD,MAAM,IAAIH,yBAAyB,CAAC;MAClCI,OAAO,EACL;IACJ,CAAC,CAAC;EACJ;AACF","ignoreList":[]}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ import { AppNotFoundException, StoreResponseParseException } from "../../../domain/errors/VersionManagerException.js";
4
+ /**
5
+ * Google Play has no public, unauthenticated lookup API (Prompt 10). This provider is a
6
+ * best-effort parser of the public store listing page's inline JSON blob. It is
7
+ * inherently fragile — Play Store markup can change without notice — and is offered as
8
+ * a pragmatic default; production deployments with a Google Play Developer API service
9
+ * account should prefer a IStoreProvider backed by that authenticated API instead.
10
+ *
11
+ * packageName is optional — on Android the app's own bundle id *is* its package name,
12
+ * so when it's not supplied explicitly this falls back to request.bundleId.
13
+ */
14
+ export class GooglePlayProvider {
15
+ id = 'google-play';
16
+ constructor(http, packageName) {
17
+ this.http = http;
18
+ this.packageName = packageName;
19
+ }
20
+ async fetchLatestVersionInfo(request) {
21
+ const packageName = this.packageName ?? request.bundleId;
22
+ const storeUrl = `https://play.google.com/store/apps/details?id=${encodeURIComponent(packageName)}&hl=en`;
23
+ const response = await this.http.request({
24
+ url: storeUrl,
25
+ method: 'GET',
26
+ timeoutMs: request.timeoutMs
27
+ });
28
+ if (response.status === 404) {
29
+ throw new AppNotFoundException({
30
+ message: `No app found on Google Play for package "${packageName}"`,
31
+ metadata: {
32
+ packageName
33
+ }
34
+ });
35
+ }
36
+ if (response.status !== 200) {
37
+ throw new StoreResponseParseException({
38
+ message: `Google Play returned HTTP ${response.status}`
39
+ });
40
+ }
41
+ const version = extractPlayStoreVersion(response.body);
42
+ if (!version) {
43
+ throw new StoreResponseParseException({
44
+ message: 'Could not extract a version string from the Google Play store page',
45
+ metadata: {
46
+ packageName
47
+ }
48
+ });
49
+ }
50
+ return {
51
+ latestVersion: version,
52
+ storeUrl: `https://play.google.com/store/apps/details?id=${packageName}`,
53
+ releaseNotes: null,
54
+ minimumOsVersion: null
55
+ };
56
+ }
57
+ }
58
+ function extractPlayStoreVersion(html) {
59
+ const match = /\[\[\["(\d+(?:\.\d+){1,3})"\]\]/.exec(html);
60
+ return match?.[1] ?? null;
61
+ }
62
+ //# sourceMappingURL=GooglePlayProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["AppNotFoundException","StoreResponseParseException","GooglePlayProvider","id","constructor","http","packageName","fetchLatestVersionInfo","request","bundleId","storeUrl","encodeURIComponent","response","url","method","timeoutMs","status","message","metadata","version","extractPlayStoreVersion","body","latestVersion","releaseNotes","minimumOsVersion","html","match","exec"],"sourceRoot":"../../../../../src","sources":["data/providers/google-play/GooglePlayProvider.ts"],"mappings":";;AAAA,SACEA,oBAAoB,EACpBC,2BAA2B,QACtB,mDAAgD;AASvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,kBAAkB,CAA2B;EAC/CC,EAAE,GAAoB,aAAa;EAE5CC,WAAWA,CACQC,IAAiB,EACjBC,WAAoB,EACrC;IAAA,KAFiBD,IAAiB,GAAjBA,IAAiB;IAAA,KACjBC,WAAoB,GAApBA,WAAoB;EACpC;EAEH,MAAMC,sBAAsBA,CAC1BC,OAA2B,EACC;IAC5B,MAAMF,WAAW,GAAG,IAAI,CAACA,WAAW,IAAIE,OAAO,CAACC,QAAQ;IACxD,MAAMC,QAAQ,GAAG,iDAAiDC,kBAAkB,CAACL,WAAW,CAAC,QAAQ;IACzG,MAAMM,QAAQ,GAAG,MAAM,IAAI,CAACP,IAAI,CAACG,OAAO,CAAC;MACvCK,GAAG,EAAEH,QAAQ;MACbI,MAAM,EAAE,KAAK;MACbC,SAAS,EAAEP,OAAO,CAACO;IACrB,CAAC,CAAC;IAEF,IAAIH,QAAQ,CAACI,MAAM,KAAK,GAAG,EAAE;MAC3B,MAAM,IAAIhB,oBAAoB,CAAC;QAC7BiB,OAAO,EAAE,4CAA4CX,WAAW,GAAG;QACnEY,QAAQ,EAAE;UAAEZ;QAAY;MAC1B,CAAC,CAAC;IACJ;IACA,IAAIM,QAAQ,CAACI,MAAM,KAAK,GAAG,EAAE;MAC3B,MAAM,IAAIf,2BAA2B,CAAC;QACpCgB,OAAO,EAAE,6BAA6BL,QAAQ,CAACI,MAAM;MACvD,CAAC,CAAC;IACJ;IAEA,MAAMG,OAAO,GAAGC,uBAAuB,CAACR,QAAQ,CAACS,IAAI,CAAC;IACtD,IAAI,CAACF,OAAO,EAAE;MACZ,MAAM,IAAIlB,2BAA2B,CAAC;QACpCgB,OAAO,EACL,oEAAoE;QACtEC,QAAQ,EAAE;UAAEZ;QAAY;MAC1B,CAAC,CAAC;IACJ;IAEA,OAAO;MACLgB,aAAa,EAAEH,OAAO;MACtBT,QAAQ,EAAE,iDAAiDJ,WAAW,EAAE;MACxEiB,YAAY,EAAE,IAAI;MAClBC,gBAAgB,EAAE;IACpB,CAAC;EACH;AACF;AAEA,SAASJ,uBAAuBA,CAACK,IAAY,EAAiB;EAC5D,MAAMC,KAAK,GAAG,iCAAiC,CAACC,IAAI,CAACF,IAAI,CAAC;EAC1D,OAAOC,KAAK,GAAG,CAAC,CAAC,IAAI,IAAI;AAC3B","ignoreList":[]}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ import { UnsupportedStoreException } from "../../../domain/errors/VersionManagerException.js";
4
+ /**
5
+ * Not yet implemented — Huawei AppGallery integration is designed in Prompt 11 of this
6
+ * series (AG Connect API parameters, error-code mapping) but not built in this pass.
7
+ * The file exists so the provider is independently importable/tree-shakeable
8
+ * (Prompt 1 §8) without pulling in Apple/Google/Custom code.
9
+ */
10
+ export class HuaweiAppGalleryProvider {
11
+ id = 'huawei';
12
+ async fetchLatestVersionInfo() {
13
+ throw new UnsupportedStoreException({
14
+ message: 'Huawei AppGallery provider is not yet implemented — see Prompt 11 in the design series'
15
+ });
16
+ }
17
+ }
18
+ //# sourceMappingURL=HuaweiAppGalleryProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["UnsupportedStoreException","HuaweiAppGalleryProvider","id","fetchLatestVersionInfo","message"],"sourceRoot":"../../../../../src","sources":["data/providers/huawei/HuaweiAppGalleryProvider.ts"],"mappings":";;AAAA,SAASA,yBAAyB,QAAQ,mDAAgD;AAK1F;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,wBAAwB,CAA2B;EACrDC,EAAE,GAAoB,QAAQ;EAEvC,MAAMC,sBAAsBA,CAAA,EAA+B;IACzD,MAAM,IAAIH,yBAAyB,CAAC;MAClCI,OAAO,EACL;IACJ,CAAC,CAAC;EACJ;AACF","ignoreList":[]}