@@ -29,6 +29,11 @@ type ClientOptionsBuilder struct {
2929 // Logger is the slog logger to use for the client. If set, it will be
3030 // wrapped with the SDK's structured logger adapter.
3131 Logger * slog.Logger
32+
33+ // PayloadCodec is populated by Build when a remote payload codec is
34+ // configured. Callers can use it to decode payloads outside the gRPC
35+ // interceptor chain (e.g. payloads nested inside opaque proto bytes).
36+ PayloadCodec converter.PayloadCodec
3237}
3338
3439type oauthCredentials struct {
@@ -248,13 +253,18 @@ func (b *ClientOptionsBuilder) Build(ctx context.Context) (client.Options, error
248253 if err != nil {
249254 return client.Options {}, fmt .Errorf ("invalid codec headers: %w" , err )
250255 }
251- interceptor , err := newPayloadCodecInterceptor (
256+ payloadCodec := newRemotePayloadCodec (
252257 profile .Namespace , profile .Codec .Endpoint , profile .Codec .Auth , codecHeaders )
258+ interceptor , err := converter .NewPayloadCodecGRPCClientInterceptor (
259+ converter.PayloadCodecGRPCClientInterceptorOptions {
260+ Codecs : []converter.PayloadCodec {payloadCodec },
261+ })
253262 if err != nil {
254263 return client.Options {}, fmt .Errorf ("failed creating payload codec interceptor: %w" , err )
255264 }
256265 clientOpts .ConnectionOptions .DialOptions = append (
257266 clientOpts .ConnectionOptions .DialOptions , grpc .WithChainUnaryInterceptor (interceptor ))
267+ b .PayloadCodec = payloadCodec
258268 }
259269
260270 // Set connect timeout for GetSystemInfo if provided.
@@ -278,16 +288,17 @@ func parseKeyValuePairs(pairs []string) (map[string]string, error) {
278288 return result , nil
279289}
280290
281- // newPayloadCodecInterceptor creates a gRPC interceptor for remote payload codec.
282- func newPayloadCodecInterceptor (
291+ // newRemotePayloadCodec constructs a remote payload codec from the configured endpoint,
292+ // auth, and headers. The returned codec can be used both inside a gRPC interceptor and
293+ // to decode payloads nested inside opaque proto bytes (e.g. system Nexus operation inputs).
294+ func newRemotePayloadCodec (
283295 namespace string ,
284296 codecEndpoint string ,
285297 codecAuth string ,
286298 codecHeaders map [string ]string ,
287- ) (grpc. UnaryClientInterceptor , error ) {
299+ ) converter. PayloadCodec {
288300 codecEndpoint = strings .ReplaceAll (codecEndpoint , "{namespace}" , namespace )
289-
290- payloadCodec := converter .NewRemotePayloadCodec (
301+ return converter .NewRemotePayloadCodec (
291302 converter.RemotePayloadCodecOptions {
292303 Endpoint : codecEndpoint ,
293304 ModifyRequest : func (req * http.Request ) error {
@@ -302,11 +313,6 @@ func newPayloadCodecInterceptor(
302313 },
303314 },
304315 )
305- return converter .NewPayloadCodecGRPCClientInterceptor (
306- converter.PayloadCodecGRPCClientInterceptorOptions {
307- Codecs : []converter.PayloadCodec {payloadCodec },
308- },
309- )
310316}
311317
312318func (c * oauthCredentials ) getToken (ctx context.Context ) (string , error ) {
0 commit comments