expo-iap 3.0.8 → 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 +2 -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 +20 -47
- package/build/index.d.ts.map +1 -1
- package/build/index.js +94 -137
- package/build/index.js.map +1 -1
- package/build/modules/android.d.ts.map +1 -1
- package/build/modules/android.js +2 -1
- package/build/modules/android.js.map +1 -1
- package/build/modules/ios.d.ts +16 -1
- package/build/modules/ios.d.ts.map +1 -1
- package/build/modules/ios.js +29 -16
- package/build/modules/ios.js.map +1 -1
- package/build/types.d.ts +8 -6
- package/build/types.d.ts.map +1 -1
- package/build/types.js.map +1 -1
- package/build/useIAP.d.ts +1 -1
- package/build/useIAP.d.ts.map +1 -1
- package/build/useIAP.js +12 -15
- 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 +122 -165
- package/src/modules/android.ts +2 -1
- package/src/modules/ios.ts +31 -19
- package/src/types.ts +8 -6
- package/src/useIAP.ts +17 -25
- package/src/utils/errorMapping.ts +203 -23
- 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/build/utils/purchase.d.ts +0 -9
- package/build/utils/purchase.d.ts.map +0 -1
- package/build/utils/purchase.js +0 -34
- package/build/utils/purchase.js.map +0 -1
- package/src/purchase-error.ts +0 -265
- package/src/utils/purchase.ts +0 -52
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"]}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { Purchase } from '../types';
|
|
2
|
-
/**
|
|
3
|
-
* Normalizes purchase identifiers so `id` reflects the transaction identifier (if present).
|
|
4
|
-
* Falls back to the existing `id` when no transaction identifier is available.
|
|
5
|
-
*/
|
|
6
|
-
export declare const normalizePurchaseId: <T extends Purchase | null | undefined>(purchase: T) => T;
|
|
7
|
-
export declare const normalizePurchaseList: <T extends Purchase>(purchases: T[] | null | undefined) => T[];
|
|
8
|
-
export declare const normalizePurchasePayload: <T extends Purchase | null | undefined>(payload: T | T[] | null | undefined) => typeof payload;
|
|
9
|
-
//# sourceMappingURL=purchase.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"purchase.d.ts","sourceRoot":"","sources":["../../src/utils/purchase.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,UAAU,CAAC;AAKvC;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,QAAQ,GAAG,IAAI,GAAG,SAAS,EACvE,UAAU,CAAC,KACV,CAeF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,QAAQ,EACtD,WAAW,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,KAChC,CAAC,EAUH,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,CAAC,SAAS,QAAQ,GAAG,IAAI,GAAG,SAAS,EAC5E,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,KAClC,OAAO,OAOT,CAAC"}
|
package/build/utils/purchase.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
const isPurchaseObject = (value) => Boolean(value) && typeof value === 'object';
|
|
2
|
-
/**
|
|
3
|
-
* Normalizes purchase identifiers so `id` reflects the transaction identifier (if present).
|
|
4
|
-
* Falls back to the existing `id` when no transaction identifier is available.
|
|
5
|
-
*/
|
|
6
|
-
export const normalizePurchaseId = (purchase) => {
|
|
7
|
-
if (!isPurchaseObject(purchase)) {
|
|
8
|
-
return purchase;
|
|
9
|
-
}
|
|
10
|
-
const transactionId = purchase.transactionId;
|
|
11
|
-
if (typeof transactionId !== 'string' || transactionId.length === 0) {
|
|
12
|
-
return purchase;
|
|
13
|
-
}
|
|
14
|
-
if (purchase.id === transactionId) {
|
|
15
|
-
return purchase;
|
|
16
|
-
}
|
|
17
|
-
return { ...purchase, id: transactionId };
|
|
18
|
-
};
|
|
19
|
-
export const normalizePurchaseList = (purchases) => {
|
|
20
|
-
if (!Array.isArray(purchases)) {
|
|
21
|
-
return purchases ?? [];
|
|
22
|
-
}
|
|
23
|
-
if (purchases.length === 0) {
|
|
24
|
-
return purchases;
|
|
25
|
-
}
|
|
26
|
-
return purchases.map((purchase) => normalizePurchaseId(purchase));
|
|
27
|
-
};
|
|
28
|
-
export const normalizePurchasePayload = (payload) => {
|
|
29
|
-
if (Array.isArray(payload)) {
|
|
30
|
-
return payload.map((purchase) => normalizePurchaseId(purchase));
|
|
31
|
-
}
|
|
32
|
-
return normalizePurchaseId(payload);
|
|
33
|
-
};
|
|
34
|
-
//# sourceMappingURL=purchase.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"purchase.js","sourceRoot":"","sources":["../../src/utils/purchase.ts"],"names":[],"mappings":"AAEA,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAAoC,EAAE,CAC5E,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC;AAE9C;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,QAAW,EACR,EAAE;IACL,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,aAAa,GAAI,QAAoC,CAAC,aAAa,CAAC;IAC1E,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpE,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,QAAQ,CAAC,EAAE,KAAK,aAAa,EAAE,CAAC;QAClC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO,EAAC,GAAG,QAAQ,EAAE,EAAE,EAAE,aAAa,EAAM,CAAC;AAC/C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,SAAiC,EAC5B,EAAE;IACP,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,OAAO,SAAS,IAAI,EAAE,CAAC;IACzB,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAQ,CAAC;AAC3E,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,OAAmC,EACnB,EAAE;IAClB,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC9B,mBAAmB,CAAC,QAAQ,CAAC,CACZ,CAAC;IACtB,CAAC;IACD,OAAO,mBAAmB,CAAC,OAAY,CAAmB,CAAC;AAC7D,CAAC,CAAC","sourcesContent":["import type {Purchase} from '../types';\n\nconst isPurchaseObject = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === 'object';\n\n/**\n * Normalizes purchase identifiers so `id` reflects the transaction identifier (if present).\n * Falls back to the existing `id` when no transaction identifier is available.\n */\nexport const normalizePurchaseId = <T extends Purchase | null | undefined>(\n purchase: T,\n): T => {\n if (!isPurchaseObject(purchase)) {\n return purchase;\n }\n\n const transactionId = (purchase as Record<string, unknown>).transactionId;\n if (typeof transactionId !== 'string' || transactionId.length === 0) {\n return purchase;\n }\n\n if (purchase.id === transactionId) {\n return purchase;\n }\n\n return {...purchase, id: transactionId} as T;\n};\n\nexport const normalizePurchaseList = <T extends Purchase>(\n purchases: T[] | null | undefined,\n): T[] => {\n if (!Array.isArray(purchases)) {\n return purchases ?? [];\n }\n\n if (purchases.length === 0) {\n return purchases;\n }\n\n return purchases.map((purchase) => normalizePurchaseId(purchase)) as T[];\n};\n\nexport const normalizePurchasePayload = <T extends Purchase | null | undefined>(\n payload: T | T[] | null | undefined,\n): typeof payload => {\n if (Array.isArray(payload)) {\n return payload.map((purchase) =>\n normalizePurchaseId(purchase),\n ) as typeof payload;\n }\n return normalizePurchaseId(payload as T) as typeof payload;\n};\n"]}
|
package/src/purchase-error.ts
DELETED
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
import {NATIVE_ERROR_CODES} from './ExpoIapModule';
|
|
2
|
-
import {ErrorCode, IapPlatform} from './types';
|
|
3
|
-
|
|
4
|
-
/** Properties used to construct a {@link PurchaseError}. */
|
|
5
|
-
export interface PurchaseErrorProps {
|
|
6
|
-
message: string;
|
|
7
|
-
responseCode?: number;
|
|
8
|
-
debugMessage?: string;
|
|
9
|
-
code?: ErrorCode;
|
|
10
|
-
productId?: string;
|
|
11
|
-
platform?: IapPlatform;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/** Shape of raw platform error objects coming from native modules. */
|
|
15
|
-
type PlatformErrorData = {
|
|
16
|
-
code?: string | number;
|
|
17
|
-
message?: string;
|
|
18
|
-
responseCode?: number;
|
|
19
|
-
debugMessage?: string;
|
|
20
|
-
productId?: string;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const toStandardizedCode = (errorCode: ErrorCode): string =>
|
|
24
|
-
errorCode.startsWith('E_') ? errorCode : `E_${errorCode}`;
|
|
25
|
-
|
|
26
|
-
const normalizePlatform = (platform: IapPlatform): 'ios' | 'android' =>
|
|
27
|
-
typeof platform === 'string' && platform.toLowerCase() === 'ios'
|
|
28
|
-
? 'ios'
|
|
29
|
-
: 'android';
|
|
30
|
-
|
|
31
|
-
const OPENIAP_ERROR_CODE_SET: Set<string> = new Set(
|
|
32
|
-
Object.values(ErrorCode).map((code) => toStandardizedCode(code)),
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
const COMMON_ERROR_CODE_MAP: Record<ErrorCode, string> = {
|
|
36
|
-
[ErrorCode.Unknown]: toStandardizedCode(ErrorCode.Unknown),
|
|
37
|
-
[ErrorCode.UserCancelled]: toStandardizedCode(ErrorCode.UserCancelled),
|
|
38
|
-
[ErrorCode.UserError]: toStandardizedCode(ErrorCode.UserError),
|
|
39
|
-
[ErrorCode.ItemUnavailable]: toStandardizedCode(ErrorCode.ItemUnavailable),
|
|
40
|
-
[ErrorCode.RemoteError]: toStandardizedCode(ErrorCode.RemoteError),
|
|
41
|
-
[ErrorCode.NetworkError]: toStandardizedCode(ErrorCode.NetworkError),
|
|
42
|
-
[ErrorCode.ServiceError]: toStandardizedCode(ErrorCode.ServiceError),
|
|
43
|
-
[ErrorCode.ReceiptFailed]: toStandardizedCode(ErrorCode.ReceiptFailed),
|
|
44
|
-
[ErrorCode.ReceiptFinished]: toStandardizedCode(ErrorCode.ReceiptFinished),
|
|
45
|
-
[ErrorCode.ReceiptFinishedFailed]: toStandardizedCode(
|
|
46
|
-
ErrorCode.ReceiptFinishedFailed,
|
|
47
|
-
),
|
|
48
|
-
[ErrorCode.NotPrepared]: toStandardizedCode(ErrorCode.NotPrepared),
|
|
49
|
-
[ErrorCode.NotEnded]: toStandardizedCode(ErrorCode.NotEnded),
|
|
50
|
-
[ErrorCode.AlreadyOwned]: toStandardizedCode(ErrorCode.AlreadyOwned),
|
|
51
|
-
[ErrorCode.DeveloperError]: toStandardizedCode(ErrorCode.DeveloperError),
|
|
52
|
-
[ErrorCode.BillingResponseJsonParseError]: toStandardizedCode(
|
|
53
|
-
ErrorCode.BillingResponseJsonParseError,
|
|
54
|
-
),
|
|
55
|
-
[ErrorCode.DeferredPayment]: toStandardizedCode(ErrorCode.DeferredPayment),
|
|
56
|
-
[ErrorCode.Interrupted]: toStandardizedCode(ErrorCode.Interrupted),
|
|
57
|
-
[ErrorCode.IapNotAvailable]: toStandardizedCode(ErrorCode.IapNotAvailable),
|
|
58
|
-
[ErrorCode.PurchaseError]: toStandardizedCode(ErrorCode.PurchaseError),
|
|
59
|
-
[ErrorCode.SyncError]: toStandardizedCode(ErrorCode.SyncError),
|
|
60
|
-
[ErrorCode.TransactionValidationFailed]: toStandardizedCode(
|
|
61
|
-
ErrorCode.TransactionValidationFailed,
|
|
62
|
-
),
|
|
63
|
-
[ErrorCode.ActivityUnavailable]: toStandardizedCode(
|
|
64
|
-
ErrorCode.ActivityUnavailable,
|
|
65
|
-
),
|
|
66
|
-
[ErrorCode.AlreadyPrepared]: toStandardizedCode(ErrorCode.AlreadyPrepared),
|
|
67
|
-
[ErrorCode.Pending]: toStandardizedCode(ErrorCode.Pending),
|
|
68
|
-
[ErrorCode.ConnectionClosed]: toStandardizedCode(ErrorCode.ConnectionClosed),
|
|
69
|
-
[ErrorCode.InitConnection]: toStandardizedCode(ErrorCode.InitConnection),
|
|
70
|
-
[ErrorCode.ServiceDisconnected]: toStandardizedCode(
|
|
71
|
-
ErrorCode.ServiceDisconnected,
|
|
72
|
-
),
|
|
73
|
-
[ErrorCode.QueryProduct]: toStandardizedCode(ErrorCode.QueryProduct),
|
|
74
|
-
[ErrorCode.SkuNotFound]: toStandardizedCode(ErrorCode.SkuNotFound),
|
|
75
|
-
[ErrorCode.SkuOfferMismatch]: toStandardizedCode(ErrorCode.SkuOfferMismatch),
|
|
76
|
-
[ErrorCode.ItemNotOwned]: toStandardizedCode(ErrorCode.ItemNotOwned),
|
|
77
|
-
[ErrorCode.BillingUnavailable]: toStandardizedCode(
|
|
78
|
-
ErrorCode.BillingUnavailable,
|
|
79
|
-
),
|
|
80
|
-
[ErrorCode.FeatureNotSupported]: toStandardizedCode(
|
|
81
|
-
ErrorCode.FeatureNotSupported,
|
|
82
|
-
),
|
|
83
|
-
[ErrorCode.EmptySkuList]: toStandardizedCode(ErrorCode.EmptySkuList),
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Mapping between platforms and their canonical error codes.
|
|
88
|
-
* Values are platform-native string identifiers.
|
|
89
|
-
*/
|
|
90
|
-
export const ErrorCodeMapping = {
|
|
91
|
-
ios: COMMON_ERROR_CODE_MAP,
|
|
92
|
-
android: COMMON_ERROR_CODE_MAP,
|
|
93
|
-
} as const;
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Error thrown by expo-iap when purchases fail.
|
|
97
|
-
*/
|
|
98
|
-
export class PurchaseError extends Error {
|
|
99
|
-
public responseCode?: number;
|
|
100
|
-
public debugMessage?: string;
|
|
101
|
-
public code?: ErrorCode;
|
|
102
|
-
public productId?: string;
|
|
103
|
-
public platform?: IapPlatform;
|
|
104
|
-
|
|
105
|
-
constructor(
|
|
106
|
-
message: string,
|
|
107
|
-
responseCode?: number,
|
|
108
|
-
debugMessage?: string,
|
|
109
|
-
code?: ErrorCode,
|
|
110
|
-
productId?: string,
|
|
111
|
-
platform?: IapPlatform,
|
|
112
|
-
);
|
|
113
|
-
constructor(props: PurchaseErrorProps);
|
|
114
|
-
constructor(
|
|
115
|
-
messageOrProps: string | PurchaseErrorProps,
|
|
116
|
-
responseCode?: number,
|
|
117
|
-
debugMessage?: string,
|
|
118
|
-
code?: ErrorCode,
|
|
119
|
-
productId?: string,
|
|
120
|
-
platform?: IapPlatform,
|
|
121
|
-
) {
|
|
122
|
-
super(
|
|
123
|
-
typeof messageOrProps === 'string'
|
|
124
|
-
? messageOrProps
|
|
125
|
-
: messageOrProps.message,
|
|
126
|
-
);
|
|
127
|
-
this.name = '[expo-iap]: PurchaseError';
|
|
128
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
129
|
-
|
|
130
|
-
if (typeof messageOrProps === 'string') {
|
|
131
|
-
this.responseCode = responseCode;
|
|
132
|
-
this.debugMessage = debugMessage;
|
|
133
|
-
this.code = code;
|
|
134
|
-
this.productId = productId;
|
|
135
|
-
this.platform = platform;
|
|
136
|
-
} else {
|
|
137
|
-
this.responseCode = messageOrProps.responseCode;
|
|
138
|
-
this.debugMessage = messageOrProps.debugMessage;
|
|
139
|
-
this.code = messageOrProps.code;
|
|
140
|
-
this.productId = messageOrProps.productId;
|
|
141
|
-
this.platform = messageOrProps.platform;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Create a {@link PurchaseError} from raw platform error data.
|
|
147
|
-
*/
|
|
148
|
-
static fromPlatformError(
|
|
149
|
-
errorData: PlatformErrorData,
|
|
150
|
-
platform: IapPlatform,
|
|
151
|
-
): PurchaseError {
|
|
152
|
-
const normalizedPlatform = normalizePlatform(platform);
|
|
153
|
-
|
|
154
|
-
const errorCode = errorData.code
|
|
155
|
-
? ErrorCodeUtils.fromPlatformCode(errorData.code, normalizedPlatform)
|
|
156
|
-
: ErrorCode.Unknown;
|
|
157
|
-
|
|
158
|
-
return new PurchaseError({
|
|
159
|
-
message: errorData.message ?? 'Unknown error occurred',
|
|
160
|
-
responseCode: errorData.responseCode,
|
|
161
|
-
debugMessage: errorData.debugMessage,
|
|
162
|
-
code: errorCode,
|
|
163
|
-
productId: errorData.productId,
|
|
164
|
-
platform,
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Returns the platform specific error code for this instance.
|
|
170
|
-
*/
|
|
171
|
-
getPlatformCode(): string | number | undefined {
|
|
172
|
-
if (!this.code || !this.platform) {
|
|
173
|
-
return undefined;
|
|
174
|
-
}
|
|
175
|
-
return ErrorCodeUtils.toPlatformCode(this.code, this.platform);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/** Utility helpers for translating error codes between platforms. */
|
|
180
|
-
export const ErrorCodeUtils = {
|
|
181
|
-
/**
|
|
182
|
-
* Returns the native error code for the provided {@link ErrorCode}.
|
|
183
|
-
*/
|
|
184
|
-
getNativeErrorCode: (errorCode: ErrorCode): string => {
|
|
185
|
-
const standardized = toStandardizedCode(errorCode);
|
|
186
|
-
return (
|
|
187
|
-
(NATIVE_ERROR_CODES as Record<string, string | undefined>)[
|
|
188
|
-
standardized
|
|
189
|
-
] ?? standardized
|
|
190
|
-
);
|
|
191
|
-
},
|
|
192
|
-
/**
|
|
193
|
-
* Converts a platform-specific error code into a standardized {@link ErrorCode}.
|
|
194
|
-
*/
|
|
195
|
-
fromPlatformCode: (
|
|
196
|
-
platformCode: string | number,
|
|
197
|
-
_platform: IapPlatform,
|
|
198
|
-
): ErrorCode => {
|
|
199
|
-
if (typeof platformCode === 'string' && platformCode.startsWith('E_')) {
|
|
200
|
-
if (OPENIAP_ERROR_CODE_SET.has(platformCode)) {
|
|
201
|
-
const match = Object.entries(COMMON_ERROR_CODE_MAP).find(
|
|
202
|
-
([, value]) => value === platformCode,
|
|
203
|
-
);
|
|
204
|
-
if (match) {
|
|
205
|
-
return match[0] as ErrorCode;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
for (const [standardized, nativeCode] of Object.entries(
|
|
211
|
-
(NATIVE_ERROR_CODES || {}) as Record<string, string | number>,
|
|
212
|
-
)) {
|
|
213
|
-
if (
|
|
214
|
-
nativeCode === platformCode &&
|
|
215
|
-
OPENIAP_ERROR_CODE_SET.has(standardized)
|
|
216
|
-
) {
|
|
217
|
-
const match = Object.entries(COMMON_ERROR_CODE_MAP).find(
|
|
218
|
-
([, mappedCode]) => mappedCode === standardized,
|
|
219
|
-
);
|
|
220
|
-
if (match) {
|
|
221
|
-
return match[0] as ErrorCode;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
for (const [errorCode, mappedCode] of Object.entries(
|
|
227
|
-
COMMON_ERROR_CODE_MAP,
|
|
228
|
-
)) {
|
|
229
|
-
if (mappedCode === platformCode) {
|
|
230
|
-
return errorCode as ErrorCode;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return ErrorCode.Unknown;
|
|
235
|
-
},
|
|
236
|
-
/**
|
|
237
|
-
* Converts a standardized {@link ErrorCode} into its platform-specific value.
|
|
238
|
-
*/
|
|
239
|
-
toPlatformCode: (
|
|
240
|
-
errorCode: ErrorCode,
|
|
241
|
-
_platform: IapPlatform,
|
|
242
|
-
): string | number => {
|
|
243
|
-
const standardized = toStandardizedCode(errorCode);
|
|
244
|
-
const native = (NATIVE_ERROR_CODES as Record<string, string | number>)[
|
|
245
|
-
standardized
|
|
246
|
-
];
|
|
247
|
-
return native ?? COMMON_ERROR_CODE_MAP[errorCode] ?? 'E_UNKNOWN';
|
|
248
|
-
},
|
|
249
|
-
/**
|
|
250
|
-
* Determines whether the error code is supported on the given platform.
|
|
251
|
-
*/
|
|
252
|
-
isValidForPlatform: (
|
|
253
|
-
errorCode: ErrorCode,
|
|
254
|
-
platform: IapPlatform,
|
|
255
|
-
): boolean => {
|
|
256
|
-
const standardized = toStandardizedCode(errorCode);
|
|
257
|
-
if (
|
|
258
|
-
(NATIVE_ERROR_CODES as Record<string, unknown>)[standardized] !==
|
|
259
|
-
undefined
|
|
260
|
-
) {
|
|
261
|
-
return true;
|
|
262
|
-
}
|
|
263
|
-
return standardized in ErrorCodeMapping[normalizePlatform(platform)];
|
|
264
|
-
},
|
|
265
|
-
};
|
package/src/utils/purchase.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import type {Purchase} from '../types';
|
|
2
|
-
|
|
3
|
-
const isPurchaseObject = (value: unknown): value is Record<string, unknown> =>
|
|
4
|
-
Boolean(value) && typeof value === 'object';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Normalizes purchase identifiers so `id` reflects the transaction identifier (if present).
|
|
8
|
-
* Falls back to the existing `id` when no transaction identifier is available.
|
|
9
|
-
*/
|
|
10
|
-
export const normalizePurchaseId = <T extends Purchase | null | undefined>(
|
|
11
|
-
purchase: T,
|
|
12
|
-
): T => {
|
|
13
|
-
if (!isPurchaseObject(purchase)) {
|
|
14
|
-
return purchase;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const transactionId = (purchase as Record<string, unknown>).transactionId;
|
|
18
|
-
if (typeof transactionId !== 'string' || transactionId.length === 0) {
|
|
19
|
-
return purchase;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (purchase.id === transactionId) {
|
|
23
|
-
return purchase;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return {...purchase, id: transactionId} as T;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export const normalizePurchaseList = <T extends Purchase>(
|
|
30
|
-
purchases: T[] | null | undefined,
|
|
31
|
-
): T[] => {
|
|
32
|
-
if (!Array.isArray(purchases)) {
|
|
33
|
-
return purchases ?? [];
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (purchases.length === 0) {
|
|
37
|
-
return purchases;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return purchases.map((purchase) => normalizePurchaseId(purchase)) as T[];
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export const normalizePurchasePayload = <T extends Purchase | null | undefined>(
|
|
44
|
-
payload: T | T[] | null | undefined,
|
|
45
|
-
): typeof payload => {
|
|
46
|
-
if (Array.isArray(payload)) {
|
|
47
|
-
return payload.map((purchase) =>
|
|
48
|
-
normalizePurchaseId(purchase),
|
|
49
|
-
) as typeof payload;
|
|
50
|
-
}
|
|
51
|
-
return normalizePurchaseId(payload as T) as typeof payload;
|
|
52
|
-
};
|