feat(smithy): provides fixes based on C# spike#55
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (1)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
|
@copilot resolve the merge conflicts in this pull request |
…ithy-models-findings-csharp # Conflicts: # smithy/openapi/FunctionsService.openapi.json
Merged |
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