IAPKit deploys from main while every SDK that decodes its responses is frozen
inside published apps, so a value it adds later must degrade rather than fail a
purchase. #321 made that true by hand in six SDK parsers. The generated
decoders still throw, so the next parser someone writes gets it wrong again.
Fix it at the generator instead, in two parts. Neither adds an enum member, so
neither breaks an exhaustive when / switch in consumer code.
a. Degrade to the neutral member when the enum already declares one.
IapkitPurchaseState has UNKNOWN and IapStore has Unknown, but the
generated fromJson throws anyway — packages/gql/codegen/plugins/kotlin.ts:230,
dart.ts:187, csharp.ts:322. Emit a return of the neutral member instead, and
keep the throw only for enums with no neutral value.
b. Drop an optional object whose required enum field cannot decode.
clientPayload is optional, but its format is a required
IapkitClientPayloadFormat, which has no neutral member. Rather than adding one,
emit the owner-field decode so an unreadable format yields null for the whole
payload — which is what the hand-written SDK parsers already do.
With (b) in place, IapkitClientPayloadFormat does not need an Unknown member.
Known wrong today (all reachable only through the generated decoders, which
#321 routed around rather than fixed):
libraries/flutter_inapp_purchase/lib/types.dart — throws ArgumentError for
state, store, and client-payload format.
libraries/godot-iap/addons/godot-iap/types.gd — assigns the raw string into
an enum-typed variable, a runtime type error.
packages/google/.../Types.kt and the kmp mirror — a missing or non-string
format silently defaults to Toml, so a JSON body would be read as TOML.
Scope: the Kotlin, Dart, C#, GDScript and TypeScript plugins under
packages/gql/codegen/plugins/, then bun run generate. Add a case per language
asserting an unknown value degrades instead of throwing.
Context: #321, and /docs/kit-compatibility for the policy this enforces.
IAPKit deploys from
mainwhile every SDK that decodes its responses is frozeninside published apps, so a value it adds later must degrade rather than fail a
purchase. #321 made that true by hand in six SDK parsers. The generated
decoders still throw, so the next parser someone writes gets it wrong again.
Fix it at the generator instead, in two parts. Neither adds an enum member, so
neither breaks an exhaustive
when/switchin consumer code.a. Degrade to the neutral member when the enum already declares one.
IapkitPurchaseStatehasUNKNOWNandIapStorehasUnknown, but thegenerated
fromJsonthrows anyway —packages/gql/codegen/plugins/kotlin.ts:230,dart.ts:187,csharp.ts:322. Emit a return of the neutral member instead, andkeep the throw only for enums with no neutral value.
b. Drop an optional object whose required enum field cannot decode.
clientPayloadis optional, but itsformatis a requiredIapkitClientPayloadFormat, which has no neutral member. Rather than adding one,emit the owner-field decode so an unreadable format yields
nullfor the wholepayload — which is what the hand-written SDK parsers already do.
With (b) in place,
IapkitClientPayloadFormatdoes not need anUnknownmember.Known wrong today (all reachable only through the generated decoders, which
#321 routed around rather than fixed):
libraries/flutter_inapp_purchase/lib/types.dart— throwsArgumentErrorforstate, store, and client-payload format.
libraries/godot-iap/addons/godot-iap/types.gd— assigns the raw string intoan enum-typed variable, a runtime type error.
packages/google/.../Types.ktand the kmp mirror — a missing or non-stringformatsilently defaults toToml, so a JSON body would be read as TOML.Scope: the Kotlin, Dart, C#, GDScript and TypeScript plugins under
packages/gql/codegen/plugins/, thenbun run generate. Add a case per languageasserting an unknown value degrades instead of throwing.
Context: #321, and
/docs/kit-compatibilityfor the policy this enforces.