Skip to content

fix(openapiv3,ts): map Struct/Value/ListValue to their protojson JSON projection - #233

Open
SebastienMelki wants to merge 1 commit into
mainfrom
fix/issue-230-structpb-json-projection
Open

fix(openapiv3,ts): map Struct/Value/ListValue to their protojson JSON projection#233
SebastienMelki wants to merge 1 commit into
mainfrom
fix/issue-230-structpb-json-projection

Conversation

@SebastienMelki

Copy link
Copy Markdown
Owner

Summary

  • google.protobuf.Struct, Value, and ListValue were emitted by openapiv3 and the TS generators (tscommon/tsclientgen/tsservergen) in their protobuf descriptor shape (internal oneof/map fields) instead of the JSON they actually serialize to under protojson — a plain object, any JSON value, and a plain array, respectively.
  • Same class of defect #226 fixed for the wrapper types (DoubleValue, StringValue, ...); this extends the same mechanism to Struct/Value/ListValue.
  • Adds internal/annotations/structpb_types.go with shared detection helpers (IsStructMessage, IsValueMessage, IsListValueMessage, IsStructWellKnownMessage, IsStructWellKnownField), consumed by both generators.
  • Mapping:
    Type OpenAPI schema TypeScript type
    Struct {type: object, additionalProperties: true} Record<string, unknown>
    Value {} (any value) unknown
    ListValue {type: array, items: {}} unknown[]
  • Covers singular fields, repeated fields, map values, direct RPC input/output, and (openapiv3 only) SSE streaming.
  • Go (httpgen/clientgen) and Python (pyclientgen) were unaffected: structpb already has correct protojson semantics natively in Go, and pyclientgen already special-cased these three types correctly.

Fixes #230

Test plan

  • go build ./...
  • gofmt -l . (clean)
  • go vet ./...
  • go test ./internal/annotations/... ./internal/openapiv3/... ./internal/tscommon/... ./internal/tsclientgen/... ./internal/tsservergen/... ./internal/httpgen/...
  • New golden fixtures (structpb_types.proto) added for openapiv3 (incl. direct-WKT RPC + SSE) and ts-client/ts-server (incl. direct-WKT RPC as request/response type); UPDATE_GOLDEN=1 output eyeballed to confirm no Struct/Value/ListValue descriptor-shaped schema/interface leaks into generated output
  • No pre-existing golden files changed (no regressions)

🤖 Generated with Claude Code

… projection

google.protobuf.Struct, Value, and ListValue were emitted in openapiv3 and the
TS generators (tscommon/tsclientgen/tsservergen) as their protobuf descriptor
shape (the internal oneof/map fields) instead of the JSON they actually
serialize to under protojson: a plain object, any JSON value, and a plain
array respectively. This is the same class of defect #226 fixed for the
wrapper types (DoubleValue, StringValue, ...), just not yet extended to these
three well-known types.

Adds internal/annotations/structpb_types.go with shared detection helpers,
and mirrors the existing wrapper-type special-casing in both generators:
Struct -> {type: object, additionalProperties: true} / Record<string, unknown>
Value  -> {} (any value) / unknown
ListValue -> {type: array, items: {}} / unknown[]

Covers singular, repeated, and map-value fields, direct RPC input/output, and
(openapiv3) SSE streaming. Go (httpgen/clientgen) and Python (pyclientgen)
were unaffected -- structpb already has correct protojson semantics natively
in Go, and pyclientgen already special-cased these types correctly.

Fixes #230

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 30.46%. Comparing base (a2b2e8e) to head (de90934).

Files with missing lines Patch % Lines
internal/tscommon/types.go 0.00% 13 Missing and 1 partial ⚠️
internal/annotations/structpb_types.go 0.00% 12 Missing ⚠️
internal/tscommon/imports.go 0.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #233      +/-   ##
==========================================
- Coverage   30.54%   30.46%   -0.08%     
==========================================
  Files          67       68       +1     
  Lines       11404    11432      +28     
==========================================
  Hits         3483     3483              
- Misses       7750     7776      +26     
- Partials      171      173       +2     
Flag Coverage Δ
unittests 30.46% <0.00%> (-0.08%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

🔍 CI Pipeline Status

Lint: success
Test: success
Coverage: success
Build: success
Integration: success


📊 Coverage Report: Available in checks above
🔗 Artifacts: Test results and coverage reports uploaded

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

openapiv3: google.protobuf.Struct / Value / ListValue emitted in descriptor shape instead of their JSON projection

1 participant