feat: auto-generate harmonised, ergonomic SDKs across 12 languages#35
Draft
mridang wants to merge 771 commits into
Draft
feat: auto-generate harmonised, ergonomic SDKs across 12 languages#35mridang wants to merge 771 commits into
mridang wants to merge 771 commits into
Conversation
️✅ There are no secrets present in this pull request anymore.If these secrets were true positive and are still valid, we highly recommend you to revoke them. 🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request. |
5166131 to
3cb26d3
Compare
1113be3 to
bc8fd3d
Compare
e134b80 to
f61e4ed
Compare
ace5c59 to
9039e83
Compare
mridang
added a commit
that referenced
this pull request
May 4, 2026
…, #35) - #2: Make Go ApiResult.Data nullable (*T pointer type) - #5: Dart caCertPath defaults to null instead of empty string - #9: Add toCookieValue to ObjectSerializer in all 12 languages - #14: Dart DefaultApiClient uses caCertPath with SecurityContext - #15: Fix Dart redirect handling (autoRedirect + maxRedirects) - #18: Route Dart/Rust path params through ValueSerializer.serializeStyled() - #26: Add default value support in Go, Rust, Swift, Dart, Elixir models - #35: Update Go version to 1.26 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
58765c7 to
df347a4
Compare
mridang
added a commit
that referenced
this pull request
May 4, 2026
…, #35) - #2: Make Go ApiResult.Data nullable (*T pointer type) - #5: Dart caCertPath defaults to null instead of empty string - #9: Add toCookieValue to ObjectSerializer in all 12 languages - #14: Dart DefaultApiClient uses caCertPath with SecurityContext - #15: Fix Dart redirect handling (autoRedirect + maxRedirects) - #18: Route Dart/Rust path params through ValueSerializer.serializeStyled() - #26: Add default value support in Go, Rust, Swift, Dart, Elixir models - #35: Update Go version to 1.26 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
df347a4 to
642ef91
Compare
mridang
added a commit
that referenced
this pull request
May 4, 2026
…, #35) - #2: Make Go ApiResult.Data nullable (*T pointer type) - #5: Dart caCertPath defaults to null instead of empty string - #9: Add toCookieValue to ObjectSerializer in all 12 languages - #14: Dart DefaultApiClient uses caCertPath with SecurityContext - #15: Fix Dart redirect handling (autoRedirect + maxRedirects) - #18: Route Dart/Rust path params through ValueSerializer.serializeStyled() - #26: Add default value support in Go, Rust, Swift, Dart, Elixir models - #35: Update Go version to 1.26 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
642ef91 to
6713b61
Compare
mridang
added a commit
that referenced
this pull request
May 5, 2026
…, #35) - #2: Make Go ApiResult.Data nullable (*T pointer type) - #5: Dart caCertPath defaults to null instead of empty string - #9: Add toCookieValue to ObjectSerializer in all 12 languages - #14: Dart DefaultApiClient uses caCertPath with SecurityContext - #15: Fix Dart redirect handling (autoRedirect + maxRedirects) - #18: Route Dart/Rust path params through ValueSerializer.serializeStyled() - #26: Add default value support in Go, Rust, Swift, Dart, Elixir models - #35: Update Go version to 1.26 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
6713b61 to
f6d73f3
Compare
mridang
added a commit
that referenced
this pull request
May 5, 2026
…, #35) - #2: Make Go ApiResult.Data nullable (*T pointer type) - #5: Dart caCertPath defaults to null instead of empty string - #9: Add toCookieValue to ObjectSerializer in all 12 languages - #14: Dart DefaultApiClient uses caCertPath with SecurityContext - #15: Fix Dart redirect handling (autoRedirect + maxRedirects) - #18: Route Dart/Rust path params through ValueSerializer.serializeStyled() - #26: Add default value support in Go, Rust, Swift, Dart, Elixir models - #35: Update Go version to 1.26 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
b4d5152 to
1c15042
Compare
conn is provably non-nil under the respond_to?(:close) guard, so the safe-navigation operator is redundant (Qodana RubyRedundantSafeNavigation). Matches the existing non-safe-navigation close on response bodies.
Harmonize base-class construction with java/kotlin/csharp/php, where the abstract base API constructor is already protected. node's BaseApi ctor becomes protected (concrete *Api classes keep their own public ctor); swift's BaseApi init becomes internal and each concrete *Api gains a public override init delegating to super. Consumers still construct the concrete classes; the base is no longer publicly instantiable.
php: drop unnecessary curly braces in string interpolation, redundant constructor parentheses, and a useless parenthesis group. ruby: use %w for plain string-literal arrays in tests. python: restructure _sanitize_for_serialization to a single return so all paths return a value. No behaviour change; verified by the php/ruby/python build, lint, static-analysis and client specs.
The facade (clientClassName) now exposes a static withAuthenticator(Authenticator) entry point so the whole class can be generated; bespoke authenticators are passed in rather than requiring a hand-written facade per SDK.
When clientClassName equals the root module segment (e.g. Zitadel inside module Zitadel::Client), an unanchored reference like Zitadel::Client::X resolves to the facade class and NameErrors. Anchor production references with a leading :: and make the facade RBS honour clientClassName.
Node derived its default User-Agent from the hardcoded placeholder "openapi-typescript-client" instead of the npm package name, and Go and Rust left the User-Agent unset (nil/None) by default. The other nine SDKs already inject "<pkg>/<ver> (<lang>)". Node now derives the default from npmName, and Go and Rust inject the same branded <pkg>/<ver> (<lang>) default that every other SDK uses. The Go and Rust default-User-Agent tests assert the branded value instead of nil/None.
Emit google.protobuf.Duration "<seconds>s" form (e.g. "3600s") which
Zitadel's API requires; ISO-8601 ("PT1H") was rejected as HTTP 400.
Mask token / password / client secret / api key / implicit access token as *** in the default string, debug, repr and inspect representations of every generated authenticator, across all 12 languages. Previously only php, ruby, node and elixir masked comprehensively; java, python, csharp, rust, kotlin, swift, dart and go leaked secrets through toString / Debug / __repr__. Because the masking now lives in the templates, regeneration re-adds it, so the generated BearerAuthenticator and scheme-named authenticators stay masked and idempotent instead of being reverted on every run. Redaction assertions were added to the generated authenticator test templates so they survive the prune step.
The redaction assertions belong in each authenticator's own test file in the consuming SDKs, not sprinkled across the generated per-authenticator test templates under ad-hoc method names. Remove them from the templates and regenerate the goldens; the secret masking itself stays in the authenticator templates.
Each per-authenticator test template now carries one consistently-named redaction test asserting the secret is masked as *** in the authenticator's default string representation, mirroring the per-authenticator tests in the consuming SDKs. Also make the Java BasicAuthenticator mask uniform (*** instead of <redacted>) so the marker matches every other authenticator.
…assertion The protobuf-duration migration left three test templates referencing the removed ISO-8601 API: the Swift ApiErrorTests used ISO8601DurationError and the Dart object_serializer_test used parseIso8601Duration / formatIso8601Duration / Iso8601DurationFormatException. Point them at the protobuf-duration API and rewrite the Dart duration cases to protobuf-JSON literals (e.g. "5400s"). Elixir redacts secrets by omission via @derive {Inspect, except: ...} rather than a *** marker, so its redaction tests now assert the secret value is absent instead of asserting a *** placeholder.
The protobuf-duration migration left ISO-8601 duration assertions in the Swift, Dart and Elixir test templates (the serializer emits "5400s" / "0s" / "-300s", not "PT1H30M"). Rewrite every duration test in those languages to protobuf-JSON values and assertions; the reject cases now feed ISO-8601 strings and expect a parse error. Verified locally: Swift, Dart and Elixir ClientSpec all pass.
…ements Structural invariants (one source file = one test file; identical docs/shape; idempotency), a 10th test-parity dimension, per-finding why_not_surfaced + why_not_caught fields, multi-round loop-until-dry, and a hard WONTFIX deny-list.
…/AK/AU-resid/N1) Code fixes: csharp/node/swift/elixir AL decompression-error wrapping; node+dart N1 redirect body-replay guard scoped to 307/308; php AU-resid discriminator throw. Identical canonical tests for all 5 findings added across all 12 SDKs per the fix-time parity rule. Goldens not yet regenerated.
swift: AL decompression guard now gates on gzip magic bytes (Linux URLSession auto-decompresses but leaves the Content-Encoding header, so the residual-header heuristic wrongly threw on every response); platform-guarded zlib decode. rust/elixir: N1 302-proceeds test asserted the guard predicate deterministically instead of a chasm round-trip (chasm can't model https->http; returned 405).
…ats (D1/U1/U2/D2) D1: standalone Bearer + ApiKey authenticator tests in the 11 non-java SDKs. U1: ServerConfiguration + ServerVariable tests across all 12. U2: ApiResult tests across all 12. D2: README Caveats section added to java/kotlin/csharp/python/rust. Each new test registered in its Better<Lang>Codegen; all 12 ClientSpecs green.
The Gap AL guard used full-line // comments in DefaultApiClient; the swift and node FormattingSpec (generatedCodeShouldNotContainInlineComments) require block /* */ comments in generated production code. Convert them; behaviour unchanged.
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.
Description
Adds 7 new language generators (Kotlin, Go, Rust, Dart, Swift, Elixir, C#) alongside the existing 5 (Java, Python, Ruby, PHP, Node/TypeScript) to produce fully harmonised, ergonomic client SDKs from any OpenAPI 3.0 spec. Every generated SDK shares the same architecture: BaseApi, DefaultApiClient, ObjectSerializer, ValueSerializer, HeaderSelector, Configuration, structured exceptions, per-operation Options classes, authentication (API key, Basic, Bearer, OAuth2), OpenTelemetry propagation, HTTP compression, TLS/proxy transport options, binary upload/download, and per-operation server overrides.
Motivation and Context
The default OpenAPI Generator templates produce inconsistent, non-idiomatic code across languages. This PR replaces them with a unified set of Mustache templates that generate production-grade SDKs on par with hand-written clients from Stripe, Stainless, or Speakeasy — fully linted, statically analysed, formatted, and integration-tested in Docker.
How Has This Been Tested?
All 12 SDKs are generated on-the-fly during the Maven build. Each SDK runs a full test suite inside Docker covering unit tests, integration tests against a live Petstore mock, formatting checks, linting, and static analysis. Regression tests for HeaderSelector and ValueSerializer ensure cross-language parity.
Checklist