diff --git a/generators/go-v2/ast/src/custom-config/BaseGoCustomConfigSchema.ts b/generators/go-v2/ast/src/custom-config/BaseGoCustomConfigSchema.ts index b8f29627c72e..a36e4157d9ee 100644 --- a/generators/go-v2/ast/src/custom-config/BaseGoCustomConfigSchema.ts +++ b/generators/go-v2/ast/src/custom-config/BaseGoCustomConfigSchema.ts @@ -24,7 +24,8 @@ export const baseGoCustomConfigSchema = z.object({ enableWireTests: z.boolean().optional(), exportAllRequestsAtRoot: z.boolean().optional(), customReadmeSections: z.array(CustomReadmeSectionSchema).optional(), - customPagerName: z.string().optional() + customPagerName: z.string().optional(), + oauthTokenOverride: z.boolean().optional() }); export type BaseGoCustomConfigSchema = z.infer; diff --git a/generators/go/cmd/fern-go-fiber/main.go b/generators/go/cmd/fern-go-fiber/main.go index 27e1fa6eeee6..9e2d3d7efcf7 100644 --- a/generators/go/cmd/fern-go-fiber/main.go +++ b/generators/go/cmd/fern-go-fiber/main.go @@ -34,6 +34,7 @@ func run(config *cmd.Config, coordinator *coordinator.Client) ([]*generator.File config.UseReaderForBytesRequest, config.GettersPassByValue, config.ExportAllRequestsAtRoot, + config.OAuthTokenOverride, config.Organization, config.Version, config.IrFilepath, diff --git a/generators/go/cmd/fern-go-model/main.go b/generators/go/cmd/fern-go-model/main.go index affbe27227e1..94075caada5b 100644 --- a/generators/go/cmd/fern-go-model/main.go +++ b/generators/go/cmd/fern-go-model/main.go @@ -34,6 +34,7 @@ func run(config *cmd.Config, coordinator *coordinator.Client) ([]*generator.File config.UseReaderForBytesRequest, config.GettersPassByValue, config.ExportAllRequestsAtRoot, + config.OAuthTokenOverride, config.Organization, config.Version, config.IrFilepath, diff --git a/generators/go/cmd/fern-go-sdk/main.go b/generators/go/cmd/fern-go-sdk/main.go index bcf4d3c1fdc5..f7f5b464be00 100644 --- a/generators/go/cmd/fern-go-sdk/main.go +++ b/generators/go/cmd/fern-go-sdk/main.go @@ -34,6 +34,7 @@ func run(config *cmd.Config, coordinator *coordinator.Client) ([]*generator.File config.UseReaderForBytesRequest, config.GettersPassByValue, config.ExportAllRequestsAtRoot, + config.OAuthTokenOverride, config.Organization, config.Version, config.IrFilepath, diff --git a/generators/go/internal/cmd/cmd.go b/generators/go/internal/cmd/cmd.go index b951839b9aa5..e76ff53e0b95 100644 --- a/generators/go/internal/cmd/cmd.go +++ b/generators/go/internal/cmd/cmd.go @@ -64,6 +64,7 @@ type Config struct { UseReaderForBytesRequest bool GettersPassByValue bool ExportAllRequestsAtRoot bool + OAuthTokenOverride bool Organization string CoordinatorURL string CoordinatorTaskID string @@ -235,6 +236,7 @@ func newConfig(configFilename string) (*Config, error) { UseReaderForBytesRequest: *customConfig.UseReaderForBytesRequest, GettersPassByValue: *customConfig.GettersPassByValue, ExportAllRequestsAtRoot: *customConfig.ExportAllRequestsAtRoot, + OAuthTokenOverride: *customConfig.OAuthTokenOverride, Organization: config.Organization, AlwaysSendRequiredProperties: *customConfig.AlwaysSendRequiredProperties, Whitelabel: config.Whitelabel, @@ -299,6 +301,7 @@ type customConfig struct { UseReaderForBytesRequest *bool `json:"useReaderForBytesRequest,omitempty"` GettersPassByValue *bool `json:"gettersPassByValue,omitempty"` ExportAllRequestsAtRoot *bool `json:"exportAllRequestsAtRoot,omitempty"` + OAuthTokenOverride *bool `json:"oauthTokenOverride,omitempty"` ClientName string `json:"clientName,omitempty"` ClientConstructorName string `json:"clientConstructorName,omitempty"` ImportPath string `json:"importPath,omitempty"` @@ -459,6 +462,9 @@ func applyCustomConfigDefaultsForV1(customConfig *customConfig) *customConfig { if customConfig.ExportAllRequestsAtRoot == nil { customConfig.ExportAllRequestsAtRoot = gospec.Ptr(false) } + if customConfig.OAuthTokenOverride == nil { + customConfig.OAuthTokenOverride = gospec.Ptr(false) + } if customConfig.UnionVersion == "" { customConfig.UnionVersion = "v1" } diff --git a/generators/go/internal/generator/config.go b/generators/go/internal/generator/config.go index 616b84ac755b..c6fb6e8e870d 100644 --- a/generators/go/internal/generator/config.go +++ b/generators/go/internal/generator/config.go @@ -28,6 +28,7 @@ type Config struct { UseReaderForBytesRequest bool GettersPassByValue bool ExportAllRequestsAtRoot bool + OAuthTokenOverride bool Organization string Version string IRFilepath string @@ -74,6 +75,7 @@ func NewConfig( useReaderForBytesRequest bool, gettersPassByValue bool, exportAllRequestsAtRoot bool, + oauthTokenOverride bool, organization string, version string, irFilepath string, @@ -105,6 +107,7 @@ func NewConfig( UseReaderForBytesRequest: useReaderForBytesRequest, GettersPassByValue: gettersPassByValue, ExportAllRequestsAtRoot: exportAllRequestsAtRoot, + OAuthTokenOverride: oauthTokenOverride, Version: version, IRFilepath: irFilepath, SnippetFilepath: snippetFilepath, diff --git a/generators/go/internal/generator/generator.go b/generators/go/internal/generator/generator.go index 681a30b86db0..4e427c83b63c 100644 --- a/generators/go/internal/generator/generator.go +++ b/generators/go/internal/generator/generator.go @@ -382,6 +382,7 @@ func (g *Generator) generate(ir *fernir.IntermediateRepresentation, mode Mode) ( ir.SdkConfig, g.config.ModuleConfig, g.config.Version, + g.config.OAuthTokenOverride, ); err != nil { return nil, err } diff --git a/generators/go/internal/generator/sdk.go b/generators/go/internal/generator/sdk.go index 635e0e10ea43..d9ad4e1d9759 100644 --- a/generators/go/internal/generator/sdk.go +++ b/generators/go/internal/generator/sdk.go @@ -290,6 +290,7 @@ func (f *fileWriter) WriteRequestOptionsDefinition( sdkConfig *ir.SdkConfig, moduleConfig *ModuleConfig, sdkVersion string, + oauthTokenOverride bool, ) error { importPath := path.Join(f.baseImportPath, "core") f.P("// RequestOption adapts the behavior of the client or an individual request.") @@ -329,6 +330,9 @@ func (f *fileWriter) WriteRequestOptionsDefinition( typeReferenceToGoType(authScheme.Header.ValueType, f.types, f.scope, f.baseImportPath, importPath, false), ) } + if authScheme.Oauth != nil && oauthTokenOverride { + f.P("Token string") + } } for _, header := range headers { if !shouldGenerateHeader(header, f.types) { @@ -370,7 +374,7 @@ func (f *fileWriter) WriteRequestOptionsDefinition( return err } f.P() - return f.writeRequestOptionStructs(auth, headers, len(idempotencyHeaders) > 0) + return f.writeRequestOptionStructs(auth, headers, len(idempotencyHeaders) > 0, oauthTokenOverride) } // Generate the ToHeader method. @@ -417,6 +421,11 @@ func (f *fileWriter) WriteRequestOptionsDefinition( f.P(`header.Set("`, header.Name.WireValue, `", fmt.Sprintf("`, prefix, `%v",`, value, "))") f.P("}") } + if authScheme.Oauth != nil && oauthTokenOverride { + f.P(`if r.Token != "" {`) + f.P(`header.Set("Authorization", "Bearer " + r.Token)`) + f.P("}") + } } for _, header := range headers { valueTypeFormat := formatForValueType(header.ValueType, f.types) @@ -455,7 +464,7 @@ func (f *fileWriter) WriteRequestOptionsDefinition( f.P() - if err := f.writeRequestOptionStructs(auth, headers, len(idempotencyHeaders) > 0); err != nil { + if err := f.writeRequestOptionStructs(auth, headers, len(idempotencyHeaders) > 0, oauthTokenOverride); err != nil { return err } @@ -493,6 +502,7 @@ func (f *fileWriter) writeRequestOptionStructs( auth *ir.ApiAuth, headers []*ir.HttpHeader, asIdempotentRequestOption bool, + oauthTokenOverride bool, ) error { if err := f.writeOptionStruct("BaseURL", "string", true, asIdempotentRequestOption); err != nil { return err @@ -557,6 +567,11 @@ func (f *fileWriter) writeRequestOptionStructs( return err } } + if authScheme.Oauth != nil && oauthTokenOverride { + if err := f.writeOptionStruct("Token", "string", true, asIdempotentRequestOption); err != nil { + return err + } + } } } diff --git a/generators/go/sdk/versions.yml b/generators/go/sdk/versions.yml index a3166cb4497a..05af4400431b 100644 --- a/generators/go/sdk/versions.yml +++ b/generators/go/sdk/versions.yml @@ -1,5 +1,15 @@ # yaml-language-server: $schema=../../../fern-versions-yml.schema.json +- version: 1.19.0 + changelogEntry: + - summary: | + Add support for OAuth token override via the `oauthTokenOverride` config option. + When enabled, users can provide a pre-generated bearer token directly via the `WithToken` + option function, bypassing the OAuth client credentials flow. + type: feat + createdAt: "2025-12-08" + irVersion: 60 + - version: 1.18.4 changelogEntry: - summary: |