Skip to content
This repository was archived by the owner on Apr 26, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
261 changes: 261 additions & 0 deletions .claude/commands/commit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
# Commit Changes

Complete workflow: branch → commit → push → PR

## Usage

```text
/commit [options]
```

**Options:**

- `--push` or `-p`: Push to remote after commit
- `--pr`: Create PR after push (implies --push)
- `--all` or `-a`: Commit all changes at once
- `<path>`: Commit only specific path (e.g., `src/hooks`)

## Examples

```bash
# Full workflow: commit, push, create PR
/commit --pr

# Commit all changes and create PR
/commit --all --pr

# Just commit specific path
/commit src/hooks

# Commit and push without PR
/commit --push
```

## Complete Workflow

### 1. Check Branch

```bash
# Check current branch
git branch --show-current
```

**If on `main`** → Create a feature branch first:

```bash
git checkout -b feat/<feature-name>
```

**If NOT on `main`** → Proceed with commits directly.

**Branch naming conventions:**

- `feat/<feature-name>` - New features
- `fix/<bug-description>` - Bug fixes
- `docs/<doc-update>` - Documentation only
- `chore/<task>` - Maintenance tasks

### 2. Check Current Status

```bash
git status
git diff --name-only
```

### 3. Stage Changes

**Specific path:**

```bash
git add <path>
```

**All changes:**

```bash
git add .
```

### 4. Review Staged Changes

```bash
git diff --cached --stat
git diff --cached --name-only
```

### 5. Create Commit

Follow conventional commit format:

```bash
git commit -m "$(cat <<'EOF'
<type>(<scope>): <description>

<body - what changed and why>

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comment thread
hyochan marked this conversation as resolved.
EOF
)"
```

**Commit Types:**

| Type | Description |
| ---------- | --------------------- |
| `feat` | New feature |
| `fix` | Bug fix |
| `docs` | Documentation only |
| `refactor` | Code refactoring |
| `chore` | Maintenance tasks |
| `test` | Adding/updating tests |

**Scope Examples:**

- `ios` - iOS native code changes
- `android` - Android native code changes
- `hooks` - React hooks (useIAP)
- `types` - TypeScript type definitions
- `nitro` - Nitro module specs
- `podspec` - CocoaPods configuration

### 6. Push to Remote

```bash
git push -u origin <branch-name>
```

### 7. Create Pull Request

```bash
gh pr create --title "<type>(<scope>): <description>" --body "$(cat <<'EOF'
## Summary

<1-3 bullet points describing changes>

## Changes

### <Category 1>
- Change 1
- Change 2

### <Category 2>
- Change 1

## Test plan

- [ ] `yarn typecheck` passes
- [ ] `yarn lint` passes
- [ ] `yarn test` passes

🤖 Generated with [Claude Code](https://claude.ai/code)
EOF
)"
```

---

## Commit Order (Recommended)

When making cross-platform changes, commit in this order:

| Order | Path | Description |
| ----- | --------------------- | ------------------------------------------ |
| 1 | `src/specs/` | Nitro interface definitions |
| 2 | `nitrogen/generated/` | Generated Nitro files (after `yarn specs`) |
| 3 | `ios/` | iOS native implementation |
| 4 | `android/` | Android native implementation |
| 5 | `src/` | TypeScript implementation |
| 6 | `src/__tests__/` | Test files |
| 7 | `*.podspec` | CocoaPods configuration |

---

## Example Commit Messages

**Feature addition:**

```text
feat(ios): add tvOS and macOS platform support

- Add tvOS 15.0 and macOS 14.0 to podspec platforms
- Add platform detection helpers (isTVOS, isMacOS, isStandardIOS)
- Skip promotedProductListenerIOS on tvOS/macOS
- Update Swift availability annotations

Closes #3141

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comment thread
hyochan marked this conversation as resolved.
```

**Bug fix:**

```text
fix(hooks): register listeners after initConnection

Move listener registration after initConnection succeeds
to ensure Nitro runtime is fully initialized. This fixes
crashes on platforms where Nitro initializes later.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comment thread
hyochan marked this conversation as resolved.
```

**Chore/maintenance:**

```text
chore(deps): update OpenIAP to 1.3.11

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comment thread
hyochan marked this conversation as resolved.
```

---

## Example PR Body

```markdown
## Summary

- Add tvOS 15.0 and macOS 14.0 platform support
- Fix Nitro initialization timing for non-iOS platforms
- Add platform detection helpers

## Changes

### Podspec (NitroIap.podspec)

- Add `:tvos => '15.0'` and `:macos => '14.0'` platforms

### iOS Native (ios/)

- Update `@available` to include all platforms

### TypeScript (src/)

- Add `isTVOS()`, `isMacOS()`, `isStandardIOS()` helpers
- Skip promoted product listener on tvOS/macOS
- Register listeners after initConnection succeeds

### Tests (src/\_\_tests\_\_/)

- Add platform detection tests

## Test plan

- [x] `yarn typecheck` passes
- [x] `yarn lint` passes
- [x] `yarn test` passes

🤖 Generated with [Claude Code](https://claude.ai/code)
```

---

## Quick Reference

```bash
# Full workflow from main
git checkout -b feat/my-feature
git add .
git commit -m "feat(scope): description"
git push -u origin feat/my-feature
gh pr create --title "feat(scope): description" --body "..."
```
69 changes: 69 additions & 0 deletions .claude/commands/review-pr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Review PR Comments

Review and address PR review comments for this repository.

## Arguments

- `$ARGUMENTS` - PR number (e.g., `123`) or PR URL

## Project-Specific Build Commands

Based on changed files, run these checks BEFORE committing:

| Path | Commands |
| ----------- | ----------------------------------------------- |
| `src/` | `yarn typecheck && yarn lint && yarn test` |
| `ios/` | `cd example/ios && bundle exec pod install` |
| `android/` | `cd example/android && ./gradlew assembleDebug` |
| `plugin/` | `yarn typecheck && yarn test` |
| `*.podspec` | `pod lib lint --allow-warnings` |

## Project Conventions

When reviewing, check these project-specific rules:

- **iOS functions**: Must end with `IOS` suffix (e.g., `getStorefrontIOS`)
- **Android functions**: Must end with `Android` suffix (e.g., `consumePurchaseAndroid`)
- **Cross-platform functions**: No suffix (e.g., `initConnection`, `fetchProducts`)
- **Generated files**: Do NOT edit files in `nitrogen/generated/` or `src/types.ts`
- **Type imports**: Use `import type` for type-only imports

See [CLAUDE.md](../../CLAUDE.md) for full conventions.

## Reply Format Rules (CRITICAL)

When replying to PR comments:

### Commit Hash Formatting

**NEVER wrap commit hashes in backticks or code blocks.** GitHub only auto-links plain text commit hashes.

| Format | Example | Result |
| ---------- | ----------------------- | ------------------------ |
| ✅ CORRECT | `Fixed in f3b5fec.` | Clickable link to commit |
| ❌ WRONG | `Fixed in \`f3b5fec\`.` | Plain text, no link |

**Examples of correct replies:**

```text
Fixed in f3b5fec.

**Changes:**
- Updated listener registration order
```

```text
Fixed in abc1234 along with other review items.
```

**Do NOT use backticks around the commit hash** - this breaks GitHub's auto-linking feature.

## Workflow

1. Fetch PR comments: `gh pr view <number> --comments`
2. Review each comment and understand the requested change
3. Make the necessary code changes
4. Run relevant build commands based on changed files
5. Commit with descriptive message referencing the review
6. Push changes
7. Reply to each comment with the fix commit hash (no backticks!)
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,7 @@ android/keystores/debug.keystore
lib/
nitrogen/generated
tsconfig.tsbuildinfo
.claude
# Claude Code (keep commands, ignore local settings)
.claude/settings.local.json

coverage
3 changes: 2 additions & 1 deletion NitroIap.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ Pod::Spec.new do |s|
# React Native IAP uses StoreKit 2 via OpenIAP, which requires iOS 15+.
# Enforce this at the podspec level so projects with a lower deployment target
# get a clear CocoaPods error instead of a vague SwiftCompile failure.
s.platforms = { :ios => '15.0', :visionos => 1.0 }
# Platform versions match OpenIAP requirements: iOS 15+, macOS 14+, tvOS 15+, watchOS 8+
s.platforms = { :ios => '15.0', :tvos => '15.0', :macos => '14.0', :watchos => '8.0', :visionos => 1.0 }
s.source = { :git => "https://github.com/hyochan/react-native-iap.git", :tag => "#{s.version}" }

s.source_files = [
Expand Down
2 changes: 1 addition & 1 deletion ios/HybridRnIap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Foundation
import NitroModules
import OpenIAP

@available(iOS 15.0, *)
@available(iOS 15.0, macOS 14.0, tvOS 15.0, watchOS 8.0, *)
class HybridRnIap: HybridRnIapSpec {
// MARK: - Properties
private var updateListenerTask: Task<Void, Never>?
Expand Down
17 changes: 17 additions & 0 deletions src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,21 @@ describe('Public API (src/index.ts)', () => {
IAP = require('../index');
});

describe('platform detection helpers', () => {
// Note: More comprehensive platform detection tests are in platform-detection.test.ts
// which properly resets modules for accurate Platform detection testing
it('isNitroReady returns true when Nitro is initialized', () => {
expect(IAP.isNitroReady()).toBe(true);
});

it('exports platform detection functions', () => {
expect(typeof IAP.isTVOS).toBe('function');
expect(typeof IAP.isMacOS).toBe('function');
expect(typeof IAP.isStandardIOS).toBe('function');
expect(typeof IAP.isNitroReady).toBe('function');
});
});

describe('listeners', () => {
it('purchaseUpdatedListener wraps and forwards validated purchases', () => {
const listener = jest.fn();
Expand Down Expand Up @@ -169,6 +184,8 @@ describe('Public API (src/index.ts)', () => {

it('promotedProductListenerIOS on iOS converts and forwards product', () => {
(Platform as any).OS = 'ios';
(Platform as any).isTV = false;
(Platform as any).isMacCatalyst = false;
const nitroProduct = {
id: 'sku1',
title: 'Title',
Expand Down
Loading