refactor: move sku into platform-specific verification options#54
Conversation
- Remove sku from VerifyPurchaseProps root level - Add sku to VerifyPurchaseAppleOptions (replaces jws) - Add sku to VerifyPurchaseGoogleOptions - Update Kotlin code to use googleOptions.sku - Update tests for new schema structure - Update release notes for v1.3.4/v1.3.14/v1.3.2
|
Warning Rate limit exceeded@hyochan has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 5 minutes and 43 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (8)
WalkthroughThe PR refactors the purchase verification API structure across multiple packages, moving the Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/google/openiap/src/main/java/dev/hyo/openiap/utils/PurchaseVerificationValidator.kt (1)
31-57: Addskuto the non-blank validation (and error message).
Right nowskuis used to build the Google endpoint path but isn’t validated, so blankskuyields a hard-to-diagnose HTTP error.val packageName = googleOptions.packageName val purchaseToken = googleOptions.purchaseToken val accessToken = googleOptions.accessToken val isSub = googleOptions.isSub + val sku = googleOptions.sku - if (packageName.isBlank() || purchaseToken.isBlank() || accessToken.isBlank()) { + if (packageName.isBlank() || purchaseToken.isBlank() || accessToken.isBlank() || sku.isBlank()) { throw IllegalArgumentException( - "Google Play validation requires packageName, purchaseToken, and accessToken" + "Google Play validation requires packageName, sku, purchaseToken, and accessToken" ) } - - val sku = googleOptions.sku val typeSegment = if (isSub == true) "subscriptions" else "products"
🧹 Nitpick comments (2)
packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt (1)
1-4: Generator command in header may be stale/inconsistent.
Header saysnpm run generate, but repo guidance elsewhere suggests different generation flows; consider aligning the generator/header to the actual command used in this repo to avoid manual edits. Based on learnings/coding guidelines.packages/google/openiap/src/test/java/dev/hyo/openiap/PurchaseVerificationValidatorTest.kt (1)
27-51: Tests updated correctly for nestedgoogleOptions.sku.
These updates match the new API shape and should catch most migration mistakes at compile time. Consider adding a test asserting blankskuis rejected once the validator enforces it.Also applies to: 84-94, 129-139
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
packages/gql/src/generated/Types.ktis excluded by!**/generated/**packages/gql/src/generated/Types.swiftis excluded by!**/generated/**packages/gql/src/generated/types.dartis excluded by!**/generated/**packages/gql/src/generated/types.tsis excluded by!**/generated/**
📒 Files selected for processing (8)
packages/apple/Sources/Models/Types.swift(3 hunks)packages/docs/src/pages/docs/updates/notes.tsx(3 hunks)packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt(5 hunks)packages/google/openiap/src/main/java/dev/hyo/openiap/utils/PurchaseVerificationValidator.kt(1 hunks)packages/google/openiap/src/test/java/dev/hyo/openiap/PurchaseVerificationValidatorTest.kt(7 hunks)packages/gql/src/type-android.graphql(1 hunks)packages/gql/src/type-ios.graphql(1 hunks)packages/gql/src/type.graphql(0 hunks)
💤 Files with no reviewable changes (1)
- packages/gql/src/type.graphql
🧰 Additional context used
📓 Path-based instructions (10)
packages/gql/**/*
📄 CodeRabbit inference engine (CLAUDE.md)
Run
bun run generateto regenerate types for all platforms (TypeScript, Swift, Kotlin, Dart) from the GraphQL schema
Files:
packages/gql/src/type-android.graphqlpackages/gql/src/type-ios.graphql
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: iOS-specific functions must end withIOSsuffix (e.g.,clearTransactionIOS,getAppTransactionIOS)
Android-specific functions must end withAndroidsuffix (e.g.,acknowledgePurchaseAndroid,consumePurchaseAndroid)
Use action prefixes for function naming:getfor retrieval,requestfor async operations,clearfor removal,is/hasfor boolean checks,show/presentfor UI display,begin/finish/endfor process controlPrefer interface for defining object shapes in TypeScript
Files:
packages/docs/src/pages/docs/updates/notes.tsx
packages/docs/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/docs/**/*.{ts,tsx}: Use kebab-case for search modal IDs (e.g.,id: 'request-products')
Modal state should be defined once at the app root level using Preact Signals (signal from '@preact/signals-react'), not instantiated multiple times
ALL components must fit within parent boundaries and never overflow outside parent containers; useoverflow-hidden,break-words, andwhitespace-nowrapas needed
Delete unused components, functions, and imports immediately; do not keep commented-out code or unused variables
ANY function that returns a Promise must be wrapped withvoidoperator when used where a void return is expected (e.g., event handlers)
Files:
packages/docs/src/pages/docs/updates/notes.tsx
packages/docs/**/*
📄 CodeRabbit inference engine (CLAUDE.md)
packages/docs/**/*: Before committing, runnpx prettier --write,npm run lint,bun run tscornpm run typecheck, andnpm run buildto verify formatting, linting, types, and build success
Use conventional commit format with lowercase type prefix and lowercase description (e.g.,feat: add user authentication)
Files:
packages/docs/src/pages/docs/updates/notes.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (GEMINI.md)
**/*.{ts,tsx,js,jsx}: Use camelCase for variable and function names
Use PascalCase for class and component names
Always use async/await for handling promises instead of .then() chains
Add JSDoc comments for public functions and exported APIs
Use const by default, let if reassignment is needed, avoid var
Files:
packages/docs/src/pages/docs/updates/notes.tsx
packages/apple/**/*.swift
📄 CodeRabbit inference engine (CLAUDE.md)
packages/apple/**/*.swift: iOS-specific functions MUST haveIOSsuffix (e.g.,presentCodeRedemptionSheetIOS(),showManageSubscriptionsIOS())
Use Pascal case for acronyms at the beginning or middle of names (e.g.,IapManager,IapPurchase), but ALL CAPS only when appearing as a suffix (e.g.,ProductIAP,OpenIAP)
Files:
packages/apple/Sources/Models/Types.swift
packages/apple/Sources/Models/Types.swift
📄 CodeRabbit inference engine (CLAUDE.md)
DO NOT edit
Types.swiftinSources/Models/as it is auto-generated from the OpenIAP GraphQL schema; regenerate using./scripts/generate-types.sh
Files:
packages/apple/Sources/Models/Types.swift
packages/apple/Sources/Models/**/*.swift
📄 CodeRabbit inference engine (CLAUDE.md)
OpenIAP official types in
Sources/Models/must match types defined at openiap.dev/docs/types
Files:
packages/apple/Sources/Models/Types.swift
packages/google/**/*.kt
📄 CodeRabbit inference engine (CLAUDE.md)
DO NOT add
Androidsuffix to function names in the Android-only package, even for Android-specific APIs (e.g., useacknowledgePurchase()notacknowledgePurchaseAndroid())
Files:
packages/google/openiap/src/main/java/dev/hyo/openiap/utils/PurchaseVerificationValidator.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/Types.ktpackages/google/openiap/src/test/java/dev/hyo/openiap/PurchaseVerificationValidatorTest.kt
packages/google/openiap/src/main/java/dev/hyo/openiap/utils/**/*.kt
📄 CodeRabbit inference engine (CLAUDE.md)
Place reusable Kotlin helper functions in
openiap/src/main/java/dev/hyo/openiap/utils/
Files:
packages/google/openiap/src/main/java/dev/hyo/openiap/utils/PurchaseVerificationValidator.kt
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/apple/openiap-versions.json : To update OpenIAP GraphQL types in the iOS/macOS library, edit the `gql` field in `openiap-versions.json`, run `./scripts/generate-types.sh`, and run `swift test` to verify compatibility
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/google/**/*.kt : DO NOT add `Android` suffix to function names in the Android-only package, even for Android-specific APIs (e.g., use `acknowledgePurchase()` not `acknowledgePurchaseAndroid()`)
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/google/openiap-versions.json : To update OpenIAP GraphQL types in the Android library, edit the `gql` field in `openiap-versions.json`, then run `./scripts/generate-types.sh` and compile to verify
Applied to files:
packages/gql/src/type-android.graphqlpackages/gql/src/type-ios.graphqlpackages/docs/src/pages/docs/updates/notes.tsxpackages/google/openiap/src/main/java/dev/hyo/openiap/utils/PurchaseVerificationValidator.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/Types.ktpackages/google/openiap/src/test/java/dev/hyo/openiap/PurchaseVerificationValidatorTest.kt
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/google/openiap/src/main/Types.kt : DO NOT edit `openiap/src/main/Types.kt` as it is auto-generated from the GraphQL schema; regenerate it using `./scripts/generate-types.sh`
Applied to files:
packages/gql/src/type-android.graphqlpackages/google/openiap/src/main/java/dev/hyo/openiap/utils/PurchaseVerificationValidator.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/Types.ktpackages/google/openiap/src/test/java/dev/hyo/openiap/PurchaseVerificationValidatorTest.kt
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/apple/openiap-versions.json : To update OpenIAP GraphQL types in the iOS/macOS library, edit the `gql` field in `openiap-versions.json`, run `./scripts/generate-types.sh`, and run `swift test` to verify compatibility
Applied to files:
packages/gql/src/type-android.graphqlpackages/gql/src/type-ios.graphqlpackages/docs/src/pages/docs/updates/notes.tsxpackages/apple/Sources/Models/Types.swiftpackages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/google/**/*.kt : DO NOT add `Android` suffix to function names in the Android-only package, even for Android-specific APIs (e.g., use `acknowledgePurchase()` not `acknowledgePurchaseAndroid()`)
Applied to files:
packages/gql/src/type-android.graphqlpackages/google/openiap/src/main/java/dev/hyo/openiap/utils/PurchaseVerificationValidator.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/Types.ktpackages/google/openiap/src/test/java/dev/hyo/openiap/PurchaseVerificationValidatorTest.kt
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/apple/Sources/Models/Types.swift : DO NOT edit `Types.swift` in `Sources/Models/` as it is auto-generated from the OpenIAP GraphQL schema; regenerate using `./scripts/generate-types.sh`
Applied to files:
packages/gql/src/type-ios.graphqlpackages/apple/Sources/Models/Types.swiftpackages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/apple/Sources/Models/**/*.swift : OpenIAP official types in `Sources/Models/` must match types defined at [openiap.dev/docs/types](https://www.openiap.dev/docs/types)
Applied to files:
packages/gql/src/type-ios.graphqlpackages/apple/Sources/Models/Types.swiftpackages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to **/*.{ts,tsx} : Android-specific functions must end with `Android` suffix (e.g., `acknowledgePurchaseAndroid`, `consumePurchaseAndroid`)
Applied to files:
packages/docs/src/pages/docs/updates/notes.tsx
📚 Learning: 2025-12-06T20:15:59.223Z
Learnt from: CR
Repo: hyodotdev/openiap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T20:15:59.223Z
Learning: Applies to packages/google/openiap/src/main/java/dev/hyo/openiap/utils/**/*.kt : Place reusable Kotlin helper functions in `openiap/src/main/java/dev/hyo/openiap/utils/`
Applied to files:
packages/google/openiap/src/main/java/dev/hyo/openiap/utils/PurchaseVerificationValidator.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/Types.ktpackages/google/openiap/src/test/java/dev/hyo/openiap/PurchaseVerificationValidatorTest.kt
🧬 Code graph analysis (4)
packages/docs/src/pages/docs/updates/notes.tsx (3)
packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt (2)
code(1763-1785)code(2409-2428)packages/gql/src/generated/Types.kt (2)
code(1835-1857)code(2481-2500)packages/google/openiap/src/main/java/dev/hyo/openiap/store/OpenIapStore.kt (1)
code(599-604)
packages/apple/Sources/Models/Types.swift (2)
packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt (4)
sku(3091-3108)accessToken(3116-3159)accessToken(3168-3198)purchaseToken(3001-3018)packages/gql/src/generated/Types.kt (4)
sku(3163-3180)accessToken(3188-3231)accessToken(3240-3270)purchaseToken(3073-3090)
packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt (1)
packages/gql/src/generated/types.ts (1)
VerifyPurchaseAppleOptions(1117-1120)
packages/google/openiap/src/test/java/dev/hyo/openiap/PurchaseVerificationValidatorTest.kt (1)
packages/gql/src/generated/types.ts (1)
VerifyPurchaseProps(1173-1180)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test Android
🔇 Additional comments (8)
packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt (2)
3091-3107:VerifyPurchaseAppleOptionssku migration looks correct (but keep it generated-only).
fromJson()/toJson()now round-tripsku, matching the new schema expectation. Given this file is auto-generated, please ensure this change came from schema + generator (not manual edits).
3116-3159:VerifyPurchaseGoogleOptionsnow requiressku: good; verify call-sites pass it.
Constructor ordering change (purchaseToken, thensku) is a source-level breaking change for Kotlin callers; tests here cover it, but please ensure other call-sites were migrated too.packages/gql/src/type-android.graphql (1)
379-402: Schema change is coherent:VerifyPurchaseGoogleOptions.skuis now required.
This is a breaking contract change for all GraphQL clients; make sure generated types are regenerated (bun run generate) and released with clear migration notes. As per coding guidelines.packages/gql/src/type-ios.graphql (1)
234-239:VerifyPurchaseAppleOptionsnow takessku: consistent, but confirm backend expectations + regenerate clients.
Given this used to bejws, please ensure the server resolver(s) and all generated clients were updated in lockstep (bun run generate).packages/apple/Sources/Models/Types.swift (3)
1338-1349:VerifyPurchaseAppleOptionsnow usessku: OK; keep this strictly generated.
Please ensure this was produced via./scripts/generate-types.sh(not hand-edited). Based on learnings.
1351-1382: Swift API break:VerifyPurchaseGoogleOptionsinitializer adds requiredsku.
This will break downstream compilation until call-sites passsku; looks intended—just ensure migration docs + tests cover it.
1415-1431:VerifyPurchasePropsnow relies on nested option skus: OK.
No issues with the struct shape; just ensure the Swift package was regenerated and validated (swift test). Based on learnings.packages/docs/src/pages/docs/updates/notes.tsx (1)
32-104:and
- Update performVerifyPurchaseIOS to require apple options with sku - Update OpenIapStore.verifyPurchase to use VerifyPurchaseAppleOptions - Update test mocks to use props.apple?.sku
…orizon - Rename PurchaseVerificationProps to VerifyPurchaseProps - Update fields: sku/androidOptions → apple/google/horizon options - Add VerifyPurchaseResultHorizon documentation in Android tab - Rename result types to VerifyPurchaseResult*
- Update VerifyPurchaseProps to use apple/google/horizon fields - Remove deprecated sku root field and androidOptions - Update native iOS/Android modules for new API structure - Update example apps with platform-specific verification - Update documentation and blog for 3.2.0 release - Bump openiap versions (gql 1.3.4, google 1.3.14, apple 1.3.2) Reflects hyodotdev/openiap#53 and hyodotdev/openiap#54 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * verifyPurchase API restructured to accept platform-specific provider options (apple, google, horizon). * Added Horizon (Meta) verification support. * **Improvements** * Stronger input validation and safer UI guards for purchase/discount handling. * Verification libraries updated to newer versions. * **Documentation** * Docs and examples updated for the new parameter shape and breaking change notes. * **Tests** * Tests updated to exercise provider-wrapped input shapes. * **Chores** * Pre-commit now re-stages linted files before running tests. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Refactor again based on #53
Summary by CodeRabbit
Breaking Changes
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.