feat(smithy): provides fixes based on C# spike#55
Draft
Tr00d wants to merge 1 commit into
Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Model fixes from the C# codegen spike (SDK-1107)
The C# spike (supabase-community/supabase-csharp#273) generated clients from these models with two toolchains (NSwag 14.7.1, Kiota 1.32.4) and ran both against a live local platform (
supabase start). The runs surfaced defects in the models that static review had not caught. Both generators translated the models faithfully — every issue below is a model/conversion gap, not a generator bug — so each fix propagates to every SDK on regeneration. This PR fixes what is fixable, documents what is not, and was validated by rerunning the spike against the fixed artifacts (results at the bottom).1. List responses are wrapped in an envelope the API does not send
Issue. The model wraps list outputs in a structure (
ListBucketsOutput { items: BucketList }), producing response schemas like{"items": [...]}. The live API returns bare arrays:Impact. Generated clients fail in opposite ways: Kiota deserializes the mismatch silently and returns an empty list — no error, wrong data on a green call; NSwag throws on deserialization. Affects
ListBuckets,ListObjects,DeleteObjects,CreateSignedUrls.Why. Smithy operation outputs must be structures, and restJson1 rejects
@httpPayloadon list members ("AWS Protocols only support binding the following shape types to the payload: string, blob, structure, union, and document") — a bare-array response is inexpressible in the model.Fix.
patch-openapi.pyunwraps single-itemsenvelopes into top-level array schemas (the same mechanism already used for multipart). The model documents the limitation onListBucketsOutput.2. Optional scalar fields are not nullable
Issue. Non-
@requiredmembers convert to plain non-nullable schemas. Generators for languages with non-nullable value types (C#, Kotlin) map them to types whose default is a real value (0/false) and serialize it.Impact (observed live).
CreateBucketsentfile_size_limit: 0→ the bucket rejects every upload with 413.ListObjectssentlimit: 0→ 400.Fix.
patch-openapi.pyaddsnullable: trueto optionalnumber/integer/booleanproperties, so generators emit optional value types (long?,int?). Scoped to scalars deliberately: blanket-nullable would claimnullis a valid value for fields where the server rejects it (e.g.sortBymust be an object or absent).3. Streaming bodies convert to
$ref+format: byteIssue.
@streaming blob/ blob payloads emit$ref'd schemas withformat: byte(base64). Generators then buffer and base64-encode instead of streaming (NSwag emitsbyte[]; swift-openapi-generator needsbinaryto emitHTTPBody).Fix. All
application/octet-streamrequest/response bodies are now inline{"type": "string", "format": "binary"}— Functions (all five methods, request + response), TUSUploadChunk, and the Database row payloads. Generalises the previous UploadChunk-only patch.4. Greedy path label leaks
+into OpenAPIIssue. Smithy's
{wildcardPath+}greedy label carries the RFC-6570+into path templates and parameter names — invalid identifiers in generated code (24 C# compile errors; SDK teams had to pre-patch the spec locally before generating).Fix.
patch-openapi.pystrips the+from path templates and parameter names. Consumers can now feed the committed artifacts to generators unmodified.5. Build is not reproducible from a fresh clone
Issue.
smithy-build.jsonresolved dependencies only fromfile://~/.m2/repository, sosmithy buildfails on any machine without a pre-warmed local Maven cache.Fix. Added Maven Central as a fallback repository.
Also in this PR
*ResponseContentenvelopes,*Payloadbyte schemas) are removed from the generated output.smithy build+patch-openapi.py).Known gaps, not addressed here
200only — the API can return204with an empty body; clients currently handle this in hand-written code.cacheControl,metadata) are already optional on this branch — no change needed.Validation — spike rerun against the fixed artifacts
Both generators were rerun on the regenerated artifacts (no local pre-patching needed anymore), both spike projects compile with 0 errors, and the live harnesses were rerun against
supabase start:ListBucketsreturns real counts (previously silently 0),ListObjectscounts the uploaded objectListBucketsdeserializes (previously threw);CreateBucketworks withoutfile_size_limit(server accepts null-as-unset — no more 413 bucket); streaming upload worksListObjects400: NSwag serializes unset members as explicit nulls and the server rejectslimit: null. Generator-side serialization behaviour (WhenWritingNull+ nullable value types in client config), not a model defectStreambody + streamedFileResponseviaResponseHeadersRead(previously buffered base64byte[]); Kiota unchanged (Task<Stream>). Live Functions run still pending (needs a deployed edge function)🤖 Generated with Claude Code