react-native-instantpay-code-push 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/InstantpayCodePush.podspec +20 -0
- package/LICENSE +20 -0
- package/README.md +158 -0
- package/android/build.gradle +91 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/instantpaycodepush/BundleFileStorageService.kt +835 -0
- package/android/src/main/java/com/instantpaycodepush/BundleMetadata.kt +249 -0
- package/android/src/main/java/com/instantpaycodepush/CommonHelper.kt +39 -0
- package/android/src/main/java/com/instantpaycodepush/DecompressService.kt +85 -0
- package/android/src/main/java/com/instantpaycodepush/DecompressionStrategy.kt +24 -0
- package/android/src/main/java/com/instantpaycodepush/FileManagerService.kt +105 -0
- package/android/src/main/java/com/instantpaycodepush/HashUtils.kt +50 -0
- package/android/src/main/java/com/instantpaycodepush/InstantpayCodePushModule.kt +182 -0
- package/android/src/main/java/com/instantpaycodepush/InstantpayCodePushPackage.kt +33 -0
- package/android/src/main/java/com/instantpaycodepush/IpayCodePush.kt +101 -0
- package/android/src/main/java/com/instantpaycodepush/IpayCodePushException.kt +135 -0
- package/android/src/main/java/com/instantpaycodepush/IpayCodePushImpl.kt +329 -0
- package/android/src/main/java/com/instantpaycodepush/OkHttpDownloadService.kt +283 -0
- package/android/src/main/java/com/instantpaycodepush/ReactIntegrationManager.kt +141 -0
- package/android/src/main/java/com/instantpaycodepush/ReactIntegrationManagerBase.kt +35 -0
- package/android/src/main/java/com/instantpaycodepush/SignatureVerifier.kt +354 -0
- package/android/src/main/java/com/instantpaycodepush/VersionedPreferencesService.kt +70 -0
- package/android/src/main/java/com/instantpaycodepush/ZipDecompressionStrategy.kt +198 -0
- package/ios/InstantpayCodePush.h +5 -0
- package/ios/InstantpayCodePush.mm +21 -0
- package/lib/module/DefaultResolver.js +34 -0
- package/lib/module/DefaultResolver.js.map +1 -0
- package/lib/module/NativeInstantpayCodePush.js +5 -0
- package/lib/module/NativeInstantpayCodePush.js.map +1 -0
- package/lib/module/checkForUpdate.js +68 -0
- package/lib/module/checkForUpdate.js.map +1 -0
- package/lib/module/error.js +137 -0
- package/lib/module/error.js.map +1 -0
- package/lib/module/fetchUpdateInfo.js +36 -0
- package/lib/module/fetchUpdateInfo.js.map +1 -0
- package/lib/module/global.d.js +8 -0
- package/lib/module/global.d.js.map +1 -0
- package/lib/module/hooks/useEventCallback.js +13 -0
- package/lib/module/hooks/useEventCallback.js.map +1 -0
- package/lib/module/index.js +291 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/native.js +233 -0
- package/lib/module/native.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/store.js +53 -0
- package/lib/module/store.js.map +1 -0
- package/lib/module/types.js +62 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/wrap.js +171 -0
- package/lib/module/wrap.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/DefaultResolver.d.ts +10 -0
- package/lib/typescript/src/DefaultResolver.d.ts.map +1 -0
- package/lib/typescript/src/NativeInstantpayCodePush.d.ts +100 -0
- package/lib/typescript/src/NativeInstantpayCodePush.d.ts.map +1 -0
- package/lib/typescript/src/checkForUpdate.d.ts +29 -0
- package/lib/typescript/src/checkForUpdate.d.ts.map +1 -0
- package/lib/typescript/src/error.d.ts +124 -0
- package/lib/typescript/src/error.d.ts.map +1 -0
- package/lib/typescript/src/fetchUpdateInfo.d.ts +8 -0
- package/lib/typescript/src/fetchUpdateInfo.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useEventCallback.d.ts +5 -0
- package/lib/typescript/src/hooks/useEventCallback.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +203 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/native.d.ts +128 -0
- package/lib/typescript/src/native.d.ts.map +1 -0
- package/lib/typescript/src/store.d.ts +11 -0
- package/lib/typescript/src/store.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +174 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/lib/typescript/src/wrap.d.ts +179 -0
- package/lib/typescript/src/wrap.d.ts.map +1 -0
- package/package.json +174 -0
- package/src/DefaultResolver.ts +36 -0
- package/src/NativeInstantpayCodePush.ts +111 -0
- package/src/checkForUpdate.ts +122 -0
- package/src/error.ts +159 -0
- package/src/fetchUpdateInfo.ts +47 -0
- package/src/global.d.ts +23 -0
- package/src/hooks/useEventCallback.ts +30 -0
- package/src/index.tsx +379 -0
- package/src/native.ts +280 -0
- package/src/store.ts +69 -0
- package/src/types.ts +227 -0
- package/src/wrap.tsx +384 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { checkForUpdate } from "./checkForUpdate.js";
|
|
4
|
+
import { createDefaultResolver } from "./DefaultResolver.js";
|
|
5
|
+
import { addListener, clearCrashHistory, getAppVersion, getBaseURL, getBundleId, getChannel, getCrashHistory, getFingerprintHash, getMinBundleId, reload, updateBundle } from "./native.js";
|
|
6
|
+
import { ipayCodePushStore } from "./store.js";
|
|
7
|
+
import { wrap } from "./wrap.js";
|
|
8
|
+
export * from "./store.js";
|
|
9
|
+
export { extractSignatureFailure, isSignatureVerificationError } from "./types.js";
|
|
10
|
+
addListener("onProgress", ({
|
|
11
|
+
progress
|
|
12
|
+
}) => {
|
|
13
|
+
ipayCodePushStore.setState({
|
|
14
|
+
progress
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Register getBaseURL to global objects for use without imports.
|
|
20
|
+
* This is needed for Expo DOM components and Babel plugin generated code.
|
|
21
|
+
*/
|
|
22
|
+
const registerGlobalGetBaseURL = () => {
|
|
23
|
+
const fn = getBaseURL;
|
|
24
|
+
|
|
25
|
+
// Register to globalThis (modern, cross-platform)
|
|
26
|
+
if (typeof globalThis !== "undefined") {
|
|
27
|
+
if (!globalThis.IpayCodePushGetBaseURL) {
|
|
28
|
+
globalThis.IpayCodePushGetBaseURL = fn;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Register to global (React Native, Node.js)
|
|
33
|
+
if (typeof global !== "undefined") {
|
|
34
|
+
if (!global.IpayCodePushGetBaseURL) {
|
|
35
|
+
global.IpayCodePushGetBaseURL = fn;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// Call registration immediately on module load
|
|
41
|
+
registerGlobalGetBaseURL();
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Creates a IpayCodePush client instance with all update management methods.
|
|
45
|
+
* This function is called once on module initialization to create a singleton instance.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
function createIpayCodePushClient() {
|
|
49
|
+
// Global configuration stored from wrap
|
|
50
|
+
const globalConfig = {
|
|
51
|
+
resolver: null
|
|
52
|
+
};
|
|
53
|
+
const ensureGlobalResolver = methodName => {
|
|
54
|
+
if (!globalConfig.resolver) {
|
|
55
|
+
throw new Error(`[IpayCodePush] ${methodName} requires IpayCodePush.wrap() to be used.\n\n` + `To fix this issue, wrap your root component with IpayCodePush.wrap():\n\n` + `Option 1: With automatic updates\n` + ` export default IpayCodePush.wrap({\n` + ` baseURL: "<your-update-server-url>",\n` + ` updateStrategy: "appVersion",\n` + ` updateMode: "auto"\n` + ` })(App);\n\n` + `Option 2: Manual updates only (custom flow)\n` + ` export default IpayCodePush.wrap({\n` + ` baseURL: "<your-update-server-url>",\n` + ` updateMode: "manual"\n` + ` })(App);\n\n`);
|
|
56
|
+
}
|
|
57
|
+
return globalConfig.resolver;
|
|
58
|
+
};
|
|
59
|
+
return {
|
|
60
|
+
/**
|
|
61
|
+
* `IpayCodePush.wrap` checks for updates at the entry point, and if there is a bundle to update, it downloads the bundle and applies the update strategy.
|
|
62
|
+
*
|
|
63
|
+
* @param {object} options - Configuration options
|
|
64
|
+
* @param {string} options.source - Update server URL
|
|
65
|
+
* @param {object} [options.requestHeaders] - Request headers
|
|
66
|
+
* @param {React.ComponentType} [options.fallbackComponent] - Component to display during updates
|
|
67
|
+
* @param {boolean} [options.reloadOnForceUpdate=true] - Whether to automatically reload the app on force updates
|
|
68
|
+
* @param {Function} [options.onUpdateProcessCompleted] - Callback after update process completes
|
|
69
|
+
* @param {Function} [options.onProgress] - Callback to track bundle download progress
|
|
70
|
+
* @returns {Function} Higher-order component that wraps the app component
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```tsx
|
|
74
|
+
* export default IpayCodePush.wrap({
|
|
75
|
+
* baseURL: "<your-update-server-url>",
|
|
76
|
+
* updateStrategy: "appVersion", //"appVersion" | "fingerprint"
|
|
77
|
+
* updateMode: "auto",
|
|
78
|
+
* requestHeaders: {
|
|
79
|
+
* "Authorization": "Bearer <your-access-token>",
|
|
80
|
+
* },
|
|
81
|
+
* })(App);
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
wrap: options => {
|
|
85
|
+
let normalizedOptions;
|
|
86
|
+
if ("baseURL" in options && options.baseURL) {
|
|
87
|
+
const {
|
|
88
|
+
baseURL,
|
|
89
|
+
...rest
|
|
90
|
+
} = options;
|
|
91
|
+
normalizedOptions = {
|
|
92
|
+
...rest,
|
|
93
|
+
resolver: createDefaultResolver(baseURL)
|
|
94
|
+
};
|
|
95
|
+
} else if ("resolver" in options && options.resolver) {
|
|
96
|
+
normalizedOptions = options;
|
|
97
|
+
} else {
|
|
98
|
+
throw new Error(`[IpayCodePush] Either baseURL or resolver must be provided.\n\n` + `Option 1: Using baseURL (recommended for most cases)\n` + ` export default IpayCodePush.wrap({\n` + ` baseURL: "<your-update-server-url>",\n` + ` updateStrategy: "appVersion",\n` + ` updateMode: "auto"\n` + ` })(App);\n\n` + `Option 2: Using custom resolver (advanced)\n` + ` export default IpayCodePush.wrap({\n` + ` resolver: {\n` + ` checkUpdate: async (params) => { /* custom logic */ },\n` + ` notifyAppReady: async (params) => { /* custom logic */ }\n` + ` },\n` + ` updateMode: "manual"\n` + ` })(App);\n\n`);
|
|
99
|
+
}
|
|
100
|
+
globalConfig.resolver = normalizedOptions.resolver;
|
|
101
|
+
globalConfig.requestHeaders = options.requestHeaders;
|
|
102
|
+
globalConfig.requestTimeout = options.requestTimeout;
|
|
103
|
+
return wrap(normalizedOptions);
|
|
104
|
+
},
|
|
105
|
+
/**
|
|
106
|
+
* Reloads the app.
|
|
107
|
+
*/
|
|
108
|
+
reload,
|
|
109
|
+
/**
|
|
110
|
+
* Returns whether an update has finished downloading in this app session.
|
|
111
|
+
*
|
|
112
|
+
* When it returns true, calling `IpayCodePush.reload()` (or restarting the app)
|
|
113
|
+
* will apply the downloaded update bundle.
|
|
114
|
+
*
|
|
115
|
+
* - Derived from `progress` reaching 1.0
|
|
116
|
+
* - Resets to false when a new download starts (progress < 1)
|
|
117
|
+
*
|
|
118
|
+
* @returns {boolean} True if a downloaded update is ready to apply
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* if (IpayCodePush.isUpdateDownloaded()) {
|
|
122
|
+
* await IpayCodePush.reload();
|
|
123
|
+
* }
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
isUpdateDownloaded: () => ipayCodePushStore.getSnapshot().isUpdateDownloaded,
|
|
127
|
+
/**
|
|
128
|
+
* Fetches the current app version.
|
|
129
|
+
*/
|
|
130
|
+
getAppVersion,
|
|
131
|
+
/**
|
|
132
|
+
* Fetches the current bundle ID of the app.
|
|
133
|
+
*/
|
|
134
|
+
getBundleId,
|
|
135
|
+
/**
|
|
136
|
+
* Retrieves the initial bundle ID based on the build time of the native app.
|
|
137
|
+
*/
|
|
138
|
+
getMinBundleId,
|
|
139
|
+
/**
|
|
140
|
+
* Fetches the current channel of the app.
|
|
141
|
+
*
|
|
142
|
+
* If no channel is specified, the app is assigned to the 'production' channel.
|
|
143
|
+
*
|
|
144
|
+
* @returns {string} The current release channel of the app
|
|
145
|
+
* @default "production"
|
|
146
|
+
* @example
|
|
147
|
+
* ```ts
|
|
148
|
+
* const channel = IpayCodePush.getChannel();
|
|
149
|
+
* console.log(`Current channel: ${channel}`);
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
getChannel,
|
|
153
|
+
/**
|
|
154
|
+
* Adds a listener to IpayCodePush events.
|
|
155
|
+
*
|
|
156
|
+
* @param {keyof IpayCodePushEvent} eventName - The name of the event to listen for
|
|
157
|
+
* @param {(event: IpayCodePushEvent[T]) => void} listener - The callback function to handle the event
|
|
158
|
+
* @returns {() => void} A cleanup function that removes the event listener
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```ts
|
|
162
|
+
* const unsubscribe = IpayCodePush.addListener("onProgress", ({ progress }) => {
|
|
163
|
+
* console.log(`Update progress: ${progress * 100}%`);
|
|
164
|
+
* });
|
|
165
|
+
*
|
|
166
|
+
* // Unsubscribe when no longer needed
|
|
167
|
+
* unsubscribe();
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
addListener,
|
|
171
|
+
/**
|
|
172
|
+
* Manually checks for updates.
|
|
173
|
+
*
|
|
174
|
+
* @param {Object} config - Update check configuration
|
|
175
|
+
* @param {string} config.source - Update server URL
|
|
176
|
+
* @param {Record<string, string>} [config.requestHeaders] - Request headers
|
|
177
|
+
*
|
|
178
|
+
* @returns {Promise<UpdateInfo | null>} Update information or null if up to date
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```ts
|
|
182
|
+
* const updateInfo = await IpayCodePush.checkForUpdate({
|
|
183
|
+
* source: "<your-update-server-url>",
|
|
184
|
+
* requestHeaders: {
|
|
185
|
+
* Authorization: "Bearer <your-access-token>",
|
|
186
|
+
* },
|
|
187
|
+
* });
|
|
188
|
+
*
|
|
189
|
+
* if (!updateInfo) {
|
|
190
|
+
* console.log("App is up to date");
|
|
191
|
+
* return;
|
|
192
|
+
* }
|
|
193
|
+
*
|
|
194
|
+
* await IpayCodePush.updateBundle(updateInfo.id, updateInfo.fileUrl);
|
|
195
|
+
* if (updateInfo.shouldForceUpdate) {
|
|
196
|
+
* await HotUpdater.reload();
|
|
197
|
+
* }
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
checkForUpdate: config => {
|
|
201
|
+
const resolver = ensureGlobalResolver("checkForUpdate");
|
|
202
|
+
const mergedConfig = {
|
|
203
|
+
...config,
|
|
204
|
+
resolver,
|
|
205
|
+
requestHeaders: {
|
|
206
|
+
...globalConfig.requestHeaders,
|
|
207
|
+
...config.requestHeaders
|
|
208
|
+
},
|
|
209
|
+
requestTimeout: config.requestTimeout ?? globalConfig.requestTimeout
|
|
210
|
+
};
|
|
211
|
+
return checkForUpdate(mergedConfig);
|
|
212
|
+
},
|
|
213
|
+
/**
|
|
214
|
+
* Updates the bundle of the app.
|
|
215
|
+
*
|
|
216
|
+
* @param {UpdateBundleParams} params - Parameters object required for bundle update
|
|
217
|
+
* @param {string} params.bundleId - The bundle ID of the app
|
|
218
|
+
* @param {string|null} params.fileUrl - The URL of the zip file
|
|
219
|
+
*
|
|
220
|
+
* @returns {Promise<boolean>} Whether the update was successful
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```ts
|
|
224
|
+
* const updateInfo = await IpayCodePush.checkForUpdate({
|
|
225
|
+
* source: "<your-update-server-url>",
|
|
226
|
+
* requestHeaders: {
|
|
227
|
+
* Authorization: "Bearer <your-access-token>",
|
|
228
|
+
* },
|
|
229
|
+
* });
|
|
230
|
+
*
|
|
231
|
+
* if (!updateInfo) {
|
|
232
|
+
* return {
|
|
233
|
+
* status: "UP_TO_DATE",
|
|
234
|
+
* };
|
|
235
|
+
* }
|
|
236
|
+
*
|
|
237
|
+
* await IpayCodePush.updateBundle({
|
|
238
|
+
* bundleId: updateInfo.id,
|
|
239
|
+
* fileUrl: updateInfo.fileUrl
|
|
240
|
+
* });
|
|
241
|
+
* if (updateInfo.shouldForceUpdate) {
|
|
242
|
+
* await HotUpdater.reload();
|
|
243
|
+
* }
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
updateBundle: params => {
|
|
247
|
+
ensureGlobalResolver("updateBundle");
|
|
248
|
+
return updateBundle(params);
|
|
249
|
+
},
|
|
250
|
+
/**
|
|
251
|
+
* Fetches the fingerprint of the app.
|
|
252
|
+
*
|
|
253
|
+
* @returns {string} The fingerprint of the app
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```ts
|
|
257
|
+
* const fingerprint = IpayCodePush.getFingerprintHash();
|
|
258
|
+
* console.log(`Fingerprint: ${fingerprint}`);
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
getFingerprintHash,
|
|
262
|
+
/**
|
|
263
|
+
* Gets the list of bundle IDs that have been marked as crashed.
|
|
264
|
+
* These bundles will be rejected if attempted to install again.
|
|
265
|
+
*
|
|
266
|
+
* @returns {string[]} Array of crashed bundle IDs
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```ts
|
|
270
|
+
* const crashedBundles = IpayCodePush.getCrashHistory();
|
|
271
|
+
* console.log("Crashed bundles:", crashedBundles);
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
274
|
+
getCrashHistory,
|
|
275
|
+
/**
|
|
276
|
+
* Clears the crashed bundle history, allowing previously crashed bundles
|
|
277
|
+
* to be installed again.
|
|
278
|
+
*
|
|
279
|
+
* @returns {boolean} true if clearing was successful
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* ```ts
|
|
283
|
+
* // Clear crash history to allow retrying a previously failed bundle
|
|
284
|
+
* IpayCodePush.clearCrashHistory();
|
|
285
|
+
* ```
|
|
286
|
+
*/
|
|
287
|
+
clearCrashHistory
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
export const IpayCodePush = createIpayCodePushClient();
|
|
291
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["checkForUpdate","createDefaultResolver","addListener","clearCrashHistory","getAppVersion","getBaseURL","getBundleId","getChannel","getCrashHistory","getFingerprintHash","getMinBundleId","reload","updateBundle","ipayCodePushStore","wrap","extractSignatureFailure","isSignatureVerificationError","progress","setState","registerGlobalGetBaseURL","fn","globalThis","IpayCodePushGetBaseURL","global","createIpayCodePushClient","globalConfig","resolver","ensureGlobalResolver","methodName","Error","options","normalizedOptions","baseURL","rest","requestHeaders","requestTimeout","isUpdateDownloaded","getSnapshot","config","mergedConfig","params","IpayCodePush"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACQH,UAAU;IAEV;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACQL,WAAW;IAEX;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACQF,cAAc,EAAGsC,MAA6B,IAAK;MAC/C,MAAMZ,QAAQ,GAAGC,oBAAoB,CAAC,gBAAgB,CAAC;MAEvD,MAAMY,YAA2C,GAAG;QAChD,GAAGD,MAAM;QACTZ,QAAQ;QACRQ,cAAc,EAAE;UAChB,GAAGT,YAAY,CAACS,cAAc;UAC9B,GAAGI,MAAM,CAACJ;QACV,CAAC;QACDC,cAAc,EAAEG,MAAM,CAACH,cAAc,IAAIV,YAAY,CAACU;MAC1D,CAAC;MAED,OAAOnC,cAAc,CAACuC,YAAY,CAAC;IACvC,CAAC;IAED;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACQ3B,YAAY,EAAG4B,MAAoB,IAAK;MACpCb,oBAAoB,CAAC,cAAc,CAAC;MACpC,OAAOf,YAAY,CAAC4B,MAAM,CAAC;IAC/B,CAAC;IAED;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACQ/B,kBAAkB;IAElB;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACQD,eAAe;IAEf;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACQL;EACJ,CAAC;AACL;AAEA,OAAO,MAAMsC,YAAY,GAAGjB,wBAAwB,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { NativeEventEmitter } from "react-native";
|
|
4
|
+
import { IpayCodePushErrorCode, isIpayCodePushError } from "./error.js";
|
|
5
|
+
import IpayCodePushNative from "./NativeInstantpayCodePush.js";
|
|
6
|
+
export { IpayCodePushErrorCode, isIpayCodePushError };
|
|
7
|
+
const NIL_UUID = "00000000-0000-0000-0000-000000000000";
|
|
8
|
+
const __IPAY_CODE_PUSH_BUNDLE_ID = undefined;
|
|
9
|
+
export const IpayCodePushConstants = {
|
|
10
|
+
IPAY_CODE_PUSH_BUNDLE_ID: __IPAY_CODE_PUSH_BUNDLE_ID || NIL_UUID
|
|
11
|
+
};
|
|
12
|
+
export const addListener = (eventName, listener //(event: IpayCodePushEvent[T])
|
|
13
|
+
) => {
|
|
14
|
+
const eventEmitter = new NativeEventEmitter(IpayCodePushNative);
|
|
15
|
+
const subscription = eventEmitter.addListener(eventName, listener);
|
|
16
|
+
return () => {
|
|
17
|
+
subscription.remove();
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
// In-flight update deduplication by bundleId (session-scoped).
|
|
21
|
+
const inflightUpdates = new Map();
|
|
22
|
+
|
|
23
|
+
// Tracks the last successfully installed bundleId for this session.
|
|
24
|
+
let lastInstalledBundleId = null;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Downloads files and applies them to the app.
|
|
28
|
+
*
|
|
29
|
+
* @param {UpdateParams} params - Parameters object required for bundle update
|
|
30
|
+
* @returns {Promise<boolean>} Resolves with true if download was successful
|
|
31
|
+
* @throws {Error} Rejects with error.code from HotUpdaterErrorCode enum and error.message
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @deprecated Use updateBundle(params: UpdateBundleParamsWithStatus) instead
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
export async function updateBundle(paramsOrBundleId, fileUrl) {
|
|
39
|
+
const updateBundleId = typeof paramsOrBundleId === "string" ? paramsOrBundleId : paramsOrBundleId.bundleId;
|
|
40
|
+
const status = typeof paramsOrBundleId === "string" ? "UPDATE" : paramsOrBundleId.status;
|
|
41
|
+
|
|
42
|
+
// If we have already installed this bundle in this session, skip re-download.
|
|
43
|
+
if (status === "UPDATE" && lastInstalledBundleId === updateBundleId) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
const currentBundleId = getBundleId();
|
|
47
|
+
|
|
48
|
+
// updateBundleId <= currentBundleId
|
|
49
|
+
if (status === "UPDATE" && updateBundleId.localeCompare(currentBundleId) <= 0) {
|
|
50
|
+
throw new Error("Update bundle id is the same as the current bundle id. Preventing infinite update loop.");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// In-flight guard: return the same promise if the same bundle is already updating.
|
|
54
|
+
const existing = inflightUpdates.get(updateBundleId);
|
|
55
|
+
if (existing) return existing;
|
|
56
|
+
const targetFileUrl = typeof paramsOrBundleId === "string" ? fileUrl ?? null : paramsOrBundleId.fileUrl;
|
|
57
|
+
const targetFileHash = typeof paramsOrBundleId === "string" ? undefined : paramsOrBundleId.fileHash;
|
|
58
|
+
const promise = (async () => {
|
|
59
|
+
try {
|
|
60
|
+
const ok = await IpayCodePushNative.updateBundle({
|
|
61
|
+
bundleId: updateBundleId,
|
|
62
|
+
fileUrl: targetFileUrl,
|
|
63
|
+
fileHash: targetFileHash ?? null
|
|
64
|
+
});
|
|
65
|
+
if (ok) {
|
|
66
|
+
lastInstalledBundleId = updateBundleId;
|
|
67
|
+
}
|
|
68
|
+
return ok;
|
|
69
|
+
} finally {
|
|
70
|
+
inflightUpdates.delete(updateBundleId);
|
|
71
|
+
}
|
|
72
|
+
})();
|
|
73
|
+
inflightUpdates.set(updateBundleId, promise);
|
|
74
|
+
return promise;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Fetches the current app version.
|
|
79
|
+
*/
|
|
80
|
+
export const getAppVersion = () => {
|
|
81
|
+
const constants = IpayCodePushNative.getConstants();
|
|
82
|
+
return constants?.APP_VERSION ?? null;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Reloads the app.
|
|
87
|
+
*/
|
|
88
|
+
export const reload = async () => {
|
|
89
|
+
await IpayCodePushNative.reload();
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Fetches the minimum bundle id, which represents the initial bundle of the app
|
|
94
|
+
* since it is created at build time.
|
|
95
|
+
*
|
|
96
|
+
* @returns {string} Resolves with the minimum bundle id or null if not available.
|
|
97
|
+
*/
|
|
98
|
+
export const getMinBundleId = () => {
|
|
99
|
+
const constants = IpayCodePushNative.getConstants();
|
|
100
|
+
return constants.MIN_BUNDLE_ID;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Fetches the current bundle version id.
|
|
105
|
+
*
|
|
106
|
+
* @async
|
|
107
|
+
* @returns {string} Resolves with the current version id or null if not available.
|
|
108
|
+
*/
|
|
109
|
+
export const getBundleId = () => {
|
|
110
|
+
return IpayCodePushConstants.IPAY_CODE_PUSH_BUNDLE_ID === NIL_UUID ? getMinBundleId() : IpayCodePushConstants.IPAY_CODE_PUSH_BUNDLE_ID;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Fetches the channel for the app.
|
|
115
|
+
*
|
|
116
|
+
* @returns {string} Resolves with the channel or null if not available.
|
|
117
|
+
*/
|
|
118
|
+
export const getChannel = () => {
|
|
119
|
+
const constants = IpayCodePushNative.getConstants();
|
|
120
|
+
return constants.CHANNEL;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Fetches the fingerprint for the app.
|
|
125
|
+
*
|
|
126
|
+
* @returns {string | null} Resolves with the fingerprint hash
|
|
127
|
+
*/
|
|
128
|
+
export const getFingerprintHash = () => {
|
|
129
|
+
const constants = IpayCodePushNative.getConstants();
|
|
130
|
+
return constants.FINGERPRINT_HASH;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Result returned by notifyAppReady()
|
|
135
|
+
* - `status: "PROMOTED"` - Staging bundle was promoted to stable (ACTIVE event)
|
|
136
|
+
* - `status: "RECOVERED"` - App recovered from crash, rollback occurred (ROLLBACK event)
|
|
137
|
+
* - `status: "STABLE"` - No changes, already stable
|
|
138
|
+
* - `crashedBundleId` - Present only when status is "RECOVERED"
|
|
139
|
+
*/
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Notifies the native side that the app has successfully started with the current bundle.
|
|
143
|
+
* If the bundle matches the staging bundle, it promotes to stable.
|
|
144
|
+
*
|
|
145
|
+
* This function is called automatically when the module loads.
|
|
146
|
+
*
|
|
147
|
+
* @returns {NotifyAppReadyResult} Bundle state information
|
|
148
|
+
* - `status: "PROMOTED"` - Staging bundle was promoted to stable (ACTIVE event)
|
|
149
|
+
* - `status: "RECOVERED"` - App recovered from crash, rollback occurred (ROLLBACK event)
|
|
150
|
+
* - `status: "STABLE"` - No changes, already stable
|
|
151
|
+
* - `crashedBundleId` - Present only when status is "RECOVERED"
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```ts
|
|
155
|
+
* const result = IpayCodePush.notifyAppReady();
|
|
156
|
+
*
|
|
157
|
+
* switch (result.status) {
|
|
158
|
+
* case "PROMOTED":
|
|
159
|
+
* // Send ACTIVE analytics event
|
|
160
|
+
* analytics.track('bundle_active', { bundleId: IpayCodePush.getBundleId() });
|
|
161
|
+
* break;
|
|
162
|
+
* case "RECOVERED":
|
|
163
|
+
* // Send ROLLBACK analytics event
|
|
164
|
+
* analytics.track('bundle_rollback', { crashedBundleId: result.crashedBundleId });
|
|
165
|
+
* break;
|
|
166
|
+
* case "STABLE":
|
|
167
|
+
* // No special action needed
|
|
168
|
+
* break;
|
|
169
|
+
* }
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
export const notifyAppReady = () => {
|
|
173
|
+
const bundleId = getBundleId();
|
|
174
|
+
const result = IpayCodePushNative.notifyAppReady({
|
|
175
|
+
bundleId
|
|
176
|
+
});
|
|
177
|
+
// Oldarch returns JSON string, newarch returns array
|
|
178
|
+
if (typeof result === "string") {
|
|
179
|
+
try {
|
|
180
|
+
return JSON.parse(result);
|
|
181
|
+
} catch {
|
|
182
|
+
return {
|
|
183
|
+
status: "STABLE"
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return result;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Gets the list of bundle IDs that have been marked as crashed.
|
|
192
|
+
* These bundles will be rejected if attempted to install again.
|
|
193
|
+
*
|
|
194
|
+
* @returns {string[]} Array of crashed bundle IDs
|
|
195
|
+
*/
|
|
196
|
+
export const getCrashHistory = () => {
|
|
197
|
+
const result = IpayCodePushNative.getCrashHistory();
|
|
198
|
+
// Oldarch returns JSON string, newarch returns array
|
|
199
|
+
if (typeof result === "string") {
|
|
200
|
+
try {
|
|
201
|
+
return JSON.parse(result);
|
|
202
|
+
} catch {
|
|
203
|
+
return [];
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return result;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Clears the crashed bundle history, allowing previously crashed bundles
|
|
211
|
+
* to be installed again.
|
|
212
|
+
*
|
|
213
|
+
* @returns {boolean} true if clearing was successful
|
|
214
|
+
*/
|
|
215
|
+
export const clearCrashHistory = () => {
|
|
216
|
+
return IpayCodePushNative.clearCrashHistory();
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Gets the base URL for the current active bundle directory.
|
|
221
|
+
* Returns the file:// URL to the bundle directory without trailing slash.
|
|
222
|
+
* This is used for Expo DOM components to construct full asset paths.
|
|
223
|
+
*
|
|
224
|
+
* @returns {string | null} Base URL string (e.g., "file:///data/.../bundle-store/abc123") or null if not available
|
|
225
|
+
*/
|
|
226
|
+
export const getBaseURL = () => {
|
|
227
|
+
const result = IpayCodePushNative.getBaseURL();
|
|
228
|
+
if (typeof result === "string" && result !== "") {
|
|
229
|
+
return result;
|
|
230
|
+
}
|
|
231
|
+
return null;
|
|
232
|
+
};
|
|
233
|
+
//# sourceMappingURL=native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["NativeEventEmitter","IpayCodePushErrorCode","isIpayCodePushError","IpayCodePushNative","NIL_UUID","__IPAY_CODE_PUSH_BUNDLE_ID","undefined","IpayCodePushConstants","IPAY_CODE_PUSH_BUNDLE_ID","addListener","eventName","listener","eventEmitter","subscription","remove","inflightUpdates","Map","lastInstalledBundleId","updateBundle","paramsOrBundleId","fileUrl","updateBundleId","bundleId","status","currentBundleId","getBundleId","localeCompare","Error","existing","get","targetFileUrl","targetFileHash","fileHash","promise","ok","delete","set","getAppVersion","constants","getConstants","APP_VERSION","reload","getMinBundleId","MIN_BUNDLE_ID","getChannel","CHANNEL","getFingerprintHash","FINGERPRINT_HASH","notifyAppReady","result","JSON","parse","getCrashHistory","clearCrashHistory","getBaseURL"],"sourceRoot":"../../src","sources":["native.ts"],"mappings":";;AAAA,SAASA,kBAAkB,QAAQ,cAAc;AACjD,SAASC,qBAAqB,EAAEC,mBAAmB,QAAQ,YAAS;AAGpE,OAAOC,kBAAkB,MAElB,+BAA4B;AAGnC,SAASF,qBAAqB,EAAEC,mBAAmB;AAEnD,MAAME,QAAQ,GAAG,sCAAsC;AAEvD,MAAMC,0BAA0B,GAACC,SAAS;AAE1C,OAAO,MAAMC,qBAAqB,GAAG;EACjCC,wBAAwB,EAAEH,0BAA0B,IAAID;AAC5D,CAAC;AASD,OAAO,MAAMK,WAAW,GAAGA,CACvBC,SAAY,EACZC,QAA8B,CAAE;AAAA,KAC/B;EACD,MAAMC,YAAY,GAAG,IAAIZ,kBAAkB,CAACG,kBAAkB,CAAC;EAC/D,MAAMU,YAAY,GAAGD,YAAY,CAACH,WAAW,CAACC,SAAS,EAAEC,QAAQ,CAAC;EAElE,OAAO,MAAM;IACTE,YAAY,CAACC,MAAM,CAAC,CAAC;EACzB,CAAC;AACL,CAAC;AAMD;AACA,MAAMC,eAAe,GAAG,IAAIC,GAAG,CAA2B,CAAC;;AAE3D;AACA,IAAIC,qBAAoC,GAAG,IAAI;;AAE/C;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;;AAMA,OAAO,eAAeC,YAAYA,CAC9BC,gBAAuC,EACvCC,OAAuB,EACP;EAEhB,MAAMC,cAAc,GAAG,OAAOF,gBAAgB,KAAK,QAAQ,GAAGA,gBAAgB,GAAGA,gBAAgB,CAACG,QAAQ;EAE1G,MAAMC,MAAM,GAAG,OAAOJ,gBAAgB,KAAK,QAAQ,GAAG,QAAQ,GAAGA,gBAAgB,CAACI,MAAM;;EAExF;EACA,IAAIA,MAAM,KAAK,QAAQ,IAAIN,qBAAqB,KAAKI,cAAc,EAAE;IACjE,OAAO,IAAI;EACf;EAEA,MAAMG,eAAe,GAAGC,WAAW,CAAC,CAAC;;EAErC;EACA,IACIF,MAAM,KAAK,QAAQ,IACnBF,cAAc,CAACK,aAAa,CAACF,eAAe,CAAC,IAAI,CAAC,EACpD;IACE,MAAM,IAAIG,KAAK,CACX,yFACJ,CAAC;EACL;;EAEA;EACA,MAAMC,QAAQ,GAAGb,eAAe,CAACc,GAAG,CAACR,cAAc,CAAC;EACpD,IAAIO,QAAQ,EAAE,OAAOA,QAAQ;EAE7B,MAAME,aAAa,GAAG,OAAOX,gBAAgB,KAAK,QAAQ,GAAIC,OAAO,IAAI,IAAI,GAAID,gBAAgB,CAACC,OAAO;EAEzG,MAAMW,cAAc,GAAG,OAAOZ,gBAAgB,KAAK,QAAQ,GAAGb,SAAS,GAAGa,gBAAgB,CAACa,QAAQ;EAEnG,MAAMC,OAAO,GAAG,CAAC,YAAY;IACzB,IAAI;MACA,MAAMC,EAAE,GAAG,MAAM/B,kBAAkB,CAACe,YAAY,CAAC;QAC7CI,QAAQ,EAAED,cAAc;QACxBD,OAAO,EAAEU,aAAa;QACtBE,QAAQ,EAAED,cAAc,IAAI;MAChC,CAAC,CAAC;MAEF,IAAIG,EAAE,EAAE;QACJjB,qBAAqB,GAAGI,cAAc;MAC1C;MAEA,OAAOa,EAAE;IAEb,CAAC,SAAS;MACNnB,eAAe,CAACoB,MAAM,CAACd,cAAc,CAAC;IAC1C;EACJ,CAAC,EAAE,CAAC;EAEJN,eAAe,CAACqB,GAAG,CAACf,cAAc,EAAEY,OAAO,CAAC;EAC5C,OAAOA,OAAO;AAClB;;AAEA;AACA;AACA;AACA,OAAO,MAAMI,aAAa,GAAGA,CAAA,KAAqB;EAC9C,MAAMC,SAAS,GAAGnC,kBAAkB,CAACoC,YAAY,CAAC,CAAC;EACnD,OAAOD,SAAS,EAAEE,WAAW,IAAI,IAAI;AACzC,CAAC;;AAED;AACA;AACA;AACA,OAAO,MAAMC,MAAM,GAAG,MAAAA,CAAA,KAAY;EAC9B,MAAMtC,kBAAkB,CAACsC,MAAM,CAAC,CAAC;AACrC,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,cAAc,GAAGA,CAAA,KAAc;EACxC,MAAMJ,SAAS,GAAGnC,kBAAkB,CAACoC,YAAY,CAAC,CAAC;EACnD,OAAOD,SAAS,CAACK,aAAa;AAClC,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMlB,WAAW,GAAGA,CAAA,KAAc;EACvC,OAAOlB,qBAAqB,CAACC,wBAAwB,KAAKJ,QAAQ,GAC9DsC,cAAc,CAAC,CAAC,GAChBnC,qBAAqB,CAACC,wBAAwB;AACpD,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMoC,UAAU,GAAGA,CAAA,KAAc;EACpC,MAAMN,SAAS,GAAGnC,kBAAkB,CAACoC,YAAY,CAAC,CAAC;EACnD,OAAOD,SAAS,CAACO,OAAO;AAC5B,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,kBAAkB,GAAGA,CAAA,KAAqB;EACnD,MAAMR,SAAS,GAAGnC,kBAAkB,CAACoC,YAAY,CAAC,CAAC;EACnD,OAAOD,SAAS,CAACS,gBAAgB;AACrC,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,cAAc,GAAGA,CAAA,KAA4B;EACtD,MAAM1B,QAAQ,GAAGG,WAAW,CAAC,CAAC;EAC9B,MAAMwB,MAAM,GAAG9C,kBAAkB,CAAC6C,cAAc,CAAC;IAAE1B;EAAS,CAAC,CAAC;EAC9D;EACA,IAAI,OAAO2B,MAAM,KAAK,QAAQ,EAAE;IAC5B,IAAI;MACA,OAAOC,IAAI,CAACC,KAAK,CAACF,MAAM,CAAC;IAC7B,CAAC,CAAC,MAAM;MACJ,OAAO;QAAE1B,MAAM,EAAE;MAAS,CAAC;IAC/B;EACJ;EACA,OAAO0B,MAAM;AACjB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMG,eAAe,GAAGA,CAAA,KAAgB;EAC3C,MAAMH,MAAM,GAAG9C,kBAAkB,CAACiD,eAAe,CAAC,CAAC;EACnD;EACA,IAAI,OAAOH,MAAM,KAAK,QAAQ,EAAE;IAC5B,IAAI;MACA,OAAOC,IAAI,CAACC,KAAK,CAACF,MAAM,CAAC;IAC7B,CAAC,CAAC,MAAM;MACJ,OAAO,EAAE;IACb;EACJ;EACA,OAAOA,MAAM;AACjB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMI,iBAAiB,GAAGA,CAAA,KAAe;EAC5C,OAAOlD,kBAAkB,CAACkD,iBAAiB,CAAC,CAAC;AACjD,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,UAAU,GAAGA,CAAA,KAAqB;EAC3C,MAAML,MAAM,GAAG9C,kBAAkB,CAACmD,UAAU,CAAC,CAAC;EAC9C,IAAI,OAAOL,MAAM,KAAK,QAAQ,IAAIA,MAAM,KAAK,EAAE,EAAE;IAC7C,OAAOA,MAAM;EACjB;EACA,OAAO,IAAI;AACf,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import useSyncExternalStoreExports from "use-sync-external-store/shim/with-selector";
|
|
4
|
+
const {
|
|
5
|
+
useSyncExternalStoreWithSelector
|
|
6
|
+
} = useSyncExternalStoreExports;
|
|
7
|
+
const createIpayCodePushStore = () => {
|
|
8
|
+
let state = {
|
|
9
|
+
progress: 0,
|
|
10
|
+
isUpdateDownloaded: false
|
|
11
|
+
};
|
|
12
|
+
const getSnapshot = () => {
|
|
13
|
+
return state;
|
|
14
|
+
};
|
|
15
|
+
const listeners = new Set();
|
|
16
|
+
const emitChange = () => {
|
|
17
|
+
for (const listener of listeners) {
|
|
18
|
+
listener();
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const setState = newState => {
|
|
22
|
+
// Merge first, then normalize derived fields
|
|
23
|
+
const nextState = {
|
|
24
|
+
...state,
|
|
25
|
+
...newState
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Derive `isUpdateDownloaded` from `progress` if provided.
|
|
29
|
+
// If `progress` is not provided but `isUpdateDownloaded` is,
|
|
30
|
+
// honor the explicit value.
|
|
31
|
+
if ("progress" in newState && typeof newState.progress === "number") {
|
|
32
|
+
nextState.isUpdateDownloaded = newState.progress >= 1;
|
|
33
|
+
} else if ("isUpdateDownloaded" in newState && typeof newState.isUpdateDownloaded === "boolean") {
|
|
34
|
+
nextState.isUpdateDownloaded = newState.isUpdateDownloaded;
|
|
35
|
+
}
|
|
36
|
+
state = nextState;
|
|
37
|
+
emitChange();
|
|
38
|
+
};
|
|
39
|
+
const subscribe = listener => {
|
|
40
|
+
listeners.add(listener);
|
|
41
|
+
return () => listeners.delete(listener);
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
getSnapshot,
|
|
45
|
+
setState,
|
|
46
|
+
subscribe
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
export const ipayCodePushStore = createIpayCodePushStore();
|
|
50
|
+
export const useIpayCodePushStore = (selector = snapshot => snapshot) => {
|
|
51
|
+
return useSyncExternalStoreWithSelector(ipayCodePushStore.subscribe, ipayCodePushStore.getSnapshot, ipayCodePushStore.getSnapshot, selector);
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useSyncExternalStoreExports","useSyncExternalStoreWithSelector","createIpayCodePushStore","state","progress","isUpdateDownloaded","getSnapshot","listeners","Set","emitChange","listener","setState","newState","nextState","subscribe","add","delete","ipayCodePushStore","useIpayCodePushStore","selector","snapshot"],"sourceRoot":"../../src","sources":["store.ts"],"mappings":";;AAAA,OAAOA,2BAA2B,MAAM,4CAA4C;AAOpF,MAAM;EAAEC;AAAiC,CAAC,GAAGD,2BAA2B;AAExE,MAAME,uBAAuB,GAAGA,CAAA,KAAM;EAElC,IAAIC,KAAwB,GAAG;IAC3BC,QAAQ,EAAE,CAAC;IACXC,kBAAkB,EAAE;EACxB,CAAC;EAED,MAAMC,WAAW,GAAGA,CAAA,KAAM;IACtB,OAAOH,KAAK;EAChB,CAAC;EAED,MAAMI,SAAS,GAAG,IAAIC,GAAG,CAAa,CAAC;EAEvC,MAAMC,UAAU,GAAGA,CAAA,KAAM;IACrB,KAAK,MAAMC,QAAQ,IAAIH,SAAS,EAAE;MAC9BG,QAAQ,CAAC,CAAC;IACd;EACJ,CAAC;EAED,MAAMC,QAAQ,GAAIC,QAAoC,IAAK;IACvD;IACA,MAAMC,SAA4B,GAAG;MACjC,GAAGV,KAAK;MACR,GAAGS;IACP,CAAC;;IAED;IACA;IACA;IACA,IAAI,UAAU,IAAIA,QAAQ,IAAI,OAAOA,QAAQ,CAACR,QAAQ,KAAK,QAAQ,EAAE;MACjES,SAAS,CAACR,kBAAkB,GAAGO,QAAQ,CAACR,QAAQ,IAAI,CAAC;IACzD,CAAC,MAAM,IAAI,oBAAoB,IAAIQ,QAAQ,IAAI,OAAOA,QAAQ,CAACP,kBAAkB,KAAK,SAAS,EAAE;MAC7FQ,SAAS,CAACR,kBAAkB,GAAGO,QAAQ,CAACP,kBAAkB;IAC9D;IAEAF,KAAK,GAAGU,SAAS;IACjBJ,UAAU,CAAC,CAAC;EAChB,CAAC;EAED,MAAMK,SAAS,GAAIJ,QAAoB,IAAK;IACxCH,SAAS,CAACQ,GAAG,CAACL,QAAQ,CAAC;IACvB,OAAO,MAAMH,SAAS,CAACS,MAAM,CAACN,QAAQ,CAAC;EAC3C,CAAC;EAED,OAAO;IAAEJ,WAAW;IAAEK,QAAQ;IAAEG;EAAU,CAAC;AAC/C,CAAC;AAED,OAAO,MAAMG,iBAAiB,GAAGf,uBAAuB,CAAC,CAAC;AAE1D,OAAO,MAAMgB,oBAAoB,GAAGA,CAChCC,QAA4C,GAAIC,QAAQ,IAAKA,QAAa,KACzE;EACD,OAAOnB,gCAAgC,CACnCgB,iBAAiB,CAACH,SAAS,EAC3BG,iBAAiB,CAACX,WAAW,EAC7BW,iBAAiB,CAACX,WAAW,EAC7Ba,QACJ,CAAC;AACL,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Parameters passed to resolver.checkUpdate method
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Parameters passed to resolver.notifyAppReady method
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Resolver interface for custom network operations
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Information about a signature verification failure.
|
|
17
|
+
* This is a security-critical event that indicates the bundle
|
|
18
|
+
* may have been tampered with or the public key is misconfigured.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Checks if an error is a signature verification failure.
|
|
23
|
+
* Matches error messages from both iOS and Android native implementations.
|
|
24
|
+
*
|
|
25
|
+
* **IMPORTANT**: This function relies on specific error message patterns from native code.
|
|
26
|
+
* If you change the error messages in the native implementations, update these patterns:
|
|
27
|
+
* - iOS: `ios/ipaycodepush/Internal/SignatureVerifier.swift` (SignatureVerificationError)
|
|
28
|
+
* - Android: `android/src/main/java/com/ipaycodepush/SignatureVerifier.kt` (SignatureVerificationException)
|
|
29
|
+
*/
|
|
30
|
+
export function isSignatureVerificationError(error) {
|
|
31
|
+
if (!(error instanceof Error)) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
const message = error.message.toLowerCase();
|
|
35
|
+
|
|
36
|
+
// Match iOS SignatureVerificationError messages
|
|
37
|
+
// Match Android SignatureVerificationException messages
|
|
38
|
+
return message.includes("signature verification") || message.includes("public key not configured") || message.includes("public key format is invalid") || message.includes("signature format is invalid") || message.includes("bundle may be corrupted or tampered");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Extracts signature verification failure details from an error.
|
|
43
|
+
*/
|
|
44
|
+
export function extractSignatureFailure(error, bundleId) {
|
|
45
|
+
const normalizedError = error instanceof Error ? error : new Error(String(error));
|
|
46
|
+
return {
|
|
47
|
+
bundleId,
|
|
48
|
+
message: normalizedError.message,
|
|
49
|
+
error: normalizedError
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The update info for the database layer.
|
|
55
|
+
* This is the update info that is used by the database.
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The update info for the app layer.
|
|
60
|
+
* This is the update info that is used by the app.
|
|
61
|
+
*/
|
|
62
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["isSignatureVerificationError","error","Error","message","toLowerCase","includes","extractSignatureFailure","bundleId","normalizedError","String"],"sourceRoot":"../../src","sources":["types.ts"],"mappings":";;AACA;AACA;AACA;;AAgDA;AACA;AACA;;AA0BA;AACA;AACA;;AAoDA;AACA;AACA;AACA;AACA;;AAgBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,4BAA4BA,CAACC,KAAc,EAAW;EAClE,IAAI,EAAEA,KAAK,YAAYC,KAAK,CAAC,EAAE;IAC3B,OAAO,KAAK;EAChB;EAEA,MAAMC,OAAO,GAAGF,KAAK,CAACE,OAAO,CAACC,WAAW,CAAC,CAAC;;EAE3C;EACA;EACA,OACID,OAAO,CAACE,QAAQ,CAAC,wBAAwB,CAAC,IAC1CF,OAAO,CAACE,QAAQ,CAAC,2BAA2B,CAAC,IAC7CF,OAAO,CAACE,QAAQ,CAAC,8BAA8B,CAAC,IAChDF,OAAO,CAACE,QAAQ,CAAC,6BAA6B,CAAC,IAC/CF,OAAO,CAACE,QAAQ,CAAC,qCAAqC,CAAC;AAE/D;;AAEA;AACA;AACA;AACA,OAAO,SAASC,uBAAuBA,CACnCL,KAAc,EACdM,QAAgB,EACY;EAC5B,MAAMC,eAAe,GACjBP,KAAK,YAAYC,KAAK,GAAGD,KAAK,GAAG,IAAIC,KAAK,CAACO,MAAM,CAACR,KAAK,CAAC,CAAC;EAE7D,OAAO;IACHM,QAAQ;IACRJ,OAAO,EAAEK,eAAe,CAACL,OAAO;IAChCF,KAAK,EAAEO;EACX,CAAC;AACL;;AAKA;AACA;AACA;AACA;;AAUA;AACA;AACA;AACA","ignoreList":[]}
|