Skip to content

Commit a99d40a

Browse files
committed
docs: apply contents in CLAUDE.md to AGENTS.md
1 parent 34cf368 commit a99d40a

File tree

1 file changed

+73
-9
lines changed

1 file changed

+73
-9
lines changed

AGENTS.md

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,22 @@
8181
- Cover: helpers (`src/utils/*`), hooks (`src/hooks/*`), plugin behavior, error mapping. Avoid testing generated code.
8282
- Use `yarn test:ci` for coverage; add focused tests near changes.
8383

84+
## Hook API Semantics (useIAP)
85+
86+
- Most hook methods return `Promise<void>` and update internal state. Read results from hook state: `products`, `subscriptions`, `availablePurchases`, etc.
87+
- Value-returning exceptions in the hook:
88+
- `getActiveSubscriptions(ids?) => Promise<ActiveSubscription[]>` (also updates `activeSubscriptions`)
89+
- `hasActiveSubscriptions(ids?) => Promise<boolean>`
90+
- The root API (from `src/index.ts`) is value-returning and can be awaited directly. Prefer root API when not using React state.
91+
92+
Example:
93+
94+
```ts
95+
const { fetchProducts, products } = useIAP()
96+
await fetchProducts({ skus: ['p1'] })
97+
// then read products from state
98+
```
99+
84100
## CI Checks
85101

86102
Run locally before pushing to avoid CI failures:
@@ -97,6 +113,54 @@ yarn test:ci
97113
yarn ci:check
98114
```
99115

116+
## Platform-Specific Features
117+
118+
- iOS (StoreKit 2): Subscription management, promotional offers, family sharing, refund requests, transaction verification, receipt validation.
119+
- Android (Play Billing): Multiple SKU purchases, subscription offers, obfuscated account/profile IDs, purchase acknowledgement, product consumption.
120+
- Android billing uses automatic service reconnection; connection handling is simplified in native code.
121+
122+
## Error Handling
123+
124+
- Centralized TS helpers in `src/utils/*` and types in `src/types.ts`:
125+
- `parseErrorStringToJsonObj()` — parse native error strings into structured objects
126+
- `isUserCancelledError()` — detect user-cancelled operations
127+
- `ErrorCode` enum — normalized cross-platform error codes
128+
- Native layers map platform errors to the same JSON shape before returning to JS.
129+
130+
Error JSON format (from native):
131+
132+
```json
133+
{
134+
"code": "E_USER_CANCELLED",
135+
"message": "User cancelled the purchase",
136+
"responseCode": 1,
137+
"debugMessage": "User pressed cancel",
138+
"productId": "com.example.product"
139+
}
140+
```
141+
142+
Usage example:
143+
144+
```ts
145+
try {
146+
await requestPurchase({
147+
/* ... */
148+
})
149+
} catch (e) {
150+
const err = parseErrorStringToJsonObj(e)
151+
if (isUserCancelledError(err)) return
152+
console.error('IAP failed:', err.code, err.message)
153+
}
154+
```
155+
156+
## Troubleshooting
157+
158+
- Specs changed but build fails: run `yarn specs` to regenerate Nitrogen bridge and rebuild native.
159+
- React duplication issues in example apps: ensure Metro alias resolves a single `react`/`react-native` (see `example/metro.config.js`).
160+
- iOS pods: `cd example/ios && bundle install && bundle exec pod install` (for Expo example: `cd example-expo/ios && pod install`).
161+
- Install issues: `yarn install`, clear cache `yarn cache clean`, or reinstall `rm -rf node_modules example/node_modules && yarn install`.
162+
- Metro cache: `cd example && yarn start --reset-cache`.
163+
100164
## Nitro Modules
101165

102166
### Types
@@ -137,20 +201,20 @@ yarn ci:check
137201

138202
```ts
139203
// src/specs/RnIap.nitro.ts
140-
export type Purchase = {id: string; productId: string; date: Date};
204+
export type Purchase = { id: string; productId: string; date: Date }
141205
export type Result<T> =
142-
| {kind: 'ok'; value: T}
143-
| {kind: 'err'; code: string; message: string};
206+
| { kind: 'ok'; value: T }
207+
| { kind: 'err'; code: string; message: string }
144208

145209
export interface RnIapSpec {
146-
init(): Promise<void>;
147-
fetchProducts(ids: string[]): Promise<Product[]>;
210+
init(): Promise<void>
211+
fetchProducts(ids: string[]): Promise<Product[]>
148212
requestPurchase(
149213
id: string,
150-
opts?: {quantity?: number},
151-
): Promise<Result<Purchase>>;
152-
addPurchaseListener(cb: (p: Purchase) => void): void;
153-
getStorefrontIOS?(): string;
214+
opts?: { quantity?: number }
215+
): Promise<Result<Purchase>>
216+
addPurchaseListener(cb: (p: Purchase) => void): void
217+
getStorefrontIOS?(): string
154218
}
155219
```
156220

0 commit comments

Comments
 (0)