expo-iap 3.0.7 → 3.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/CLAUDE.md +14 -2
- package/CONTRIBUTING.md +19 -0
- package/README.md +18 -6
- package/android/build.gradle +24 -1
- package/android/src/main/java/expo/modules/iap/ExpoIapLog.kt +69 -0
- package/android/src/main/java/expo/modules/iap/ExpoIapModule.kt +190 -59
- package/build/index.d.ts +32 -111
- package/build/index.d.ts.map +1 -1
- package/build/index.js +198 -243
- package/build/index.js.map +1 -1
- package/build/modules/android.d.ts +7 -12
- package/build/modules/android.d.ts.map +1 -1
- package/build/modules/android.js +15 -12
- package/build/modules/android.js.map +1 -1
- package/build/modules/ios.d.ts +35 -36
- package/build/modules/ios.d.ts.map +1 -1
- package/build/modules/ios.js +101 -35
- package/build/modules/ios.js.map +1 -1
- package/build/types.d.ts +107 -82
- package/build/types.d.ts.map +1 -1
- package/build/types.js +1 -0
- package/build/types.js.map +1 -1
- package/build/useIAP.d.ts +7 -12
- package/build/useIAP.d.ts.map +1 -1
- package/build/useIAP.js +49 -23
- package/build/useIAP.js.map +1 -1
- package/build/utils/errorMapping.d.ts +32 -23
- package/build/utils/errorMapping.d.ts.map +1 -1
- package/build/utils/errorMapping.js +117 -22
- package/build/utils/errorMapping.js.map +1 -1
- package/ios/ExpoIap.podspec +3 -2
- package/ios/ExpoIapHelper.swift +96 -0
- package/ios/ExpoIapLog.swift +127 -0
- package/ios/ExpoIapModule.swift +218 -340
- package/openiap-versions.json +5 -0
- package/package.json +2 -2
- package/plugin/build/withIAP.js +6 -4
- package/plugin/src/withIAP.ts +14 -4
- package/scripts/update-types.mjs +20 -1
- package/src/index.ts +280 -356
- package/src/modules/android.ts +25 -23
- package/src/modules/ios.ts +138 -48
- package/src/types.ts +139 -91
- package/src/useIAP.ts +91 -58
- package/src/utils/errorMapping.ts +203 -23
- package/.copilot-instructions.md +0 -321
- package/.cursorrules +0 -321
- package/build/purchase-error.d.ts +0 -67
- package/build/purchase-error.d.ts.map +0 -1
- package/build/purchase-error.js +0 -166
- package/build/purchase-error.js.map +0 -1
- package/src/purchase-error.ts +0 -265
package/.cursorrules
DELETED
|
@@ -1,321 +0,0 @@
|
|
|
1
|
-
# GitHub Copilot and Cursor Rules for expo-iap
|
|
2
|
-
|
|
3
|
-
## Package Manager
|
|
4
|
-
|
|
5
|
-
**IMPORTANT: This project uses Bun exclusively. Do not suggest npm, yarn, or pnpm commands.**
|
|
6
|
-
|
|
7
|
-
- Install dependencies: `bun install`
|
|
8
|
-
- Run scripts: `bun run <script>`
|
|
9
|
-
- Run tests: `bun test`
|
|
10
|
-
- Add packages: `bun add <package>`
|
|
11
|
-
- Add dev dependencies: `bun add -d <package>`
|
|
12
|
-
|
|
13
|
-
**NEVER suggest creating package-lock.json or yarn.lock files. Only bun.lock should exist.**
|
|
14
|
-
|
|
15
|
-
## Platform-Specific Function Naming
|
|
16
|
-
|
|
17
|
-
When suggesting code for expo-iap, follow these naming conventions:
|
|
18
|
-
|
|
19
|
-
### Platform-Specific Functions
|
|
20
|
-
|
|
21
|
-
Functions that only work on one platform MUST have platform suffixes:
|
|
22
|
-
|
|
23
|
-
- iOS: `functionNameIOS()`
|
|
24
|
-
- Android: `functionNameAndroid()`
|
|
25
|
-
|
|
26
|
-
```typescript
|
|
27
|
-
// Correct examples:
|
|
28
|
-
export const getStorefrontIOS = async (): Promise<string> => { ... }
|
|
29
|
-
export const consumeProductAndroid = async (token: string): Promise<void> => { ... }
|
|
30
|
-
export const getAppTransactionIOS = async (): Promise<AppTransactionIOS | null> => { ... }
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### Cross-Platform Functions
|
|
34
|
-
|
|
35
|
-
Functions that abstract platform differences don't need suffixes:
|
|
36
|
-
|
|
37
|
-
```typescript
|
|
38
|
-
// Correct cross-platform example:
|
|
39
|
-
export const getProducts = async (skus: string[]): Promise<Product[]> => {
|
|
40
|
-
return Platform.select({
|
|
41
|
-
ios: async () => {
|
|
42
|
-
/* iOS implementation */
|
|
43
|
-
},
|
|
44
|
-
android: async () => {
|
|
45
|
-
/* Android implementation */
|
|
46
|
-
},
|
|
47
|
-
})();
|
|
48
|
-
};
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Project Overview
|
|
52
|
-
|
|
53
|
-
This is the **expo-iap** library - a modern React Native/Expo module for handling in-app purchases across iOS and Android platforms. The library provides a unified, TypeScript-first API with automatic type inference and platform abstraction.
|
|
54
|
-
|
|
55
|
-
## Key Principles
|
|
56
|
-
|
|
57
|
-
### 🎯 Modern TypeScript-First API
|
|
58
|
-
|
|
59
|
-
- **Automatic Type Inference**: No manual type casting required
|
|
60
|
-
- **Unified Platform API**: Single API that works across iOS and Android
|
|
61
|
-
- **Consistent Results**: Unified data structure regardless of platform
|
|
62
|
-
- **Clean Error Handling**: Result pattern with detailed error information
|
|
63
|
-
|
|
64
|
-
### 🚀 Primary API Pattern
|
|
65
|
-
|
|
66
|
-
```typescript
|
|
67
|
-
const result = await requestPurchase({
|
|
68
|
-
request: {sku: 'product.id'},
|
|
69
|
-
type: 'inapp',
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
if (result.success) {
|
|
73
|
-
console.log('Purchase successful:', result.transactionId);
|
|
74
|
-
} else {
|
|
75
|
-
console.error('Purchase failed:', result.error.message);
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### 🏗️ Code Style Guidelines
|
|
80
|
-
|
|
81
|
-
#### TypeScript Best Practices
|
|
82
|
-
|
|
83
|
-
- **Explicit Type Definitions**: Always define types explicitly for public APIs
|
|
84
|
-
- **Function Overloads**: Provide multiple signatures for better IntelliSense
|
|
85
|
-
- **Discriminated Unions**: Use for platform-specific types and conditional returns
|
|
86
|
-
- **Strict Type Safety**: No `any` types in production code
|
|
87
|
-
|
|
88
|
-
#### Naming Conventions
|
|
89
|
-
|
|
90
|
-
- **PascalCase**: Interfaces, types, enums, classes
|
|
91
|
-
- **camelCase**: Functions, variables, methods, properties
|
|
92
|
-
- **kebab-case**: File names (except for React components)
|
|
93
|
-
- **Descriptive Names**: Avoid abbreviations, use clear intent-revealing names
|
|
94
|
-
|
|
95
|
-
#### Error Handling Pattern
|
|
96
|
-
|
|
97
|
-
```typescript
|
|
98
|
-
type PurchaseResult<T = unknown> =
|
|
99
|
-
| {success: true; data: T; platform: 'ios' | 'android'}
|
|
100
|
-
| {success: false; error: PurchaseError; platform: 'ios' | 'android'};
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
## API Implementation Patterns
|
|
104
|
-
|
|
105
|
-
### Core Purchase Functions
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
export function requestPurchase(params: {
|
|
109
|
-
readonly request: {sku: string; quantity?: number};
|
|
110
|
-
readonly type: 'inapp';
|
|
111
|
-
}): Promise<ProductPurchase | ProductPurchase[]>;
|
|
112
|
-
|
|
113
|
-
export function requestSubscription(params: {
|
|
114
|
-
readonly request: {sku: string};
|
|
115
|
-
}): Promise<SubscriptionPurchase | SubscriptionPurchase[]>;
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### Platform Abstraction
|
|
119
|
-
|
|
120
|
-
The library automatically handles platform differences:
|
|
121
|
-
|
|
122
|
-
- **iOS**: Uses `sku` directly with StoreKit
|
|
123
|
-
- **Android**: Converts to Google Play Billing format
|
|
124
|
-
- **Unified Properties**: Both platforms return consistent data
|
|
125
|
-
|
|
126
|
-
### Type Guards for Advanced Usage
|
|
127
|
-
|
|
128
|
-
```typescript
|
|
129
|
-
export const isPurchaseResult = (
|
|
130
|
-
result: unknown,
|
|
131
|
-
): result is ProductPurchase | SubscriptionPurchase => {
|
|
132
|
-
return (
|
|
133
|
-
result !== null &&
|
|
134
|
-
typeof result === 'object' &&
|
|
135
|
-
'transactionId' in result &&
|
|
136
|
-
'productId' in result
|
|
137
|
-
);
|
|
138
|
-
};
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## File Organization
|
|
142
|
-
|
|
143
|
-
```
|
|
144
|
-
src/
|
|
145
|
-
├── index.ts # Main exports
|
|
146
|
-
├── ExpoIap.types.ts # Core type definitions
|
|
147
|
-
├── ExpoIapModule.ts # Native module interface
|
|
148
|
-
├── useIAP.ts # React hook (legacy support)
|
|
149
|
-
├── modules/
|
|
150
|
-
│ ├── android.ts # Android-specific utilities
|
|
151
|
-
│ └── ios.ts # iOS-specific utilities
|
|
152
|
-
└── types/
|
|
153
|
-
├── ExpoIapAndroid.types.ts # Android type definitions
|
|
154
|
-
└── ExpoIapIos.types.ts # iOS type definitions
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Usage Examples
|
|
158
|
-
|
|
159
|
-
### Simple Product Purchase
|
|
160
|
-
|
|
161
|
-
```typescript
|
|
162
|
-
import {requestPurchase} from 'expo-iap';
|
|
163
|
-
|
|
164
|
-
const handlePurchase = async (productId: string) => {
|
|
165
|
-
const result = await requestPurchase({
|
|
166
|
-
request: {sku: productId},
|
|
167
|
-
type: 'inapp',
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
if (result.success) {
|
|
171
|
-
console.log('Purchase successful:', result.data);
|
|
172
|
-
} else {
|
|
173
|
-
console.error('Purchase failed:', result.error.message);
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### Subscription Purchase
|
|
179
|
-
|
|
180
|
-
```typescript
|
|
181
|
-
import {requestSubscription} from 'expo-iap';
|
|
182
|
-
|
|
183
|
-
const handleSubscription = async (subscriptionId: string) => {
|
|
184
|
-
const result = await requestSubscription({
|
|
185
|
-
request: {sku: subscriptionId},
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
if (result.success) {
|
|
189
|
-
console.log('Subscription activated:', result.data);
|
|
190
|
-
} else {
|
|
191
|
-
console.error('Subscription failed:', result.error.message);
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
## Type Naming
|
|
197
|
-
|
|
198
|
-
- Platform-specific types: `ProductIOS`, `ProductAndroid`, `PurchaseErrorIOS`
|
|
199
|
-
- Cross-platform types: `Product`, `Purchase`, `PurchaseError`
|
|
200
|
-
|
|
201
|
-
## Code Suggestions
|
|
202
|
-
|
|
203
|
-
When generating code:
|
|
204
|
-
|
|
205
|
-
1. Check if the function is platform-specific
|
|
206
|
-
2. Add appropriate suffix if it only works on one platform
|
|
207
|
-
3. Use Platform.select() for cross-platform implementations
|
|
208
|
-
4. Always use TypeScript
|
|
209
|
-
5. Include proper error handling
|
|
210
|
-
6. Add JSDoc comments for public APIs
|
|
211
|
-
|
|
212
|
-
## Testing
|
|
213
|
-
|
|
214
|
-
Suggest tests that:
|
|
215
|
-
|
|
216
|
-
- Cover both iOS and Android paths
|
|
217
|
-
- Use `bun test` commands
|
|
218
|
-
- Include platform mocking when needed
|
|
219
|
-
- Test error scenarios
|
|
220
|
-
|
|
221
|
-
## Common Patterns
|
|
222
|
-
|
|
223
|
-
### Platform Selection
|
|
224
|
-
|
|
225
|
-
```typescript
|
|
226
|
-
Platform.select({
|
|
227
|
-
ios: () => {
|
|
228
|
-
/* iOS code */
|
|
229
|
-
},
|
|
230
|
-
android: () => {
|
|
231
|
-
/* Android code */
|
|
232
|
-
},
|
|
233
|
-
default: () => {
|
|
234
|
-
/* Fallback */
|
|
235
|
-
},
|
|
236
|
-
});
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
### Receipt Validation (Platform-specific parameters)
|
|
240
|
-
|
|
241
|
-
```typescript
|
|
242
|
-
// iOS only needs SKU
|
|
243
|
-
await validateReceiptIos(sku);
|
|
244
|
-
|
|
245
|
-
// Android needs additional parameters
|
|
246
|
-
await validateReceiptAndroid({
|
|
247
|
-
packageName,
|
|
248
|
-
productToken,
|
|
249
|
-
accessToken,
|
|
250
|
-
});
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
## Documentation Standards
|
|
254
|
-
|
|
255
|
-
### Code Comments
|
|
256
|
-
|
|
257
|
-
- **Document the "why"**, not just the "what"
|
|
258
|
-
- **Explain platform differences** and how they're handled
|
|
259
|
-
- **Provide usage examples** for complex APIs
|
|
260
|
-
- **Use JSDoc format** for all public APIs
|
|
261
|
-
|
|
262
|
-
### Example Documentation Pattern
|
|
263
|
-
|
|
264
|
-
````typescript
|
|
265
|
-
/**
|
|
266
|
-
* Enhanced requestPurchase with unified API support
|
|
267
|
-
*
|
|
268
|
-
* This function automatically handles platform differences:
|
|
269
|
-
* - iOS: Uses `sku` directly with StoreKit
|
|
270
|
-
* - Android: Converts to Google Play Billing format
|
|
271
|
-
*
|
|
272
|
-
* @param params - Purchase request parameters
|
|
273
|
-
* @param params.request - Request object with product details
|
|
274
|
-
* @param params.type - Purchase type: 'inapp' for products
|
|
275
|
-
*
|
|
276
|
-
* @returns Promise resolving to purchase result
|
|
277
|
-
*
|
|
278
|
-
* @example
|
|
279
|
-
* ```typescript
|
|
280
|
-
* const result = await requestPurchase({
|
|
281
|
-
* request: { sku: 'com.example.premium' },
|
|
282
|
-
* type: 'inapp'
|
|
283
|
-
* });
|
|
284
|
-
* ```
|
|
285
|
-
*/
|
|
286
|
-
````
|
|
287
|
-
|
|
288
|
-
## Development Philosophy
|
|
289
|
-
|
|
290
|
-
The expo-iap library provides a **world-class developer experience**:
|
|
291
|
-
|
|
292
|
-
### ✅ Core Achievements
|
|
293
|
-
|
|
294
|
-
- **🎯 Zero Manual Casting**: Automatic type inference
|
|
295
|
-
- **🌍 Unified API**: Single codebase for iOS and Android
|
|
296
|
-
- **⚡ Enhanced DX**: Better IntelliSense and error messages
|
|
297
|
-
- **🛡️ Full Backward Compatibility**: Existing code continues to work
|
|
298
|
-
- **📚 Modern Patterns**: TypeScript-first, result pattern error handling
|
|
299
|
-
|
|
300
|
-
### 🎯 When Contributing, Always Consider:
|
|
301
|
-
|
|
302
|
-
1. **Developer Experience First** - Eliminate manual work and reduce cognitive load
|
|
303
|
-
2. **Platform Differences** - Handle iOS/Android disparities transparently
|
|
304
|
-
3. **Type Safety** - Provide automatic inference with compile-time guarantees
|
|
305
|
-
4. **Documentation Excellence** - Explain the "why" behind solutions
|
|
306
|
-
5. **Backward Compatibility** - Never break existing code
|
|
307
|
-
6. **Performance** - Optimize for common use cases
|
|
308
|
-
7. **Testing** - Comprehensive coverage across platforms and scenarios
|
|
309
|
-
|
|
310
|
-
### 🚀 Ultimate Goal
|
|
311
|
-
|
|
312
|
-
Transform in-app purchases from a complex, error-prone process into something as simple as:
|
|
313
|
-
|
|
314
|
-
```typescript
|
|
315
|
-
const result = await requestPurchase({
|
|
316
|
-
request: {sku: 'premium.product'},
|
|
317
|
-
type: 'inapp',
|
|
318
|
-
});
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
While maintaining full power and flexibility for advanced enterprise use cases.
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { ErrorCode, IapPlatform } from './types';
|
|
2
|
-
/** Properties used to construct a {@link PurchaseError}. */
|
|
3
|
-
export interface PurchaseErrorProps {
|
|
4
|
-
message: string;
|
|
5
|
-
responseCode?: number;
|
|
6
|
-
debugMessage?: string;
|
|
7
|
-
code?: ErrorCode;
|
|
8
|
-
productId?: string;
|
|
9
|
-
platform?: IapPlatform;
|
|
10
|
-
}
|
|
11
|
-
/** Shape of raw platform error objects coming from native modules. */
|
|
12
|
-
type PlatformErrorData = {
|
|
13
|
-
code?: string | number;
|
|
14
|
-
message?: string;
|
|
15
|
-
responseCode?: number;
|
|
16
|
-
debugMessage?: string;
|
|
17
|
-
productId?: string;
|
|
18
|
-
};
|
|
19
|
-
/**
|
|
20
|
-
* Mapping between platforms and their canonical error codes.
|
|
21
|
-
* Values are platform-native string identifiers.
|
|
22
|
-
*/
|
|
23
|
-
export declare const ErrorCodeMapping: {
|
|
24
|
-
readonly ios: Record<ErrorCode, string>;
|
|
25
|
-
readonly android: Record<ErrorCode, string>;
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Error thrown by expo-iap when purchases fail.
|
|
29
|
-
*/
|
|
30
|
-
export declare class PurchaseError extends Error {
|
|
31
|
-
responseCode?: number;
|
|
32
|
-
debugMessage?: string;
|
|
33
|
-
code?: ErrorCode;
|
|
34
|
-
productId?: string;
|
|
35
|
-
platform?: IapPlatform;
|
|
36
|
-
constructor(message: string, responseCode?: number, debugMessage?: string, code?: ErrorCode, productId?: string, platform?: IapPlatform);
|
|
37
|
-
constructor(props: PurchaseErrorProps);
|
|
38
|
-
/**
|
|
39
|
-
* Create a {@link PurchaseError} from raw platform error data.
|
|
40
|
-
*/
|
|
41
|
-
static fromPlatformError(errorData: PlatformErrorData, platform: IapPlatform): PurchaseError;
|
|
42
|
-
/**
|
|
43
|
-
* Returns the platform specific error code for this instance.
|
|
44
|
-
*/
|
|
45
|
-
getPlatformCode(): string | number | undefined;
|
|
46
|
-
}
|
|
47
|
-
/** Utility helpers for translating error codes between platforms. */
|
|
48
|
-
export declare const ErrorCodeUtils: {
|
|
49
|
-
/**
|
|
50
|
-
* Returns the native error code for the provided {@link ErrorCode}.
|
|
51
|
-
*/
|
|
52
|
-
getNativeErrorCode: (errorCode: ErrorCode) => string;
|
|
53
|
-
/**
|
|
54
|
-
* Converts a platform-specific error code into a standardized {@link ErrorCode}.
|
|
55
|
-
*/
|
|
56
|
-
fromPlatformCode: (platformCode: string | number, _platform: IapPlatform) => ErrorCode;
|
|
57
|
-
/**
|
|
58
|
-
* Converts a standardized {@link ErrorCode} into its platform-specific value.
|
|
59
|
-
*/
|
|
60
|
-
toPlatformCode: (errorCode: ErrorCode, _platform: IapPlatform) => string | number;
|
|
61
|
-
/**
|
|
62
|
-
* Determines whether the error code is supported on the given platform.
|
|
63
|
-
*/
|
|
64
|
-
isValidForPlatform: (errorCode: ErrorCode, platform: IapPlatform) => boolean;
|
|
65
|
-
};
|
|
66
|
-
export {};
|
|
67
|
-
//# sourceMappingURL=purchase-error.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"purchase-error.d.ts","sourceRoot":"","sources":["../src/purchase-error.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,SAAS,EAAE,WAAW,EAAC,MAAM,SAAS,CAAC;AAE/C,4DAA4D;AAC5D,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,WAAW,CAAC;CACxB;AAED,sEAAsE;AACtE,KAAK,iBAAiB,GAAG;IACvB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAiEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;CAGnB,CAAC;AAEX;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,WAAW,CAAC;gBAG5B,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,SAAS,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,WAAW;gBAEZ,KAAK,EAAE,kBAAkB;IAgCrC;;OAEG;IACH,MAAM,CAAC,iBAAiB,CACtB,SAAS,EAAE,iBAAiB,EAC5B,QAAQ,EAAE,WAAW,GACpB,aAAa;IAiBhB;;OAEG;IACH,eAAe,IAAI,MAAM,GAAG,MAAM,GAAG,SAAS;CAM/C;AAED,qEAAqE;AACrE,eAAO,MAAM,cAAc;IACzB;;OAEG;oCAC6B,SAAS,KAAG,MAAM;IAQlD;;OAEG;qCAEa,MAAM,GAAG,MAAM,aAClB,WAAW,KACrB,SAAS;IAsCZ;;OAEG;gCAEU,SAAS,aACT,WAAW,KACrB,MAAM,GAAG,MAAM;IAOlB;;OAEG;oCAEU,SAAS,YACV,WAAW,KACpB,OAAO;CAUX,CAAC"}
|
package/build/purchase-error.js
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import { NATIVE_ERROR_CODES } from './ExpoIapModule';
|
|
2
|
-
import { ErrorCode } from './types';
|
|
3
|
-
const toStandardizedCode = (errorCode) => errorCode.startsWith('E_') ? errorCode : `E_${errorCode}`;
|
|
4
|
-
const normalizePlatform = (platform) => typeof platform === 'string' && platform.toLowerCase() === 'ios'
|
|
5
|
-
? 'ios'
|
|
6
|
-
: 'android';
|
|
7
|
-
const OPENIAP_ERROR_CODE_SET = new Set(Object.values(ErrorCode).map((code) => toStandardizedCode(code)));
|
|
8
|
-
const COMMON_ERROR_CODE_MAP = {
|
|
9
|
-
[ErrorCode.Unknown]: toStandardizedCode(ErrorCode.Unknown),
|
|
10
|
-
[ErrorCode.UserCancelled]: toStandardizedCode(ErrorCode.UserCancelled),
|
|
11
|
-
[ErrorCode.UserError]: toStandardizedCode(ErrorCode.UserError),
|
|
12
|
-
[ErrorCode.ItemUnavailable]: toStandardizedCode(ErrorCode.ItemUnavailable),
|
|
13
|
-
[ErrorCode.RemoteError]: toStandardizedCode(ErrorCode.RemoteError),
|
|
14
|
-
[ErrorCode.NetworkError]: toStandardizedCode(ErrorCode.NetworkError),
|
|
15
|
-
[ErrorCode.ServiceError]: toStandardizedCode(ErrorCode.ServiceError),
|
|
16
|
-
[ErrorCode.ReceiptFailed]: toStandardizedCode(ErrorCode.ReceiptFailed),
|
|
17
|
-
[ErrorCode.ReceiptFinished]: toStandardizedCode(ErrorCode.ReceiptFinished),
|
|
18
|
-
[ErrorCode.ReceiptFinishedFailed]: toStandardizedCode(ErrorCode.ReceiptFinishedFailed),
|
|
19
|
-
[ErrorCode.NotPrepared]: toStandardizedCode(ErrorCode.NotPrepared),
|
|
20
|
-
[ErrorCode.NotEnded]: toStandardizedCode(ErrorCode.NotEnded),
|
|
21
|
-
[ErrorCode.AlreadyOwned]: toStandardizedCode(ErrorCode.AlreadyOwned),
|
|
22
|
-
[ErrorCode.DeveloperError]: toStandardizedCode(ErrorCode.DeveloperError),
|
|
23
|
-
[ErrorCode.BillingResponseJsonParseError]: toStandardizedCode(ErrorCode.BillingResponseJsonParseError),
|
|
24
|
-
[ErrorCode.DeferredPayment]: toStandardizedCode(ErrorCode.DeferredPayment),
|
|
25
|
-
[ErrorCode.Interrupted]: toStandardizedCode(ErrorCode.Interrupted),
|
|
26
|
-
[ErrorCode.IapNotAvailable]: toStandardizedCode(ErrorCode.IapNotAvailable),
|
|
27
|
-
[ErrorCode.PurchaseError]: toStandardizedCode(ErrorCode.PurchaseError),
|
|
28
|
-
[ErrorCode.SyncError]: toStandardizedCode(ErrorCode.SyncError),
|
|
29
|
-
[ErrorCode.TransactionValidationFailed]: toStandardizedCode(ErrorCode.TransactionValidationFailed),
|
|
30
|
-
[ErrorCode.ActivityUnavailable]: toStandardizedCode(ErrorCode.ActivityUnavailable),
|
|
31
|
-
[ErrorCode.AlreadyPrepared]: toStandardizedCode(ErrorCode.AlreadyPrepared),
|
|
32
|
-
[ErrorCode.Pending]: toStandardizedCode(ErrorCode.Pending),
|
|
33
|
-
[ErrorCode.ConnectionClosed]: toStandardizedCode(ErrorCode.ConnectionClosed),
|
|
34
|
-
[ErrorCode.InitConnection]: toStandardizedCode(ErrorCode.InitConnection),
|
|
35
|
-
[ErrorCode.ServiceDisconnected]: toStandardizedCode(ErrorCode.ServiceDisconnected),
|
|
36
|
-
[ErrorCode.QueryProduct]: toStandardizedCode(ErrorCode.QueryProduct),
|
|
37
|
-
[ErrorCode.SkuNotFound]: toStandardizedCode(ErrorCode.SkuNotFound),
|
|
38
|
-
[ErrorCode.SkuOfferMismatch]: toStandardizedCode(ErrorCode.SkuOfferMismatch),
|
|
39
|
-
[ErrorCode.ItemNotOwned]: toStandardizedCode(ErrorCode.ItemNotOwned),
|
|
40
|
-
[ErrorCode.BillingUnavailable]: toStandardizedCode(ErrorCode.BillingUnavailable),
|
|
41
|
-
[ErrorCode.FeatureNotSupported]: toStandardizedCode(ErrorCode.FeatureNotSupported),
|
|
42
|
-
[ErrorCode.EmptySkuList]: toStandardizedCode(ErrorCode.EmptySkuList),
|
|
43
|
-
};
|
|
44
|
-
/**
|
|
45
|
-
* Mapping between platforms and their canonical error codes.
|
|
46
|
-
* Values are platform-native string identifiers.
|
|
47
|
-
*/
|
|
48
|
-
export const ErrorCodeMapping = {
|
|
49
|
-
ios: COMMON_ERROR_CODE_MAP,
|
|
50
|
-
android: COMMON_ERROR_CODE_MAP,
|
|
51
|
-
};
|
|
52
|
-
/**
|
|
53
|
-
* Error thrown by expo-iap when purchases fail.
|
|
54
|
-
*/
|
|
55
|
-
export class PurchaseError extends Error {
|
|
56
|
-
responseCode;
|
|
57
|
-
debugMessage;
|
|
58
|
-
code;
|
|
59
|
-
productId;
|
|
60
|
-
platform;
|
|
61
|
-
constructor(messageOrProps, responseCode, debugMessage, code, productId, platform) {
|
|
62
|
-
super(typeof messageOrProps === 'string'
|
|
63
|
-
? messageOrProps
|
|
64
|
-
: messageOrProps.message);
|
|
65
|
-
this.name = '[expo-iap]: PurchaseError';
|
|
66
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
67
|
-
if (typeof messageOrProps === 'string') {
|
|
68
|
-
this.responseCode = responseCode;
|
|
69
|
-
this.debugMessage = debugMessage;
|
|
70
|
-
this.code = code;
|
|
71
|
-
this.productId = productId;
|
|
72
|
-
this.platform = platform;
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
this.responseCode = messageOrProps.responseCode;
|
|
76
|
-
this.debugMessage = messageOrProps.debugMessage;
|
|
77
|
-
this.code = messageOrProps.code;
|
|
78
|
-
this.productId = messageOrProps.productId;
|
|
79
|
-
this.platform = messageOrProps.platform;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Create a {@link PurchaseError} from raw platform error data.
|
|
84
|
-
*/
|
|
85
|
-
static fromPlatformError(errorData, platform) {
|
|
86
|
-
const normalizedPlatform = normalizePlatform(platform);
|
|
87
|
-
const errorCode = errorData.code
|
|
88
|
-
? ErrorCodeUtils.fromPlatformCode(errorData.code, normalizedPlatform)
|
|
89
|
-
: ErrorCode.Unknown;
|
|
90
|
-
return new PurchaseError({
|
|
91
|
-
message: errorData.message ?? 'Unknown error occurred',
|
|
92
|
-
responseCode: errorData.responseCode,
|
|
93
|
-
debugMessage: errorData.debugMessage,
|
|
94
|
-
code: errorCode,
|
|
95
|
-
productId: errorData.productId,
|
|
96
|
-
platform,
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Returns the platform specific error code for this instance.
|
|
101
|
-
*/
|
|
102
|
-
getPlatformCode() {
|
|
103
|
-
if (!this.code || !this.platform) {
|
|
104
|
-
return undefined;
|
|
105
|
-
}
|
|
106
|
-
return ErrorCodeUtils.toPlatformCode(this.code, this.platform);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
/** Utility helpers for translating error codes between platforms. */
|
|
110
|
-
export const ErrorCodeUtils = {
|
|
111
|
-
/**
|
|
112
|
-
* Returns the native error code for the provided {@link ErrorCode}.
|
|
113
|
-
*/
|
|
114
|
-
getNativeErrorCode: (errorCode) => {
|
|
115
|
-
const standardized = toStandardizedCode(errorCode);
|
|
116
|
-
return (NATIVE_ERROR_CODES[standardized] ?? standardized);
|
|
117
|
-
},
|
|
118
|
-
/**
|
|
119
|
-
* Converts a platform-specific error code into a standardized {@link ErrorCode}.
|
|
120
|
-
*/
|
|
121
|
-
fromPlatformCode: (platformCode, _platform) => {
|
|
122
|
-
if (typeof platformCode === 'string' && platformCode.startsWith('E_')) {
|
|
123
|
-
if (OPENIAP_ERROR_CODE_SET.has(platformCode)) {
|
|
124
|
-
const match = Object.entries(COMMON_ERROR_CODE_MAP).find(([, value]) => value === platformCode);
|
|
125
|
-
if (match) {
|
|
126
|
-
return match[0];
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
for (const [standardized, nativeCode] of Object.entries((NATIVE_ERROR_CODES || {}))) {
|
|
131
|
-
if (nativeCode === platformCode &&
|
|
132
|
-
OPENIAP_ERROR_CODE_SET.has(standardized)) {
|
|
133
|
-
const match = Object.entries(COMMON_ERROR_CODE_MAP).find(([, mappedCode]) => mappedCode === standardized);
|
|
134
|
-
if (match) {
|
|
135
|
-
return match[0];
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
for (const [errorCode, mappedCode] of Object.entries(COMMON_ERROR_CODE_MAP)) {
|
|
140
|
-
if (mappedCode === platformCode) {
|
|
141
|
-
return errorCode;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
return ErrorCode.Unknown;
|
|
145
|
-
},
|
|
146
|
-
/**
|
|
147
|
-
* Converts a standardized {@link ErrorCode} into its platform-specific value.
|
|
148
|
-
*/
|
|
149
|
-
toPlatformCode: (errorCode, _platform) => {
|
|
150
|
-
const standardized = toStandardizedCode(errorCode);
|
|
151
|
-
const native = NATIVE_ERROR_CODES[standardized];
|
|
152
|
-
return native ?? COMMON_ERROR_CODE_MAP[errorCode] ?? 'E_UNKNOWN';
|
|
153
|
-
},
|
|
154
|
-
/**
|
|
155
|
-
* Determines whether the error code is supported on the given platform.
|
|
156
|
-
*/
|
|
157
|
-
isValidForPlatform: (errorCode, platform) => {
|
|
158
|
-
const standardized = toStandardizedCode(errorCode);
|
|
159
|
-
if (NATIVE_ERROR_CODES[standardized] !==
|
|
160
|
-
undefined) {
|
|
161
|
-
return true;
|
|
162
|
-
}
|
|
163
|
-
return standardized in ErrorCodeMapping[normalizePlatform(platform)];
|
|
164
|
-
},
|
|
165
|
-
};
|
|
166
|
-
//# sourceMappingURL=purchase-error.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"purchase-error.js","sourceRoot":"","sources":["../src/purchase-error.ts"],"names":[],"mappings":"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","sourcesContent":["import {NATIVE_ERROR_CODES} from './ExpoIapModule';\nimport {ErrorCode, IapPlatform} from './types';\n\n/** Properties used to construct a {@link PurchaseError}. */\nexport interface PurchaseErrorProps {\n message: string;\n responseCode?: number;\n debugMessage?: string;\n code?: ErrorCode;\n productId?: string;\n platform?: IapPlatform;\n}\n\n/** Shape of raw platform error objects coming from native modules. */\ntype PlatformErrorData = {\n code?: string | number;\n message?: string;\n responseCode?: number;\n debugMessage?: string;\n productId?: string;\n};\n\nconst toStandardizedCode = (errorCode: ErrorCode): string =>\n errorCode.startsWith('E_') ? errorCode : `E_${errorCode}`;\n\nconst normalizePlatform = (platform: IapPlatform): 'ios' | 'android' =>\n typeof platform === 'string' && platform.toLowerCase() === 'ios'\n ? 'ios'\n : 'android';\n\nconst OPENIAP_ERROR_CODE_SET: Set<string> = new Set(\n Object.values(ErrorCode).map((code) => toStandardizedCode(code)),\n);\n\nconst COMMON_ERROR_CODE_MAP: Record<ErrorCode, string> = {\n [ErrorCode.Unknown]: toStandardizedCode(ErrorCode.Unknown),\n [ErrorCode.UserCancelled]: toStandardizedCode(ErrorCode.UserCancelled),\n [ErrorCode.UserError]: toStandardizedCode(ErrorCode.UserError),\n [ErrorCode.ItemUnavailable]: toStandardizedCode(ErrorCode.ItemUnavailable),\n [ErrorCode.RemoteError]: toStandardizedCode(ErrorCode.RemoteError),\n [ErrorCode.NetworkError]: toStandardizedCode(ErrorCode.NetworkError),\n [ErrorCode.ServiceError]: toStandardizedCode(ErrorCode.ServiceError),\n [ErrorCode.ReceiptFailed]: toStandardizedCode(ErrorCode.ReceiptFailed),\n [ErrorCode.ReceiptFinished]: toStandardizedCode(ErrorCode.ReceiptFinished),\n [ErrorCode.ReceiptFinishedFailed]: toStandardizedCode(\n ErrorCode.ReceiptFinishedFailed,\n ),\n [ErrorCode.NotPrepared]: toStandardizedCode(ErrorCode.NotPrepared),\n [ErrorCode.NotEnded]: toStandardizedCode(ErrorCode.NotEnded),\n [ErrorCode.AlreadyOwned]: toStandardizedCode(ErrorCode.AlreadyOwned),\n [ErrorCode.DeveloperError]: toStandardizedCode(ErrorCode.DeveloperError),\n [ErrorCode.BillingResponseJsonParseError]: toStandardizedCode(\n ErrorCode.BillingResponseJsonParseError,\n ),\n [ErrorCode.DeferredPayment]: toStandardizedCode(ErrorCode.DeferredPayment),\n [ErrorCode.Interrupted]: toStandardizedCode(ErrorCode.Interrupted),\n [ErrorCode.IapNotAvailable]: toStandardizedCode(ErrorCode.IapNotAvailable),\n [ErrorCode.PurchaseError]: toStandardizedCode(ErrorCode.PurchaseError),\n [ErrorCode.SyncError]: toStandardizedCode(ErrorCode.SyncError),\n [ErrorCode.TransactionValidationFailed]: toStandardizedCode(\n ErrorCode.TransactionValidationFailed,\n ),\n [ErrorCode.ActivityUnavailable]: toStandardizedCode(\n ErrorCode.ActivityUnavailable,\n ),\n [ErrorCode.AlreadyPrepared]: toStandardizedCode(ErrorCode.AlreadyPrepared),\n [ErrorCode.Pending]: toStandardizedCode(ErrorCode.Pending),\n [ErrorCode.ConnectionClosed]: toStandardizedCode(ErrorCode.ConnectionClosed),\n [ErrorCode.InitConnection]: toStandardizedCode(ErrorCode.InitConnection),\n [ErrorCode.ServiceDisconnected]: toStandardizedCode(\n ErrorCode.ServiceDisconnected,\n ),\n [ErrorCode.QueryProduct]: toStandardizedCode(ErrorCode.QueryProduct),\n [ErrorCode.SkuNotFound]: toStandardizedCode(ErrorCode.SkuNotFound),\n [ErrorCode.SkuOfferMismatch]: toStandardizedCode(ErrorCode.SkuOfferMismatch),\n [ErrorCode.ItemNotOwned]: toStandardizedCode(ErrorCode.ItemNotOwned),\n [ErrorCode.BillingUnavailable]: toStandardizedCode(\n ErrorCode.BillingUnavailable,\n ),\n [ErrorCode.FeatureNotSupported]: toStandardizedCode(\n ErrorCode.FeatureNotSupported,\n ),\n [ErrorCode.EmptySkuList]: toStandardizedCode(ErrorCode.EmptySkuList),\n};\n\n/**\n * Mapping between platforms and their canonical error codes.\n * Values are platform-native string identifiers.\n */\nexport const ErrorCodeMapping = {\n ios: COMMON_ERROR_CODE_MAP,\n android: COMMON_ERROR_CODE_MAP,\n} as const;\n\n/**\n * Error thrown by expo-iap when purchases fail.\n */\nexport class PurchaseError extends Error {\n public responseCode?: number;\n public debugMessage?: string;\n public code?: ErrorCode;\n public productId?: string;\n public platform?: IapPlatform;\n\n constructor(\n message: string,\n responseCode?: number,\n debugMessage?: string,\n code?: ErrorCode,\n productId?: string,\n platform?: IapPlatform,\n );\n constructor(props: PurchaseErrorProps);\n constructor(\n messageOrProps: string | PurchaseErrorProps,\n responseCode?: number,\n debugMessage?: string,\n code?: ErrorCode,\n productId?: string,\n platform?: IapPlatform,\n ) {\n super(\n typeof messageOrProps === 'string'\n ? messageOrProps\n : messageOrProps.message,\n );\n this.name = '[expo-iap]: PurchaseError';\n Object.setPrototypeOf(this, new.target.prototype);\n\n if (typeof messageOrProps === 'string') {\n this.responseCode = responseCode;\n this.debugMessage = debugMessage;\n this.code = code;\n this.productId = productId;\n this.platform = platform;\n } else {\n this.responseCode = messageOrProps.responseCode;\n this.debugMessage = messageOrProps.debugMessage;\n this.code = messageOrProps.code;\n this.productId = messageOrProps.productId;\n this.platform = messageOrProps.platform;\n }\n }\n\n /**\n * Create a {@link PurchaseError} from raw platform error data.\n */\n static fromPlatformError(\n errorData: PlatformErrorData,\n platform: IapPlatform,\n ): PurchaseError {\n const normalizedPlatform = normalizePlatform(platform);\n\n const errorCode = errorData.code\n ? ErrorCodeUtils.fromPlatformCode(errorData.code, normalizedPlatform)\n : ErrorCode.Unknown;\n\n return new PurchaseError({\n message: errorData.message ?? 'Unknown error occurred',\n responseCode: errorData.responseCode,\n debugMessage: errorData.debugMessage,\n code: errorCode,\n productId: errorData.productId,\n platform,\n });\n }\n\n /**\n * Returns the platform specific error code for this instance.\n */\n getPlatformCode(): string | number | undefined {\n if (!this.code || !this.platform) {\n return undefined;\n }\n return ErrorCodeUtils.toPlatformCode(this.code, this.platform);\n }\n}\n\n/** Utility helpers for translating error codes between platforms. */\nexport const ErrorCodeUtils = {\n /**\n * Returns the native error code for the provided {@link ErrorCode}.\n */\n getNativeErrorCode: (errorCode: ErrorCode): string => {\n const standardized = toStandardizedCode(errorCode);\n return (\n (NATIVE_ERROR_CODES as Record<string, string | undefined>)[\n standardized\n ] ?? standardized\n );\n },\n /**\n * Converts a platform-specific error code into a standardized {@link ErrorCode}.\n */\n fromPlatformCode: (\n platformCode: string | number,\n _platform: IapPlatform,\n ): ErrorCode => {\n if (typeof platformCode === 'string' && platformCode.startsWith('E_')) {\n if (OPENIAP_ERROR_CODE_SET.has(platformCode)) {\n const match = Object.entries(COMMON_ERROR_CODE_MAP).find(\n ([, value]) => value === platformCode,\n );\n if (match) {\n return match[0] as ErrorCode;\n }\n }\n }\n\n for (const [standardized, nativeCode] of Object.entries(\n (NATIVE_ERROR_CODES || {}) as Record<string, string | number>,\n )) {\n if (\n nativeCode === platformCode &&\n OPENIAP_ERROR_CODE_SET.has(standardized)\n ) {\n const match = Object.entries(COMMON_ERROR_CODE_MAP).find(\n ([, mappedCode]) => mappedCode === standardized,\n );\n if (match) {\n return match[0] as ErrorCode;\n }\n }\n }\n\n for (const [errorCode, mappedCode] of Object.entries(\n COMMON_ERROR_CODE_MAP,\n )) {\n if (mappedCode === platformCode) {\n return errorCode as ErrorCode;\n }\n }\n\n return ErrorCode.Unknown;\n },\n /**\n * Converts a standardized {@link ErrorCode} into its platform-specific value.\n */\n toPlatformCode: (\n errorCode: ErrorCode,\n _platform: IapPlatform,\n ): string | number => {\n const standardized = toStandardizedCode(errorCode);\n const native = (NATIVE_ERROR_CODES as Record<string, string | number>)[\n standardized\n ];\n return native ?? COMMON_ERROR_CODE_MAP[errorCode] ?? 'E_UNKNOWN';\n },\n /**\n * Determines whether the error code is supported on the given platform.\n */\n isValidForPlatform: (\n errorCode: ErrorCode,\n platform: IapPlatform,\n ): boolean => {\n const standardized = toStandardizedCode(errorCode);\n if (\n (NATIVE_ERROR_CODES as Record<string, unknown>)[standardized] !==\n undefined\n ) {\n return true;\n }\n return standardized in ErrorCodeMapping[normalizePlatform(platform)];\n },\n};\n"]}
|