Skip to content
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
2 changes: 1 addition & 1 deletion .claude/commands/review-pr.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Based on changed files, run these checks BEFORE committing:
When reviewing, check these project-specific rules:
- **iOS functions**: Must end with `IOS` suffix (e.g., `syncIOS`)
- **Android functions in packages/google**: NO `Android` suffix (it's Android-only)
- **Generated files**: Do NOT edit `packages/apple/Sources/Models/Types.swift` or `packages/google/openiap/src/main/Types.kt`
- **Generated files**: Do NOT edit `packages/apple/Sources/Models/Types.swift` or `packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt`

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

Expand Down
30 changes: 6 additions & 24 deletions .claude/commands/verify-all.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ set -euo pipefail

# Regenerate the schema SSOT, run codegen tests, and sync every wrapper first.
(cd packages/gql && bun run generate && bun run test)
bash scripts/sync-versions.sh

# Docs formatting, typecheck, and production bundle
(cd packages/docs && bun run format:check && bun run build)
Expand Down Expand Up @@ -193,34 +192,18 @@ git diff --check

### 2. Type Consistency

Verify `DuplicatePurchase` (and any new ErrorCode) exists in ALL generated types:
Verify the manifest-owned generated graph and cross-SDK contracts:

```bash
set -euo pipefail

missing=0
for f in packages/gql/src/generated/types.ts \
libraries/react-native-iap/src/types.ts \
libraries/expo-iap/src/types.ts \
libraries/flutter_inapp_purchase/lib/types.dart \
libraries/godot-iap/addons/godot-iap/types.gd \
packages/apple/Sources/Models/Types.swift \
packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt \
libraries/maui-iap/src/OpenIap.Maui/Types.cs; do
expected='DuplicatePurchase'
if [[ "$f" = *.gd ]]; then
expected='DUPLICATE_PURCHASE'
fi
if grep -q "$expected" "$f"; then
echo "$f: OK"
else
echo "$f: MISSING" >&2
missing=1
fi
done
exit "$missing"
(cd packages/gql && bun run test)
bun run audit:parity
```

The GQL suite derives source/target paths from
`packages/gql/generated-sync-manifest.mjs`; do not add a hard-coded file loop.

Also verify `COMMON_ERROR_CODE_MAP` in react-native-iap and expo-iap includes all ErrorCode entries:

- `libraries/react-native-iap/src/utils/errorMapping.ts`
Expand Down Expand Up @@ -334,7 +317,6 @@ the complete platform matrix in step 1.
set -euo pipefail

(cd packages/gql && bun run generate && bun run test)
bash scripts/sync-versions.sh
(cd packages/docs && bun run format:check && bun run build)
(cd packages/apple && swift test)
(cd packages/google && ./gradlew \
Expand Down
9 changes: 2 additions & 7 deletions .claude/guides/04-apple-package.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ packages/apple/
│ ├── ProductManager.swift # Thread-safe product caching
│ └── IapStatus.swift # UI status for SwiftUI
├── Tests/
├── scripts/
│ └── generate-types.sh # Type generation script
└── openiap-versions.json # Version management
```

Expand Down Expand Up @@ -60,11 +58,8 @@ Types.swift is auto-generated from GraphQL schema.
**Never edit Types.swift directly!**

```bash
# Generate types
./scripts/generate-types.sh

# Or with specific version
OPENIAP_GQL_VERSION=1.0.10 ./scripts/generate-types.sh
# From the monorepo root: generate all languages and sync manifest targets
cd packages/gql && bun run generate
```

## Version Management
Expand Down
47 changes: 8 additions & 39 deletions .claude/guides/06-gql-package.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,12 @@
# GQL Package Guide

Location: `packages/gql/`
The GraphQL package's canonical instructions live in:

## Overview
- `packages/gql/CONVENTION.md` — schema organization, marker/deprecation
contracts, supported generation commands, and generated-file rules.
- `knowledge/internal/04-platform-packages.md` — platform sync and SDK parity.
- `knowledge/internal/07-docs-consistency.md` — documentation and generated
API SSOT requirements.

Central GraphQL schema generating types for all platforms.

## Directory Structure

```text
packages/gql/
├── src/
│ ├── api.graphql # Main API schema
│ ├── api-ios.graphql # iOS-specific extensions
│ ├── api-android.graphql # Android-specific extensions
│ └── generated/
│ ├── types.ts # TypeScript
│ ├── Types.swift # Swift
│ ├── Types.kt # Kotlin
│ └── types.dart # Dart
└── package.json
```

## Type Generation

```bash
cd packages/gql

bun run generate # All types
bun run generate:swift # Swift only
bun run generate:kotlin # Kotlin only
bun run sync # Copy to packages
```

## Deprecation in GraphQL

```graphql
validateReceipt(options: ReceiptValidationProps!): ReceiptValidationResult!
@deprecated(reason: "Use verifyPurchase")
```

Generates appropriate annotations for each platform.
Do not duplicate those rules here. Read all three before changing
`packages/gql/`, then use the repository-owned `bun run generate` workflow.
Binary file added .github/pr-previews/openiap-codegen-ssot.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
118 changes: 28 additions & 90 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ jobs:
ios: ${{ steps.filter.outputs.ios }}
docs: ${{ steps.filter.outputs.docs }}
web: ${{ steps.filter.outputs.web }}
agent: ${{ steps.filter.outputs.agent }}
parity: ${{ steps.filter.outputs.parity }}
steps:
- name: Checkout
uses: actions/checkout@v7
Expand All @@ -82,6 +80,8 @@ jobs:
gql:
- 'packages/gql/**'
- 'scripts/**'
- 'package.json'
- 'bun.lock'
- 'openiap-versions.json'
- '.github/workflows/ci.yml'
- 'libraries/maui-iap/src/OpenIap.Maui/Types.cs'
Expand All @@ -99,6 +99,10 @@ jobs:
- '.github/workflows/ci.yml'
docs:
- 'packages/docs/**'
- 'packages/gql/src/generated/**'
- 'packages/gql/generated-sync-manifest.mjs'
- 'scripts/audit-docs.ts'
- 'scripts/audit-docs.test.ts'
- '.github/workflows/ci.yml'
web:
- 'packages/docs/**'
Expand All @@ -107,26 +111,9 @@ jobs:
- 'package.json'
- 'bun.lock'
- '.github/workflows/ci.yml'
agent:
- 'scripts/agent/**'
- 'packages/kit/public/llms.txt'
- 'packages/docs/public/llms*.txt'
- '.github/workflows/ci.yml'
parity:
- 'libraries/**'
- 'packages/apple/**'
- 'packages/google/**'
- 'packages/gql/**'
- 'scripts/audit-non-godot-parity.mjs'
- 'package.json'
- 'knowledge/internal/04-platform-packages.md'
- '.github/workflows/ci.yml'

audit-parity:
name: Audit SDK Parity
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.parity == 'true'
steps:
- name: Checkout
uses: actions/checkout@v7
Expand All @@ -136,9 +123,15 @@ jobs:
with:
node-version: 20

- name: Test clean-worktree drift guard
run: node --test scripts/assert-clean-worktree.test.mjs

- name: Sync generated version files
run: ./scripts/sync-versions.sh

- name: Verify version and generated synchronization is committed
run: node scripts/assert-clean-worktree.mjs

- name: Run non-Godot SDK parity audit
run: node scripts/audit-non-godot-parity.mjs

Expand Down Expand Up @@ -170,43 +163,16 @@ jobs:
working-directory: packages/gql
run: bun run generate

- name: Verify generated files
working-directory: packages/gql
run: |
test -f src/generated/types.ts || exit 1
test -f src/generated/Types.kt || exit 1
test -f src/generated/Types.swift || exit 1
test -f src/generated/types.dart || exit 1
test -f src/generated/types.gd || exit 1
test -f src/generated/Types.cs || exit 1

- name: Run tests
working-directory: packages/gql
run: bun run test

- name: Verify generated types are committed (no drift)
run: |
# `bun run generate` is expected to be idempotent: running it
# against the checked-in schema must produce the same bytes
# as the files checked into the repo. If this step fails,
# somebody changed a codegen plugin or the schema without
# re-running `bun run generate` + committing the output.
#
# Use `git status --porcelain` (plus `git diff`) so newly-
# generated but untracked files also fail the check — a
# plain `git diff` would silently pass if the generator
# starts emitting a new target file.
status="$(git status --porcelain)"
if [ -n "$status" ] || ! git diff --exit-code; then
echo ""
echo "::error::Generated types differ from checked-in copies."
echo "Run 'cd packages/gql && bun run generate' locally and commit the result."
echo ""
echo "Untracked or modified paths:"
printf '%s\n' "$status"
exit 1
fi
run: node scripts/assert-clean-worktree.mjs

# test-gql owns regeneration, platform sync, and the clean-worktree drift
# check. Consumer jobs compile the committed copies instead of invoking a
# second generator path.
test-android:
name: Test Android
runs-on: ubuntu-latest
Expand All @@ -222,25 +188,6 @@ jobs:
distribution: 'temurin'
java-version: '17'

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.13

- name: Install dependencies
run: |
# Retry bun install up to 3 times to handle transient registry errors
for i in 1 2 3; do
bun install --frozen-lockfile && break
[ $i -eq 3 ] && exit 1
echo "Attempt $i failed. Retrying..."
sleep 5
done

- name: Generate types
working-directory: packages/google
run: bun run generate:types

- name: Grant execute permission
working-directory: packages/google
run: chmod +x gradlew
Expand Down Expand Up @@ -275,25 +222,6 @@ jobs:
with:
xcode-version: ${{ env.XCODE_VERSION }}

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.13

- name: Install dependencies
run: |
# Retry bun install up to 3 times to handle transient registry errors
for i in 1 2 3; do
bun install --frozen-lockfile && break
[ $i -eq 3 ] && exit 1
echo "Attempt $i failed. Retrying..."
sleep 5
done

- name: Generate types
working-directory: packages/apple
run: bun run generate:types

- name: Build
working-directory: packages/apple
run: swift build
Expand Down Expand Up @@ -330,6 +258,11 @@ jobs:
working-directory: packages/docs
run: bun run typecheck

- name: Audit docs consistency
run: |
bun test scripts/audit-docs.test.ts
bun run audit:docs

- name: Lint
working-directory: packages/docs
run: bun run lint
Expand Down Expand Up @@ -409,8 +342,6 @@ jobs:
test-agent:
name: Test Agent Scripts
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.agent == 'true'
steps:
- name: Checkout
uses: actions/checkout@v7
Expand Down Expand Up @@ -438,3 +369,10 @@ jobs:
- name: Run tests
working-directory: scripts/agent
run: bun test

- name: Compile generated agent context
working-directory: scripts/agent
run: bun run compile:ai

- name: Verify compiled agent context is committed
run: node scripts/assert-clean-worktree.mjs
Loading
Loading