feat(ts-sdk): support optional username/password in basic auth when configured in IR#14406
feat(ts-sdk): support optional username/password in basic auth when configured in IR#14406Swimburger wants to merge 11 commits intomainfrom
Conversation
…onfigured in IR Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.
Tip: disable this comment in your organization's Code Review settings.
…d flag Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…-field omit fix Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…c-auth-optional-ts-sdk
…e empty string internally Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Generator emits unused USERNAME_PARAM/PASSWORD_PARAM constants for omitted auth fields
In writeConstants at BasicAuthProviderGenerator.ts:159-170, both USERNAME_PARAM and PASSWORD_PARAM are always emitted regardless of omit flags. When a field is omitted (e.g. passwordOmit: true), the corresponding constant is never referenced in canCreate, getAuthRequest, or the AuthOptions type — it becomes dead code.
The generated seed output at seed/ts-sdk/basic-auth-optional/src/auth/BasicAuthProvider.ts:7 confirms this: const _PASSWORD_PARAM = "password" as const; — the linter renamed it with an underscore prefix because it's unused. The fix would be to conditionally skip generating the constant when the corresponding omit flag is true.
(Refers to lines 169-170)
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Valid observation about the unused constant. This is a minor issue — the generated biome config already renames it with an underscore prefix (_PASSWORD_PARAM), and the constant is still referenced in the module namespace for the AUTH_CONFIG_ERROR_MESSAGE_PASSWORD string template in the non-omit case. Conditionally skipping the constant would require tracking which fields are omitted across both writeConstants and writeOptions, adding complexity for a cosmetic improvement. I'll leave this as-is unless the maintainer wants it addressed.
...rators/typescript/sdk/client-class-generator/src/auth-provider/BasicAuthProviderGenerator.ts
Show resolved
Hide resolved
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…teral property names Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Description
Adds conditional support for omitting username/password in basic auth for the TypeScript SDK generator. When
usernameOmitorpasswordOmitflags are set in the IR'sBasicAuthScheme, the corresponding field is completely removed from the generated SDK'sAuthOptionstype — not just made optional. Internally, the omitted field is treated as an empty string when encoding the auth header (base64(username:password)with the colon always present).Default behavior (both required) is preserved when no omit flags are set.
Split from #14378 (one PR per generator).
Changes Made
Generator (
BasicAuthProviderGenerator.ts)getAuthOptionsProperties: conditionally excludes each field from theAuthOptionstype entirely when its corresponding omit flag is set (field is removed, not made optional)generateCanCreateStatements: per-field checks — omittable fields always satisfycanCreate(returntrue), required fields must be presentgenerateGetAuthRequestStatements: refactored intobuildNullCheckshelper — omitted fields use""directly instead of reading from options; null checks are only generated for non-omitted fields; declarations and null checks are interleaved to preserve short-circuit evaluation orderCore utility (
BasicAuth.ts)username?: string; password?: stringunconditionallytoAuthorizationHeaderuses?? ""fallbacks and returnsundefinedwhen both are empty stringsTests & fixtures
basic-auth-optionaltest fixture withpassword: omit: trueseed/ts-sdk/basic-auth-optional/seed/ts-sdk/basic-auth/output (reflects widenedBasicAuth.tsinterface)Changelog
versions.yml: new 3.61.1 entry (bumped past 3.61.0-rc.0 from main)Updates since last revision
buildNullChecksnow interleaves declaration and null-check for each field (username decl → username null check → password decl → password null check), preserving the original short-circuit behavior where the password supplier is never evaluated if the username is null. Previously, both declarations were emitted before both null checks.basic-auth-optionalfixture to reflect interleaved null check pattern.Testing
BasicAuth.test.ts: 5 cases covering all credential combinations)basic-auth-optionalfixturebasic-authseed output updated and verifiedLint PR title,Validate IR Version Consistency)__snapshots__/AuthProviders.test.ts.snapfile in the cumulative diff showsconst username = ...; const password = ...; if (username == null) ...; if (password == null) ...;(both declarations then both checks). However, after the interleave fix the generator now producesconst username = ...; if (username == null) ...; const password = ...; if (password == null) ...;(interleaved). Verify the snapshot tests pass — if they don't, the snapshot file needs regeneration.BasicAuth.tsinterface is widened unconditionally: Every generated TS SDK (not just those with omit flags) will now haveusername?: string; password?: stringin the core utility. The generator controls what appears inAuthOptions, so the runtime behavior is guarded — but this does widen the type contract for downstream consumers who importBasicAuthdirectly.toAuthorizationHeader({username: "", password: ""})now returnsundefinedinstead ofBasic Og==. This affects theauthHeader != nullguard in generated code.usernameOmitandpasswordOmitare true,canCreate()always returnstrueandgetAuthRequesthardcodes both to"", producingBasic Og==— buttoAuthorizationHeaderthen returnsundefinedsince both are empty. Verify this edge case is acceptable.seed/ts-sdk/basic-auth/diff: The existing (non-optional) fixture output changed due to the unconditionalBasicAuth.tswidening. Confirm the generated client behavior is still correct for the required-fields case.Link to Devin session: https://app.devin.ai/sessions/0786b963284f4799acb409d5373cde0a
Requested by: @Swimburger