Skip to content

Bring TypeScript client emission to parity for spec-derived servers and multipart bodies #7

Description

@meoyawn

Context

#5 and #6 removed hidden YouTube behavior and added generic OpenAPI 3.2 support for document/operation servers plus ordered multipart/related bodies. The shared parser and Go emitter now consume those declarations, but the TypeScript client emitter does not.

This is not currently blocking listenbox/listenbox2#29 because Listenbox generates the YouTube client in Go. It is an Oasmith client correctness and language-parity gap.

Current failures

Generating a TypeScript client from the corrected Listenbox YouTube contract exposes three problems:

  1. operationId: youtube.videos.insert is emitted directly into class method declarations, producing invalid TypeScript such as youtube.videos.insertRequest(...). Oxfmt fails with Expected ; but found ..
  2. Document-level and operation-level servers are ignored. The generated client always constructs requests from options.baseURL ?? "", so it cannot use the declared https://www.googleapis.com upload server or distinguish an operation server from the document default.
  3. Request parameter extraction only consumes application/json through JSONRequestSchema(). The declared multipart/related body is silently omitted: no metadata argument, media argument, body, boundary, or content type is generated.

The uploadType const is already represented correctly as the TypeScript literal type "multipart".

The regression added in #6 does not catch the first failure because it tests youtubeVideosInsert rather than the exact dotted operation ID. Multipart and operation-server behavior are covered only for Go.

Required end state

  • Derive valid TypeScript symbol names from arbitrary OpenAPI operation IDs while retaining operationId only as operation identity.
  • Honor the first document server as the generated default.
  • Honor an operation-level server when no explicit caller base URL override is supplied.
  • Keep an explicit caller base URL authoritative for fixture and proxy use.
  • Generate ordered multipart bodies generically from the declared media type, prefixItems, and prefixEncoding; do not add provider detection or YouTube-specific code.
  • Preserve declared part ordering, part content types, the complete binary media body, and the declared outer multipart/related content type.
  • Reject unsupported request-body shapes during generation rather than silently emitting a request without its required body.

Regression proof

Add a TypeScript fixture using the corrected YouTube upload contract and prove:

  • the generated source parses and typechecks with exact operationId: youtube.videos.insert
  • the request targets POST https://www.googleapis.com/upload/youtube/v3/videos
  • uploadType=multipart and required query parameters are emitted
  • metadata is the first part and media is the second complete part
  • both part content types and the outer multipart/related boundary are correct
  • an explicit base URL overrides the operation server
  • changing only the operation ID changes symbols, not endpoints, headers, statuses, or protocols
  • no resumable session, status probe, 308, Range, or Content-Range behavior is emitted

Update TypeScript goldens and documentation as needed. All Oasmith checks must pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions