@hot-updater/react-native 1.0.0-rc.17 → 1.0.0-rc.21

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 (240) hide show
  1. package/lib/commonjs/checkForUpdate.js +7 -9
  2. package/lib/commonjs/checkForUpdate.js.map +1 -1
  3. package/lib/commonjs/clientPlugin.js +7 -43
  4. package/lib/commonjs/clientPlugin.js.map +1 -1
  5. package/lib/commonjs/httpClient.js +7 -9
  6. package/lib/commonjs/httpClient.js.map +1 -1
  7. package/lib/commonjs/index.js +10 -0
  8. package/lib/commonjs/index.js.map +1 -1
  9. package/lib/commonjs/native.js +4 -4
  10. package/lib/commonjs/native.js.map +1 -1
  11. package/lib/commonjs/pluginHost.js +26 -190
  12. package/lib/commonjs/pluginHost.js.map +1 -1
  13. package/lib/commonjs/releaseCatalogCache.js +7 -59
  14. package/lib/commonjs/releaseCatalogCache.js.map +1 -1
  15. package/lib/commonjs/sdkVersion.js +1 -1
  16. package/lib/module/checkForUpdate.js +1 -3
  17. package/lib/module/checkForUpdate.js.map +1 -1
  18. package/lib/module/clientPlugin.js +1 -41
  19. package/lib/module/clientPlugin.js.map +1 -1
  20. package/lib/module/httpClient.js +1 -3
  21. package/lib/module/httpClient.js.map +1 -1
  22. package/lib/module/index.js +2 -0
  23. package/lib/module/index.js.map +1 -1
  24. package/lib/module/native.js +1 -1
  25. package/lib/module/native.js.map +1 -1
  26. package/lib/module/pluginHost.js +22 -187
  27. package/lib/module/pluginHost.js.map +1 -1
  28. package/lib/module/releaseCatalogCache.js +3 -54
  29. package/lib/module/releaseCatalogCache.js.map +1 -1
  30. package/lib/module/sdkVersion.js +1 -1
  31. package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -1
  32. package/lib/typescript/commonjs/clientPlugin.d.ts +1 -184
  33. package/lib/typescript/commonjs/clientPlugin.d.ts.map +1 -1
  34. package/lib/typescript/commonjs/httpClient.d.ts +1 -2
  35. package/lib/typescript/commonjs/httpClient.d.ts.map +1 -1
  36. package/lib/typescript/commonjs/index.d.ts +1 -0
  37. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  38. package/lib/typescript/commonjs/native.d.ts +1 -1
  39. package/lib/typescript/commonjs/native.d.ts.map +1 -1
  40. package/lib/typescript/commonjs/pluginHost.d.ts +3 -28
  41. package/lib/typescript/commonjs/pluginHost.d.ts.map +1 -1
  42. package/lib/typescript/commonjs/releaseCatalogCache.d.ts +1 -13
  43. package/lib/typescript/commonjs/releaseCatalogCache.d.ts.map +1 -1
  44. package/lib/typescript/commonjs/sdkVersion.d.ts +1 -1
  45. package/lib/typescript/commonjs/types.d.ts +1 -1
  46. package/lib/typescript/commonjs/types.d.ts.map +1 -1
  47. package/lib/typescript/commonjs/wrap.types.d.ts +2 -2
  48. package/lib/typescript/module/checkForUpdate.d.ts.map +1 -1
  49. package/lib/typescript/module/clientPlugin.d.ts +1 -184
  50. package/lib/typescript/module/clientPlugin.d.ts.map +1 -1
  51. package/lib/typescript/module/httpClient.d.ts +1 -2
  52. package/lib/typescript/module/httpClient.d.ts.map +1 -1
  53. package/lib/typescript/module/index.d.ts +1 -0
  54. package/lib/typescript/module/index.d.ts.map +1 -1
  55. package/lib/typescript/module/native.d.ts +1 -1
  56. package/lib/typescript/module/native.d.ts.map +1 -1
  57. package/lib/typescript/module/pluginHost.d.ts +3 -28
  58. package/lib/typescript/module/pluginHost.d.ts.map +1 -1
  59. package/lib/typescript/module/releaseCatalogCache.d.ts +1 -13
  60. package/lib/typescript/module/releaseCatalogCache.d.ts.map +1 -1
  61. package/lib/typescript/module/sdkVersion.d.ts +1 -1
  62. package/lib/typescript/module/types.d.ts +1 -1
  63. package/lib/typescript/module/types.d.ts.map +1 -1
  64. package/lib/typescript/module/wrap.types.d.ts +2 -2
  65. package/package.json +7 -16
  66. package/src/checkForUpdate.ts +4 -6
  67. package/src/clientPlugin.ts +17 -231
  68. package/src/httpClient.ts +4 -4
  69. package/src/index.ts +7 -0
  70. package/src/native.ts +1 -1
  71. package/src/pluginHost.ts +24 -241
  72. package/src/releaseCatalogCache.ts +7 -136
  73. package/src/sdkVersion.ts +1 -1
  74. package/src/types.ts +1 -1
  75. package/src/wrap.types.ts +2 -2
  76. package/android/src/test/java/com/hotupdater/BsdiffPatchTest.kt +0 -46
  77. package/android/src/test/java/com/hotupdater/BundleFileStorageServiceTest.kt +0 -2236
  78. package/android/src/test/java/com/hotupdater/HotUpdaterExceptionTest.kt +0 -220
  79. package/android/src/test/java/com/hotupdater/HotUpdaterImplTest.kt +0 -264
  80. package/android/src/test/java/com/hotupdater/HotUpdaterRecoveryStateTest.kt +0 -97
  81. package/android/src/test/java/com/hotupdater/InstallIdentityServiceTest.kt +0 -71
  82. package/android/src/test/java/com/hotupdater/KeyValueStorageServiceTest.kt +0 -106
  83. package/android/src/test/java/com/hotupdater/NativeConfigUtilsTest.kt +0 -20
  84. package/android/src/test/java/com/hotupdater/NoBackupContext.kt +0 -11
  85. package/android/src/test/java/com/hotupdater/OkHttpDownloadServiceTest.kt +0 -397
  86. package/android/src/test/java/com/hotupdater/PendingCrashRecoveryTest.kt +0 -44
  87. package/android/src/test/java/com/hotupdater/PreviousProcessExitTest.kt +0 -57
  88. package/android/src/test/java/com/hotupdater/RelativePathResolverTest.kt +0 -41
  89. package/android/src/test/java/com/hotupdater/ReleaseCatalogCacheServiceTest.kt +0 -118
  90. package/android/src/test/java/com/hotupdater/TarBrArchiveExtractorTest.kt +0 -206
  91. package/lib/commonjs/appReady.spec.js +0 -360
  92. package/lib/commonjs/appReady.spec.js.map +0 -1
  93. package/lib/commonjs/appReady.test-utils.js +0 -25
  94. package/lib/commonjs/appReady.test-utils.js.map +0 -1
  95. package/lib/commonjs/baseURL.js +0 -16
  96. package/lib/commonjs/baseURL.js.map +0 -1
  97. package/lib/commonjs/catalogCacheNative.spec.js +0 -31
  98. package/lib/commonjs/catalogCacheNative.spec.js.map +0 -1
  99. package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js +0 -936
  100. package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js.map +0 -1
  101. package/lib/commonjs/entryImportGraph.spec.js +0 -50
  102. package/lib/commonjs/entryImportGraph.spec.js.map +0 -1
  103. package/lib/commonjs/httpClient.spec.js +0 -171
  104. package/lib/commonjs/httpClient.spec.js.map +0 -1
  105. package/lib/commonjs/index.spec.js +0 -395
  106. package/lib/commonjs/index.spec.js.map +0 -1
  107. package/lib/commonjs/iosInterop.spec.js +0 -18
  108. package/lib/commonjs/iosInterop.spec.js.map +0 -1
  109. package/lib/commonjs/native.spec.js +0 -910
  110. package/lib/commonjs/native.spec.js.map +0 -1
  111. package/lib/commonjs/pluginHost.spec.js +0 -292
  112. package/lib/commonjs/pluginHost.spec.js.map +0 -1
  113. package/lib/commonjs/plugins/insights/eventId.js +0 -129
  114. package/lib/commonjs/plugins/insights/eventId.js.map +0 -1
  115. package/lib/commonjs/plugins/insights/eventId.spec.js +0 -47
  116. package/lib/commonjs/plugins/insights/eventId.spec.js.map +0 -1
  117. package/lib/commonjs/plugins/insights/index.js +0 -272
  118. package/lib/commonjs/plugins/insights/index.js.map +0 -1
  119. package/lib/commonjs/plugins/insights/insights.spec.js +0 -640
  120. package/lib/commonjs/plugins/insights/insights.spec.js.map +0 -1
  121. package/lib/commonjs/plugins/insights/sender.js +0 -128
  122. package/lib/commonjs/plugins/insights/sender.js.map +0 -1
  123. package/lib/commonjs/plugins/insights/sender.spec.js +0 -265
  124. package/lib/commonjs/plugins/insights/sender.spec.js.map +0 -1
  125. package/lib/commonjs/plugins/insights/state.js +0 -145
  126. package/lib/commonjs/plugins/insights/state.js.map +0 -1
  127. package/lib/commonjs/releaseCatalogCache.spec.js +0 -213
  128. package/lib/commonjs/releaseCatalogCache.spec.js.map +0 -1
  129. package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js +0 -64
  130. package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js.map +0 -1
  131. package/lib/commonjs/store.notification.spec.js +0 -84
  132. package/lib/commonjs/store.notification.spec.js.map +0 -1
  133. package/lib/commonjs/store.spec.js +0 -182
  134. package/lib/commonjs/store.spec.js.map +0 -1
  135. package/lib/commonjs/updateError.spec.js +0 -149
  136. package/lib/commonjs/updateError.spec.js.map +0 -1
  137. package/lib/commonjs/wrap.progress.spec.js +0 -195
  138. package/lib/commonjs/wrap.progress.spec.js.map +0 -1
  139. package/lib/commonjs/wrap.spec.js +0 -232
  140. package/lib/commonjs/wrap.spec.js.map +0 -1
  141. package/lib/module/appReady.spec.js +0 -359
  142. package/lib/module/appReady.spec.js.map +0 -1
  143. package/lib/module/appReady.test-utils.js +0 -19
  144. package/lib/module/appReady.test-utils.js.map +0 -1
  145. package/lib/module/baseURL.js +0 -11
  146. package/lib/module/baseURL.js.map +0 -1
  147. package/lib/module/catalogCacheNative.spec.js +0 -31
  148. package/lib/module/catalogCacheNative.spec.js.map +0 -1
  149. package/lib/module/checkForUpdate.releaseCatalog.spec.js +0 -935
  150. package/lib/module/checkForUpdate.releaseCatalog.spec.js.map +0 -1
  151. package/lib/module/entryImportGraph.spec.js +0 -50
  152. package/lib/module/entryImportGraph.spec.js.map +0 -1
  153. package/lib/module/httpClient.spec.js +0 -171
  154. package/lib/module/httpClient.spec.js.map +0 -1
  155. package/lib/module/index.spec.js +0 -394
  156. package/lib/module/index.spec.js.map +0 -1
  157. package/lib/module/iosInterop.spec.js +0 -18
  158. package/lib/module/iosInterop.spec.js.map +0 -1
  159. package/lib/module/native.spec.js +0 -909
  160. package/lib/module/native.spec.js.map +0 -1
  161. package/lib/module/pluginHost.spec.js +0 -291
  162. package/lib/module/pluginHost.spec.js.map +0 -1
  163. package/lib/module/plugins/insights/eventId.js +0 -122
  164. package/lib/module/plugins/insights/eventId.js.map +0 -1
  165. package/lib/module/plugins/insights/eventId.spec.js +0 -47
  166. package/lib/module/plugins/insights/eventId.spec.js.map +0 -1
  167. package/lib/module/plugins/insights/index.js +0 -268
  168. package/lib/module/plugins/insights/index.js.map +0 -1
  169. package/lib/module/plugins/insights/insights.spec.js +0 -639
  170. package/lib/module/plugins/insights/insights.spec.js.map +0 -1
  171. package/lib/module/plugins/insights/sender.js +0 -123
  172. package/lib/module/plugins/insights/sender.js.map +0 -1
  173. package/lib/module/plugins/insights/sender.spec.js +0 -265
  174. package/lib/module/plugins/insights/sender.spec.js.map +0 -1
  175. package/lib/module/plugins/insights/state.js +0 -139
  176. package/lib/module/plugins/insights/state.js.map +0 -1
  177. package/lib/module/releaseCatalogCache.spec.js +0 -213
  178. package/lib/module/releaseCatalogCache.spec.js.map +0 -1
  179. package/lib/module/releaseCatalogCacheNativeContract.spec.js +0 -64
  180. package/lib/module/releaseCatalogCacheNativeContract.spec.js.map +0 -1
  181. package/lib/module/store.notification.spec.js +0 -85
  182. package/lib/module/store.notification.spec.js.map +0 -1
  183. package/lib/module/store.spec.js +0 -181
  184. package/lib/module/store.spec.js.map +0 -1
  185. package/lib/module/updateError.spec.js +0 -149
  186. package/lib/module/updateError.spec.js.map +0 -1
  187. package/lib/module/wrap.progress.spec.js +0 -196
  188. package/lib/module/wrap.progress.spec.js.map +0 -1
  189. package/lib/module/wrap.spec.js +0 -233
  190. package/lib/module/wrap.spec.js.map +0 -1
  191. package/lib/typescript/commonjs/appReady.test-utils.d.ts +0 -9
  192. package/lib/typescript/commonjs/appReady.test-utils.d.ts.map +0 -1
  193. package/lib/typescript/commonjs/baseURL.d.ts +0 -4
  194. package/lib/typescript/commonjs/baseURL.d.ts.map +0 -1
  195. package/lib/typescript/commonjs/plugins/insights/eventId.d.ts +0 -18
  196. package/lib/typescript/commonjs/plugins/insights/eventId.d.ts.map +0 -1
  197. package/lib/typescript/commonjs/plugins/insights/index.d.ts +0 -40
  198. package/lib/typescript/commonjs/plugins/insights/index.d.ts.map +0 -1
  199. package/lib/typescript/commonjs/plugins/insights/sender.d.ts +0 -74
  200. package/lib/typescript/commonjs/plugins/insights/sender.d.ts.map +0 -1
  201. package/lib/typescript/commonjs/plugins/insights/state.d.ts +0 -46
  202. package/lib/typescript/commonjs/plugins/insights/state.d.ts.map +0 -1
  203. package/lib/typescript/module/appReady.test-utils.d.ts +0 -9
  204. package/lib/typescript/module/appReady.test-utils.d.ts.map +0 -1
  205. package/lib/typescript/module/baseURL.d.ts +0 -4
  206. package/lib/typescript/module/baseURL.d.ts.map +0 -1
  207. package/lib/typescript/module/plugins/insights/eventId.d.ts +0 -18
  208. package/lib/typescript/module/plugins/insights/eventId.d.ts.map +0 -1
  209. package/lib/typescript/module/plugins/insights/index.d.ts +0 -40
  210. package/lib/typescript/module/plugins/insights/index.d.ts.map +0 -1
  211. package/lib/typescript/module/plugins/insights/sender.d.ts +0 -74
  212. package/lib/typescript/module/plugins/insights/sender.d.ts.map +0 -1
  213. package/lib/typescript/module/plugins/insights/state.d.ts +0 -46
  214. package/lib/typescript/module/plugins/insights/state.d.ts.map +0 -1
  215. package/plugins/insights/package.json +0 -8
  216. package/src/appReady.spec.ts +0 -393
  217. package/src/appReady.test-utils.ts +0 -31
  218. package/src/baseURL.ts +0 -15
  219. package/src/catalogCacheNative.spec.ts +0 -63
  220. package/src/checkForUpdate.releaseCatalog.spec.ts +0 -966
  221. package/src/entryImportGraph.spec.ts +0 -65
  222. package/src/httpClient.spec.ts +0 -216
  223. package/src/index.spec.ts +0 -434
  224. package/src/iosInterop.spec.ts +0 -30
  225. package/src/native.spec.ts +0 -978
  226. package/src/pluginHost.spec.ts +0 -297
  227. package/src/plugins/insights/eventId.spec.ts +0 -60
  228. package/src/plugins/insights/eventId.ts +0 -171
  229. package/src/plugins/insights/index.ts +0 -367
  230. package/src/plugins/insights/insights.spec.ts +0 -732
  231. package/src/plugins/insights/sender.spec.ts +0 -287
  232. package/src/plugins/insights/sender.ts +0 -221
  233. package/src/plugins/insights/state.ts +0 -184
  234. package/src/releaseCatalogCache.spec.ts +0 -304
  235. package/src/releaseCatalogCacheNativeContract.spec.ts +0 -80
  236. package/src/store.notification.spec.ts +0 -102
  237. package/src/store.spec.ts +0 -215
  238. package/src/updateError.spec.ts +0 -144
  239. package/src/wrap.progress.spec.ts +0 -232
  240. package/src/wrap.spec.ts +0 -262
package/src/index.spec.ts DELETED
@@ -1,434 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
-
3
- import type { HotUpdaterInitOptions, HotUpdaterOptions } from "./wrap";
4
-
5
- const mocks = vi.hoisted(() => {
6
- (
7
- globalThis as typeof globalThis & {
8
- HotUpdater: { SDK_VERSION: string };
9
- }
10
- ).HotUpdater = { SDK_VERSION: "test-sdk-version" };
11
-
12
- return {
13
- addListener: vi.fn(() => () => {}),
14
- checkForUpdate: vi.fn(async () => null),
15
- clearCrashHistory: vi.fn(() => true),
16
- createHttpClient: vi.fn((baseURL: unknown) => ({ baseURL })),
17
- getActiveUpdateState: vi.fn(() => ({
18
- activeSelection: null,
19
- highestSeenCatalogs: {},
20
- stableSelection: null,
21
- verificationPending: false,
22
- })),
23
- getAppVersion: vi.fn(() => "1.0.0"),
24
- getBaseURL: vi.fn(() => null),
25
- getUpdateId: vi.fn(() => "release-id"),
26
- getChannel: vi.fn(() => "production"),
27
- getCohort: vi.fn(() => "123"),
28
- getCrashHistory: vi.fn(() => []),
29
- getDefaultChannel: vi.fn(() => "production"),
30
- getFingerprintHash: vi.fn(() => null),
31
- getInstallId: vi.fn(() => "install-id"),
32
- getManifest: vi.fn(() => null),
33
- getMinBundleId: vi.fn(() => "min-bundle-id"),
34
- configurePlugins: vi.fn(),
35
- emitAfterAppReady: vi.fn(),
36
- reportUpdateError: vi.fn(),
37
- init: vi.fn(),
38
- isChannelSwitched: vi.fn(() => false),
39
- notifyAppReady: vi.fn(() => ({ status: "UNCHANGED" as const })),
40
- reload: vi.fn(),
41
- resetChannel: vi.fn(),
42
- setCohort: vi.fn(),
43
- setReloadBehavior: vi.fn(),
44
- stageBundle: vi.fn(),
45
- wrap: vi.fn((Component: unknown) => Component),
46
- };
47
- });
48
-
49
- vi.mock("react-native", () => ({ Platform: { OS: "ios" } }));
50
-
51
- vi.mock("./httpClient", () => ({
52
- createHttpClient: mocks.createHttpClient,
53
- }));
54
-
55
- vi.mock("./checkForUpdate", () => ({
56
- checkForUpdate: mocks.checkForUpdate,
57
- reportUpdateError: mocks.reportUpdateError,
58
- }));
59
-
60
- vi.mock("./pluginHost", () => ({
61
- configurePlugins: mocks.configurePlugins,
62
- }));
63
-
64
- vi.mock("./appReady", () => ({
65
- emitAfterAppReady: mocks.emitAfterAppReady,
66
- }));
67
-
68
- vi.mock("./native", () => ({
69
- addListener: mocks.addListener,
70
- clearCrashHistory: mocks.clearCrashHistory,
71
- getPublicActiveUpdateState: mocks.getActiveUpdateState,
72
- getActiveUpdateState: mocks.getActiveUpdateState,
73
- getBundleId: () => "bundle-id",
74
- getAppVersion: mocks.getAppVersion,
75
- getBaseURL: mocks.getBaseURL,
76
- getUpdateId: mocks.getUpdateId,
77
- getChannel: mocks.getChannel,
78
- getCohort: mocks.getCohort,
79
- getCrashHistory: mocks.getCrashHistory,
80
- getDefaultChannel: mocks.getDefaultChannel,
81
- getFingerprintHash: mocks.getFingerprintHash,
82
- getInstallId: mocks.getInstallId,
83
- getManifest: mocks.getManifest,
84
- getMinBundleId: mocks.getMinBundleId,
85
- isChannelSwitched: mocks.isChannelSwitched,
86
- notifyAppReady: mocks.notifyAppReady,
87
- reload: mocks.reload,
88
- resetChannel: mocks.resetChannel,
89
- setCohort: mocks.setCohort,
90
- setReloadBehavior: mocks.setReloadBehavior,
91
- stageBundle: mocks.stageBundle,
92
- }));
93
-
94
- vi.mock("./wrap", () => ({
95
- init: mocks.init,
96
- wrap: mocks.wrap,
97
- }));
98
-
99
- const importHotUpdater = async () => (await import("./index")).HotUpdater;
100
-
101
- describe("HotUpdater client initialization", () => {
102
- beforeEach(() => {
103
- vi.resetModules();
104
- vi.clearAllMocks();
105
- mocks.createHttpClient.mockImplementation((baseURL: unknown) => ({
106
- baseURL,
107
- }));
108
- mocks.checkForUpdate.mockResolvedValue(null);
109
- mocks.wrap.mockImplementation((Component: unknown) => Component);
110
- });
111
-
112
- afterEach(() => {
113
- vi.unstubAllGlobals();
114
- vi.restoreAllMocks();
115
- });
116
-
117
- it("exposes the console ID through the existing getter only", async () => {
118
- const HotUpdater = await importHotUpdater();
119
-
120
- expect(HotUpdater.getBundleId()).toBe("release-id");
121
- expect(HotUpdater).not.toHaveProperty("getReleaseId");
122
- expect(HotUpdater).not.toHaveProperty("getUpdateId");
123
- });
124
-
125
- it("initializes a private HTTP client from the required baseURL", async () => {
126
- const client = { createSession: vi.fn() };
127
- mocks.createHttpClient.mockReturnValue(client as never);
128
- const HotUpdater = await importHotUpdater();
129
-
130
- HotUpdater.init({
131
- baseURL: "https://updates.example.com",
132
- requestHeaders: { Authorization: "Bearer token" },
133
- requestTimeout: 1000,
134
- });
135
-
136
- expect(mocks.createHttpClient).toHaveBeenCalledWith(
137
- "https://updates.example.com",
138
- );
139
- expect(mocks.init).toHaveBeenCalledWith({
140
- client,
141
- requestHeaders: { Authorization: "Bearer token" },
142
- requestTimeout: 1000,
143
- });
144
- });
145
-
146
- it("accepts a functional baseURL without resolving it during init", async () => {
147
- const resolveBaseURL = vi.fn(() => "https://updates.example.com");
148
- const HotUpdater = await importHotUpdater();
149
-
150
- HotUpdater.init({ baseURL: resolveBaseURL });
151
-
152
- expect(mocks.createHttpClient).toHaveBeenCalledWith(resolveBaseURL);
153
- expect(resolveBaseURL).not.toHaveBeenCalled();
154
- });
155
-
156
- it("sets up plugins with the settings they fetch with, before init reads the launch", async () => {
157
- const plugin = { id: "example", setup: vi.fn() };
158
- const onError = vi.fn();
159
- mocks.init.mockImplementationOnce(() => {
160
- expect(mocks.configurePlugins).toHaveBeenCalledOnce();
161
- });
162
- const HotUpdater = await importHotUpdater();
163
-
164
- HotUpdater.init({
165
- baseURL: "https://updates.example.com",
166
- onError,
167
- plugins: [plugin],
168
- requestHeaders: { "x-api-key": "client-key" },
169
- requestTimeout: 1000,
170
- });
171
- HotUpdater.wrap({
172
- baseURL: "https://other.example.com",
173
- plugins: [plugin],
174
- updateStrategy: "appVersion",
175
- });
176
-
177
- expect(mocks.configurePlugins).toHaveBeenNthCalledWith(1, [plugin], {
178
- baseURL: "https://updates.example.com",
179
- onError,
180
- requestHeaders: { "x-api-key": "client-key" },
181
- requestTimeout: 1000,
182
- });
183
- expect(mocks.configurePlugins).toHaveBeenNthCalledWith(2, [plugin], {
184
- baseURL: "https://other.example.com",
185
- onError: undefined,
186
- requestHeaders: undefined,
187
- requestTimeout: undefined,
188
- });
189
- expect(mocks.init).toHaveBeenCalledWith(
190
- expect.not.objectContaining({ plugins: expect.anything() }),
191
- );
192
- expect(mocks.wrap).toHaveBeenCalledWith(
193
- expect.not.objectContaining({ plugins: expect.anything() }),
194
- );
195
- });
196
-
197
- it("reports a staged manual download to plugins after the launch", async () => {
198
- mocks.stageBundle.mockResolvedValueOnce({
199
- delivery: "archive",
200
- patchFallback: true,
201
- });
202
- mocks.getActiveUpdateState.mockReturnValue({
203
- activeSelection: {
204
- bundleId: "next-bundle-id",
205
- channel: "production",
206
- kind: "BUNDLE",
207
- releaseId: "next-release-id",
208
- scopeKey: "v1:fingerprint:project:ios:cHJvZHVjdGlvbg:hash",
209
- },
210
- highestSeenCatalogs: {},
211
- stableSelection: null,
212
- verificationPending: true,
213
- } as never);
214
- const HotUpdater = await importHotUpdater();
215
- HotUpdater.init({ baseURL: "https://updates.example.com" });
216
-
217
- await HotUpdater.updateBundle({
218
- assets: {},
219
- bundleId: "next-bundle-id",
220
- manifestFileHash: "manifest-hash",
221
- manifestUrl: "https://updates.example.com/manifest.json",
222
- status: "UPDATE",
223
- });
224
-
225
- expect(mocks.emitAfterAppReady).toHaveBeenCalledOnce();
226
- const [name, createPayload] = mocks.emitAfterAppReady.mock.calls[0] as [
227
- string,
228
- () => unknown,
229
- ];
230
- expect(name).toBe("onBundleDownloaded");
231
- expect(createPayload()).toEqual({
232
- channel: "production",
233
- fromBundleId: "bundle-id",
234
- fromReleaseId: null,
235
- toBundleId: "next-bundle-id",
236
- toReleaseId: "next-release-id",
237
- updateStrategy: "fingerprint",
238
- delivery: "archive",
239
- patchFallback: true,
240
- });
241
- });
242
-
243
- it("reports a failed manual download to plugins and rethrows it", async () => {
244
- const error = Object.assign(new Error("hash mismatch"), {
245
- code: "SIGNATURE_VERIFICATION_FAILED",
246
- userInfo: { reason: "hash_mismatch", stage: "download" },
247
- });
248
- mocks.stageBundle.mockRejectedValueOnce(error);
249
- const HotUpdater = await importHotUpdater();
250
- HotUpdater.init({ baseURL: "https://updates.example.com" });
251
-
252
- await expect(
253
- HotUpdater.updateBundle({
254
- assets: {},
255
- bundleId: "next-bundle-id",
256
- channel: "beta",
257
- manifestFileHash: "manifest-hash",
258
- manifestUrl: "https://updates.example.com/manifest.json",
259
- selection: {
260
- releaseId: "next-release-id",
261
- scopeKey: "v1:app-version:project:ios:YmV0YQ",
262
- },
263
- status: "UPDATE",
264
- }),
265
- ).rejects.toBe(error);
266
-
267
- expect(mocks.reportUpdateError).toHaveBeenCalledWith(
268
- error,
269
- "download",
270
- undefined,
271
- {
272
- bundleId: "bundle-id",
273
- channel: "beta",
274
- targetBundleId: "next-bundle-id",
275
- targetReleaseId: "next-release-id",
276
- updateStrategy: "appVersion",
277
- },
278
- );
279
- expect(mocks.emitAfterAppReady).not.toHaveBeenCalled();
280
- });
281
-
282
- it("requires baseURL and rejects the removed resolver shape", async () => {
283
- const HotUpdater = await importHotUpdater();
284
-
285
- expect(() => HotUpdater.init({} as never)).toThrow(
286
- "baseURL must be provided",
287
- );
288
- expect(() => HotUpdater.init({ resolver: {} } as never)).toThrow(
289
- "baseURL must be provided",
290
- );
291
- expect(mocks.init).not.toHaveBeenCalled();
292
- });
293
-
294
- it("types init and wrap with baseURL but no resolver or catalogId", () => {
295
- const initOptions = {
296
- baseURL: "https://updates.example.com",
297
- } satisfies HotUpdaterInitOptions;
298
- const wrapOptions = {
299
- baseURL: async () => "https://updates.example.com",
300
- updateStrategy: "appVersion",
301
- } satisfies HotUpdaterOptions;
302
-
303
- const assertRemovedInputsStayRejected = () => {
304
- // @ts-expect-error baseURL is required
305
- const missingBaseURL: HotUpdaterInitOptions = {};
306
- // @ts-expect-error resolver is no longer a public input
307
- const customResolver: HotUpdaterInitOptions = { resolver: {} };
308
- const clientCatalog: HotUpdaterInitOptions = {
309
- // @ts-expect-error catalogId is internal protocol metadata
310
- catalogId: "project-a",
311
- baseURL: "https://updates.example.com",
312
- };
313
- void missingBaseURL;
314
- void customResolver;
315
- void clientCatalog;
316
- };
317
-
318
- expect(assertRemovedInputsStayRejected).toBeTypeOf("function");
319
- expect(initOptions.baseURL).toBe("https://updates.example.com");
320
- expect(wrapOptions.updateStrategy).toBe("appVersion");
321
- });
322
-
323
- it("merges settings into checks", async () => {
324
- const client = { createSession: vi.fn() };
325
- mocks.createHttpClient.mockReturnValue(client as never);
326
- const checkOnError = vi.fn();
327
- const HotUpdater = await importHotUpdater();
328
- HotUpdater.init({
329
- baseURL: "https://updates.example.com",
330
- requestHeaders: { Authorization: "Bearer token" },
331
- requestTimeout: 1000,
332
- });
333
-
334
- await HotUpdater.checkForUpdate({
335
- onError: checkOnError,
336
- requestHeaders: { "X-Runtime": "secondary" },
337
- updateStrategy: "appVersion",
338
- });
339
-
340
- expect(mocks.checkForUpdate).toHaveBeenCalledWith({
341
- client,
342
- onError: checkOnError,
343
- requestHeaders: {
344
- Authorization: "Bearer token",
345
- "X-Runtime": "secondary",
346
- },
347
- requestTimeout: 1000,
348
- updateStrategy: "appVersion",
349
- });
350
- });
351
-
352
- it("normalizes wrap with the same private client contract", async () => {
353
- const client = { createSession: vi.fn() };
354
- mocks.createHttpClient.mockReturnValue(client as never);
355
- const HotUpdater = await importHotUpdater();
356
-
357
- HotUpdater.wrap({
358
- baseURL: "https://updates.example.com",
359
- updateStrategy: "appVersion",
360
- });
361
-
362
- expect(mocks.wrap).toHaveBeenCalledWith({
363
- client,
364
- updateStrategy: "appVersion",
365
- });
366
- });
367
-
368
- it.each([
369
- ["init", "wrap"],
370
- ["wrap", "init"],
371
- ] as const)(
372
- "reports %s and %s mixed usage exactly once",
373
- async (first, second) => {
374
- const consoleError = vi
375
- .spyOn(console, "error")
376
- .mockImplementation(() => undefined);
377
- const HotUpdater = await importHotUpdater();
378
- const configure = (api: "init" | "wrap") => {
379
- if (api === "init") {
380
- HotUpdater.init({ baseURL: "https://updates.example.com" });
381
- return;
382
- }
383
- HotUpdater.wrap({
384
- baseURL: "https://updates.example.com",
385
- updateStrategy: "appVersion",
386
- });
387
- };
388
-
389
- configure(first);
390
- configure(second);
391
- configure(second);
392
-
393
- expect(consoleError).toHaveBeenCalledOnce();
394
- expect(consoleError).toHaveBeenCalledWith(
395
- expect.stringContaining(
396
- "HotUpdater.init() and HotUpdater.wrap() must not be used together",
397
- ),
398
- );
399
- expect(consoleError).toHaveBeenCalledWith(
400
- expect.stringContaining(
401
- "use HotUpdater.init() with HotUpdater.checkForUpdate()",
402
- ),
403
- );
404
- consoleError.mockRestore();
405
- },
406
- );
407
-
408
- it("rejects removed manual wrap options", async () => {
409
- const HotUpdater = await importHotUpdater();
410
-
411
- expect(() =>
412
- HotUpdater.wrap({
413
- baseURL: "https://updates.example.com",
414
- updateMode: "manual",
415
- } as never),
416
- ).toThrow('HotUpdater.wrap({ updateMode: "manual" }) was removed');
417
- });
418
-
419
- it("requires initialization before manual update APIs", async () => {
420
- const HotUpdater = await importHotUpdater();
421
-
422
- expect(() =>
423
- HotUpdater.checkForUpdate({ updateStrategy: "appVersion" }),
424
- ).toThrow("requires HotUpdater.wrap() or HotUpdater.init() to be used");
425
- });
426
-
427
- it("keeps the install id and leaves user identity to the insights plugin", async () => {
428
- const HotUpdater = await importHotUpdater();
429
-
430
- expect(HotUpdater.getInstallId()).toBe("install-id");
431
- expect(HotUpdater.getMinBundleId()).toBe("min-bundle-id");
432
- expect(HotUpdater).not.toHaveProperty("setUser");
433
- });
434
- });
@@ -1,30 +0,0 @@
1
- import { readFileSync } from "node:fs";
2
- import { resolve } from "node:path";
3
-
4
- import { describe, expect, it } from "vitest";
5
-
6
- const iosInternalDirectory = resolve(
7
- import.meta.dirname,
8
- "../ios/HotUpdater/Internal",
9
- );
10
-
11
- const readIOSSource = (filename: string) =>
12
- readFileSync(resolve(iosInternalDirectory, filename), "utf8");
13
-
14
- describe("iOS Objective-C interoperability", () => {
15
- it("does not call an autoreleased NSString through raw Swift ABI", () => {
16
- const implementation = readIOSSource("HotUpdaterImpl.swift");
17
- const objectiveCImplementation = readIOSSource("HotUpdater.mm");
18
-
19
- expect(implementation).not.toContain(
20
- '@_silgen_name("HotUpdaterGetMinBundleId")',
21
- );
22
- expect(implementation).toContain(
23
- '@_silgen_name("HotUpdaterCopyMinBundleId")',
24
- );
25
- expect(implementation).toContain(".takeRetainedValue() as String");
26
- expect(objectiveCImplementation).toContain(
27
- "return (__bridge_retained void *)HotUpdaterGetMinBundleId();",
28
- );
29
- });
30
- });