react-native-iap 14.4.7 → 14.4.9

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.
@@ -24,6 +24,7 @@ import type {
24
24
  Purchase,
25
25
  SubscriptionStatusIOS,
26
26
  } from '../types';
27
+ import {RnIapConsole} from './debug';
27
28
 
28
29
  const PLATFORM_IOS: IapPlatform = 'ios';
29
30
  const PLATFORM_ANDROID: IapPlatform = 'android';
@@ -78,7 +79,7 @@ function normalizeProductTypeIOS(value?: Nullable<string>): ProductTypeIOS {
78
79
  return 'non-renewing-subscription';
79
80
  default:
80
81
  if (value) {
81
- console.warn(
82
+ RnIapConsole.warn(
82
83
  `[react-native-iap] Unknown iOS product type "${value}", defaulting to NonConsumable.`,
83
84
  );
84
85
  }
@@ -170,15 +171,25 @@ function toNullableBoolean(value: unknown): boolean | null {
170
171
  return null;
171
172
  }
172
173
 
173
- function parseSubscriptionOffers(value?: Nullable<string>) {
174
+ function parseSubscriptionOffers(value?: Nullable<string> | any[]) {
174
175
  if (!value) return undefined;
176
+
177
+ // If it's already an array (from mocks), return it as-is
178
+ if (Array.isArray(value)) {
179
+ return value;
180
+ }
181
+
182
+ // Otherwise, try to parse it as JSON string
175
183
  try {
176
- const parsed = JSON.parse(value);
184
+ const parsed = JSON.parse(value as string);
177
185
  if (Array.isArray(parsed)) {
178
186
  return parsed;
179
187
  }
180
188
  } catch (error) {
181
- console.warn('Failed to parse subscriptionOfferDetailsAndroid:', error);
189
+ RnIapConsole.warn(
190
+ 'Failed to parse subscriptionOfferDetailsAndroid:',
191
+ error,
192
+ );
182
193
  }
183
194
  return undefined;
184
195
  }
@@ -270,7 +281,7 @@ export function convertProductToProductSubscription(
270
281
  product: Product,
271
282
  ): ProductSubscription {
272
283
  if (product.type !== PRODUCT_TYPE_SUBS) {
273
- console.warn(
284
+ RnIapConsole.warn(
274
285
  'Converting non-subscription product to ProductSubscription:',
275
286
  product.id,
276
287
  );
@@ -390,7 +401,7 @@ export function validateNitroProduct(nitroProduct: NitroProduct): boolean {
390
401
  !(field in nitroProduct) ||
391
402
  nitroProduct[field as keyof NitroProduct] == null
392
403
  ) {
393
- console.error(
404
+ RnIapConsole.error(
394
405
  `NitroProduct missing required field: ${field}`,
395
406
  nitroProduct,
396
407
  );
@@ -415,7 +426,7 @@ export function validateNitroPurchase(nitroPurchase: NitroPurchase): boolean {
415
426
  !(field in nitroPurchase) ||
416
427
  nitroPurchase[field as keyof NitroPurchase] == null
417
428
  ) {
418
- console.error(
429
+ RnIapConsole.error(
419
430
  `NitroPurchase missing required field: ${field}`,
420
431
  nitroPurchase,
421
432
  );
package/src/utils.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type {AppTransaction} from './types';
2
+ import {RnIapConsole} from './utils/debug';
2
3
 
3
4
  /**
4
5
  * Parse the string payload returned by the native getAppTransactionIOS call into
@@ -62,7 +63,10 @@ export const parseAppTransactionPayload = (
62
63
  signedDate,
63
64
  };
64
65
  } catch (error) {
65
- console.warn('[parseAppTransactionPayload] Failed to parse payload', error);
66
+ RnIapConsole.warn(
67
+ '[parseAppTransactionPayload] Failed to parse payload',
68
+ error,
69
+ );
66
70
  return null;
67
71
  }
68
72
  };
@@ -1,64 +0,0 @@
1
- "use strict";
2
-
3
- import { getAvailablePurchases } from "../index.js";
4
- /**
5
- * Get active subscriptions
6
- * @param subscriptionIds - Optional array of subscription IDs to filter by
7
- * @returns Promise<ActiveSubscription[]> - Array of active subscriptions
8
- */
9
- export const getActiveSubscriptions = async subscriptionIds => {
10
- try {
11
- // Get available purchases and filter for subscriptions
12
- const purchases = await getAvailablePurchases();
13
-
14
- // Filter for subscriptions and map to ActiveSubscription format
15
- const subscriptions = purchases.filter(purchase => {
16
- // Filter by subscription IDs if provided
17
- if (subscriptionIds && subscriptionIds.length > 0) {
18
- return subscriptionIds.includes(purchase.productId);
19
- }
20
- return true;
21
- }).map(purchase => {
22
- const iosPurchase = purchase;
23
- const androidPurchase = purchase;
24
- return {
25
- productId: purchase.productId,
26
- isActive: true,
27
- // If it's in availablePurchases, it's active
28
- // Backend validation fields
29
- transactionId: purchase.id,
30
- purchaseToken: purchase.purchaseToken,
31
- transactionDate: purchase.transactionDate,
32
- // Platform-specific fields
33
- expirationDateIOS: iosPurchase.expirationDateIOS ?? null,
34
- autoRenewingAndroid: androidPurchase.autoRenewingAndroid ?? androidPurchase.isAutoRenewing,
35
- // deprecated - use isAutoRenewing instead
36
- environmentIOS: iosPurchase.environmentIOS,
37
- // Convenience fields
38
- willExpireSoon: false,
39
- // Would need to calculate based on expiration date
40
- daysUntilExpirationIOS: iosPurchase.expirationDateIOS != null ? Math.ceil((iosPurchase.expirationDateIOS - Date.now()) / (1000 * 60 * 60 * 24)) : undefined
41
- };
42
- });
43
- return subscriptions;
44
- } catch (error) {
45
- console.error('Failed to get active subscriptions:', error);
46
- throw error;
47
- }
48
- };
49
-
50
- /**
51
- * Check if there are any active subscriptions
52
- * @param subscriptionIds - Optional array of subscription IDs to check
53
- * @returns Promise<boolean> - True if there are active subscriptions
54
- */
55
- export const hasActiveSubscriptions = async subscriptionIds => {
56
- try {
57
- const activeSubscriptions = await getActiveSubscriptions(subscriptionIds);
58
- return activeSubscriptions.length > 0;
59
- } catch (error) {
60
- console.error('Failed to check active subscriptions:', error);
61
- return false;
62
- }
63
- };
64
- //# sourceMappingURL=subscription.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["getAvailablePurchases","getActiveSubscriptions","subscriptionIds","purchases","subscriptions","filter","purchase","length","includes","productId","map","iosPurchase","androidPurchase","isActive","transactionId","id","purchaseToken","transactionDate","expirationDateIOS","autoRenewingAndroid","isAutoRenewing","environmentIOS","willExpireSoon","daysUntilExpirationIOS","Math","ceil","Date","now","undefined","error","console","hasActiveSubscriptions","activeSubscriptions"],"sourceRoot":"../../../src","sources":["helpers/subscription.ts"],"mappings":";;AAAA,SAAQA,qBAAqB,QAAO,aAAK;AAGzC;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,sBAAsB,GAAG,MACpCC,eAA0B,IACQ;EAClC,IAAI;IACF;IACA,MAAMC,SAAS,GAAG,MAAMH,qBAAqB,CAAC,CAAC;;IAE/C;IACA,MAAMI,aAAa,GAAGD,SAAS,CAC5BE,MAAM,CAAEC,QAAQ,IAAK;MACpB;MACA,IAAIJ,eAAe,IAAIA,eAAe,CAACK,MAAM,GAAG,CAAC,EAAE;QACjD,OAAOL,eAAe,CAACM,QAAQ,CAACF,QAAQ,CAACG,SAAS,CAAC;MACrD;MACA,OAAO,IAAI;IACb,CAAC,CAAC,CACDC,GAAG,CAAEJ,QAAQ,IAAyB;MACrC,MAAMK,WAAW,GAAGL,QAAuB;MAC3C,MAAMM,eAAe,GAAGN,QAA2B;MACnD,OAAO;QACLG,SAAS,EAAEH,QAAQ,CAACG,SAAS;QAC7BI,QAAQ,EAAE,IAAI;QAAE;QAChB;QACAC,aAAa,EAAER,QAAQ,CAACS,EAAE;QAC1BC,aAAa,EAAEV,QAAQ,CAACU,aAAa;QACrCC,eAAe,EAAEX,QAAQ,CAACW,eAAe;QACzC;QACAC,iBAAiB,EAAEP,WAAW,CAACO,iBAAiB,IAAI,IAAI;QACxDC,mBAAmB,EACjBP,eAAe,CAACO,mBAAmB,IACnCP,eAAe,CAACQ,cAAc;QAAE;QAClCC,cAAc,EAAEV,WAAW,CAACU,cAAc;QAC1C;QACAC,cAAc,EAAE,KAAK;QAAE;QACvBC,sBAAsB,EACpBZ,WAAW,CAACO,iBAAiB,IAAI,IAAI,GACjCM,IAAI,CAACC,IAAI,CACP,CAACd,WAAW,CAACO,iBAAiB,GAAGQ,IAAI,CAACC,GAAG,CAAC,CAAC,KACxC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CACxB,CAAC,GACDC;MACR,CAAC;IACH,CAAC,CAAC;IAEJ,OAAOxB,aAAa;EACtB,CAAC,CAAC,OAAOyB,KAAK,EAAE;IACdC,OAAO,CAACD,KAAK,CAAC,qCAAqC,EAAEA,KAAK,CAAC;IAC3D,MAAMA,KAAK;EACb;AACF,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,OAAO,MAAME,sBAAsB,GAAG,MACpC7B,eAA0B,IACL;EACrB,IAAI;IACF,MAAM8B,mBAAmB,GAAG,MAAM/B,sBAAsB,CAACC,eAAe,CAAC;IACzE,OAAO8B,mBAAmB,CAACzB,MAAM,GAAG,CAAC;EACvC,CAAC,CAAC,OAAOsB,KAAK,EAAE;IACdC,OAAO,CAACD,KAAK,CAAC,uCAAuC,EAAEA,KAAK,CAAC;IAC7D,OAAO,KAAK;EACd;AACF,CAAC","ignoreList":[]}
@@ -1,14 +0,0 @@
1
- import type { ActiveSubscription } from '../types';
2
- /**
3
- * Get active subscriptions
4
- * @param subscriptionIds - Optional array of subscription IDs to filter by
5
- * @returns Promise<ActiveSubscription[]> - Array of active subscriptions
6
- */
7
- export declare const getActiveSubscriptions: (subscriptionIds?: string[]) => Promise<ActiveSubscription[]>;
8
- /**
9
- * Check if there are any active subscriptions
10
- * @param subscriptionIds - Optional array of subscription IDs to check
11
- * @returns Promise<boolean> - True if there are active subscriptions
12
- */
13
- export declare const hasActiveSubscriptions: (subscriptionIds?: string[]) => Promise<boolean>;
14
- //# sourceMappingURL=subscription.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../../../../src/helpers/subscription.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,kBAAkB,EAA+B,MAAM,UAAU,CAAC;AAE/E;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GACjC,kBAAkB,MAAM,EAAE,KACzB,OAAO,CAAC,kBAAkB,EAAE,CA+C9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GACjC,kBAAkB,MAAM,EAAE,KACzB,OAAO,CAAC,OAAO,CAQjB,CAAC"}
@@ -1,75 +0,0 @@
1
- import {getAvailablePurchases} from '../';
2
- import type {ActiveSubscription, PurchaseIOS, PurchaseAndroid} from '../types';
3
-
4
- /**
5
- * Get active subscriptions
6
- * @param subscriptionIds - Optional array of subscription IDs to filter by
7
- * @returns Promise<ActiveSubscription[]> - Array of active subscriptions
8
- */
9
- export const getActiveSubscriptions = async (
10
- subscriptionIds?: string[],
11
- ): Promise<ActiveSubscription[]> => {
12
- try {
13
- // Get available purchases and filter for subscriptions
14
- const purchases = await getAvailablePurchases();
15
-
16
- // Filter for subscriptions and map to ActiveSubscription format
17
- const subscriptions = purchases
18
- .filter((purchase) => {
19
- // Filter by subscription IDs if provided
20
- if (subscriptionIds && subscriptionIds.length > 0) {
21
- return subscriptionIds.includes(purchase.productId);
22
- }
23
- return true;
24
- })
25
- .map((purchase): ActiveSubscription => {
26
- const iosPurchase = purchase as PurchaseIOS;
27
- const androidPurchase = purchase as PurchaseAndroid;
28
- return {
29
- productId: purchase.productId,
30
- isActive: true, // If it's in availablePurchases, it's active
31
- // Backend validation fields
32
- transactionId: purchase.id,
33
- purchaseToken: purchase.purchaseToken,
34
- transactionDate: purchase.transactionDate,
35
- // Platform-specific fields
36
- expirationDateIOS: iosPurchase.expirationDateIOS ?? null,
37
- autoRenewingAndroid:
38
- androidPurchase.autoRenewingAndroid ??
39
- androidPurchase.isAutoRenewing, // deprecated - use isAutoRenewing instead
40
- environmentIOS: iosPurchase.environmentIOS,
41
- // Convenience fields
42
- willExpireSoon: false, // Would need to calculate based on expiration date
43
- daysUntilExpirationIOS:
44
- iosPurchase.expirationDateIOS != null
45
- ? Math.ceil(
46
- (iosPurchase.expirationDateIOS - Date.now()) /
47
- (1000 * 60 * 60 * 24),
48
- )
49
- : undefined,
50
- };
51
- });
52
-
53
- return subscriptions;
54
- } catch (error) {
55
- console.error('Failed to get active subscriptions:', error);
56
- throw error;
57
- }
58
- };
59
-
60
- /**
61
- * Check if there are any active subscriptions
62
- * @param subscriptionIds - Optional array of subscription IDs to check
63
- * @returns Promise<boolean> - True if there are active subscriptions
64
- */
65
- export const hasActiveSubscriptions = async (
66
- subscriptionIds?: string[],
67
- ): Promise<boolean> => {
68
- try {
69
- const activeSubscriptions = await getActiveSubscriptions(subscriptionIds);
70
- return activeSubscriptions.length > 0;
71
- } catch (error) {
72
- console.error('Failed to check active subscriptions:', error);
73
- return false;
74
- }
75
- };