UNPKG

@revenuecat/purchases-capacitor-ui

Version:
222 lines 11 kB
var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import { registerPlugin } from '@capacitor/core'; import { IOS_PAYWALL_PRESENTATION_STYLE, ANDROID_PAYWALL_PRESENTATION_STYLE, PURCHASE_LOGIC_RESULT, } from './definitions'; const nativePlugin = registerPlugin('RevenueCatUI', { web: () => import('./web').then((m) => new m.RevenueCatUIWeb()), }); function assertValidPresentationConfiguration(config) { if (config === undefined) { return; } if (typeof config !== 'object' || config === null) { throw new Error(`Invalid presentationConfiguration: expected an object or undefined.`); } const { ios, android } = config; const validIos = Object.values(IOS_PAYWALL_PRESENTATION_STYLE); const validAndroid = Object.values(ANDROID_PAYWALL_PRESENTATION_STYLE); if (ios !== undefined && !validIos.includes(ios)) { throw new Error(`Invalid presentationConfiguration.ios "${String(ios)}". Expected one of: ${validIos.join(', ')}.`); } if (android !== undefined && !validAndroid.includes(android)) { throw new Error(`Invalid presentationConfiguration.android "${String(android)}". Expected one of: ${validAndroid.join(', ')}.`); } } function resolveNativePresentationOptions(config) { if (!config) { return {}; } // iOS full-screen takes precedence as the flag that the native bridge understands if (config.ios === IOS_PAYWALL_PRESENTATION_STYLE.FULL_SCREEN) { return { useFullScreenPresentation: true }; } return {}; } function serializeResultForNative(result) { if (result.result === PURCHASE_LOGIC_RESULT.ERROR && 'error' in result && result.error) { return { result: result.result, error: { code: result.error.code, message: result.error.message, }, }; } return { result: result.result }; } async function presentWithListenerSupport(nativeMethod, options, listener, purchaseLogic) { const handles = []; try { // Register PaywallListener event handlers if (listener) { if (listener.onPurchaseStarted) { const cb = listener.onPurchaseStarted; handles.push(await nativePlugin.addListener('onPurchaseStarted', (data) => { var _a; cb({ packageBeingPurchased: (_a = data.packageBeingPurchased) !== null && _a !== void 0 ? _a : data }); })); } if (listener.onPurchaseCompleted) { const cb = listener.onPurchaseCompleted; handles.push(await nativePlugin.addListener('onPurchaseCompleted', (data) => { cb({ customerInfo: data.customerInfo, storeTransaction: data.storeTransaction, }); })); } if (listener.onPurchaseError) { const cb = listener.onPurchaseError; handles.push(await nativePlugin.addListener('onPurchaseError', (data) => { var _a; cb({ error: (_a = data.error) !== null && _a !== void 0 ? _a : data }); })); } if (listener.onPurchaseCancelled) { const cb = listener.onPurchaseCancelled; handles.push(await nativePlugin.addListener('onPurchaseCancelled', () => { cb(); })); } if (listener.onRestoreStarted) { const cb = listener.onRestoreStarted; handles.push(await nativePlugin.addListener('onRestoreStarted', () => { cb(); })); } if (listener.onRestoreCompleted) { const cb = listener.onRestoreCompleted; handles.push(await nativePlugin.addListener('onRestoreCompleted', (data) => { var _a; cb({ customerInfo: (_a = data.customerInfo) !== null && _a !== void 0 ? _a : data }); })); } if (listener.onRestoreError) { const cb = listener.onRestoreError; handles.push(await nativePlugin.addListener('onRestoreError', (data) => { var _a; cb({ error: (_a = data.error) !== null && _a !== void 0 ? _a : data }); })); } } // Always register onPurchaseInitiated so we auto-resume when the user // doesn't provide an onPurchaseInitiated callback — otherwise the // purchase flow hangs waiting for a resume that never comes. // This must be outside the `if (listener)` block because the native // delegate adapter always fires this event (even with purchaseLogic only). const onPurchaseInitiatedCb = listener === null || listener === void 0 ? void 0 : listener.onPurchaseInitiated; handles.push(await nativePlugin.addListener('onPurchaseInitiated', (data) => { var _a; const requestId = data.requestId; const packageBeingPurchased = (_a = data.package) !== null && _a !== void 0 ? _a : data.packageBeingPurchased; if (onPurchaseInitiatedCb) { onPurchaseInitiatedCb({ packageBeingPurchased, resumable: { resume(shouldProceed = true) { nativePlugin.resumePurchaseInitiated({ requestId, shouldProceed }); }, }, }); } else { // No callback provided — auto-proceed with the purchase. nativePlugin.resumePurchaseInitiated({ requestId, shouldProceed: true }); } })); // Register PurchaseLogic event handlers if (purchaseLogic) { handles.push(await nativePlugin.addListener('onPerformPurchaseRequest', async (data) => { var _a, _b, _c; const requestId = data.requestId; const packageToPurchase = (_b = (_a = data.package) !== null && _a !== void 0 ? _a : data.packageBeingPurchased) !== null && _b !== void 0 ? _b : data.packageToPurchase; try { const result = await purchaseLogic.performPurchase({ packageToPurchase }); await nativePlugin.resumePurchaseLogicPurchase(Object.assign({ requestId }, serializeResultForNative(result))); } catch (e) { await nativePlugin.resumePurchaseLogicPurchase({ requestId, result: PURCHASE_LOGIC_RESULT.ERROR, error: { message: (_c = e === null || e === void 0 ? void 0 : e.message) !== null && _c !== void 0 ? _c : 'Unknown error' }, }); } })); handles.push(await nativePlugin.addListener('onPerformRestoreRequest', async (data) => { var _a; const requestId = data.requestId; try { const result = await purchaseLogic.performRestore(); await nativePlugin.resumePurchaseLogicRestore(Object.assign({ requestId }, serializeResultForNative(result))); } catch (e) { await nativePlugin.resumePurchaseLogicRestore({ requestId, result: PURCHASE_LOGIC_RESULT.ERROR, error: { message: (_a = e === null || e === void 0 ? void 0 : e.message) !== null && _a !== void 0 ? _a : 'Unknown error' }, }); } })); } // Call native with serializable-only options const nativeOptions = Object.assign(Object.assign({}, options), { hasPaywallListener: !!listener, hasPurchaseLogic: !!purchaseLogic }); // Remove non-serializable fields delete nativeOptions.listener; delete nativeOptions.purchaseLogic; return await nativeMethod(nativeOptions); } finally { // Clean up all registered listeners for (const handle of handles) { await handle.remove(); } } } const RevenueCatUI = { async presentPaywall(options) { assertValidPresentationConfiguration(options === null || options === void 0 ? void 0 : options.presentationConfiguration); const _a = options !== null && options !== void 0 ? options : {}, { presentationConfiguration, listener, purchaseLogic } = _a, rest = __rest(_a, ["presentationConfiguration", "listener", "purchaseLogic"]); const nativeOpts = Object.assign(Object.assign({}, rest), resolveNativePresentationOptions(presentationConfiguration)); if (!listener && !purchaseLogic) { return nativePlugin.presentPaywall(nativeOpts); } return presentWithListenerSupport((opts) => nativePlugin.presentPaywall(opts), nativeOpts, listener, purchaseLogic); }, async presentPaywallIfNeeded(options) { assertValidPresentationConfiguration(options === null || options === void 0 ? void 0 : options.presentationConfiguration); const { presentationConfiguration, listener, purchaseLogic } = options, rest = __rest(options, ["presentationConfiguration", "listener", "purchaseLogic"]); const nativeOpts = Object.assign(Object.assign({}, rest), resolveNativePresentationOptions(presentationConfiguration)); if (!listener && !purchaseLogic) { return nativePlugin.presentPaywallIfNeeded(nativeOpts); } return presentWithListenerSupport((opts) => nativePlugin.presentPaywallIfNeeded(opts), nativeOpts, listener, purchaseLogic); }, async presentCustomerCenter() { return nativePlugin.presentCustomerCenter(); }, setMockWebResults: nativePlugin.setMockWebResults ? async (options) => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return nativePlugin.setMockWebResults(options); } : undefined, addListener(eventName, listener) { return nativePlugin.addListener(eventName, listener); }, removeAllListeners() { return nativePlugin.removeAllListeners(); }, }; export * from './definitions'; export { PAYWALL_RESULT } from '@revenuecat/purchases-typescript-internal-esm'; export { RevenueCatUI }; //# sourceMappingURL=index.js.map