Repository navigation
fix(downgrader): drop the content keywords of an untyped schema with subschemas in 3.0 - #149
Conversation
…subschemas in 3.0 An untyped schema with `contentMediaType` gained `format: binary` and `type: string`, even when a `$ref`, `allOf`, `anyOf`, `oneOf`, `properties` or `items` beside it showed it holds an object, as Itential's adapter documents mark JSON and XML bodies with their media type. In 3.0 nothing matched it, and tools read the body as a file upload. Such a schema now drops the content keywords, as one with `type: object` already did. Bare file parts keep the binary string. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVaw7RSkvUE8NjM89RakVV
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
ℹ️ No critical issues — the core fix is correct. One same-class omission noted inline.
Reviewed changes
- Predicate for untyped content-keyword schemas —
hasSubschemas(v3.1-to-v3.0.ts:1090) gates theformat/type: "string"injection on$ref,allOf,anyOf,oneOf,properties,items; the rest of the content-keyword handling is unchanged. - README row — documents that the keywords are dropped (rather than turned into a binary string) when the schema holds subschemas.
- Test — covers all six keywords, plus the bare
{ $ref, contentMediaType }case.
The change is correct and well-targeted: the content keywords are string-only annotations in 2020-12, so forcing type: "string" on a schema that already describes an object/array via subschemas both rejected values the source accepted and made 3.0 tools read the body as a file upload. I ran vitest run packages/downgrader/tests/v3.1-to-v3.0.test.ts (113 passing) and separately probed the predicate.
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
|
Correction to my review above: the inline suggestion attached to my first review ( schema.properties !== undefined ||
schema.items !== undefined ||
schema.prefixItems !== undefinedRationale (unchanged): Otherwise the fix is sound and the tests pass (
|
… schema A tuple with no `items`, written with `prefixItems` alone, still gained `format: binary` and `type: string` from `contentMediaType`, while one with `items: false` beside it did not. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVaw7RSkvUE8NjM89RakVV
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
prefixItemsadded to the subschema predicate —hasSubschemas(v3.1-to-v3.0.ts:1092) now also returns true forprefixItems, so an untyped schema with a content keyword and a tuple keeps its converteditemsinstead of being forced totype: "string".- Test — covers
{ prefixItems: [...], contentMediaType }yielding{ items: {} }, completing the set of keywords the earlier review noted as missing. - README row — now lists
prefixItemsamong the keywords that suppress thetype: "string"injection.
This delta directly addresses the one prior inline thread (prefixItems omitted from hasSubschemas); the author's fix is correct — the tuple is an array, not a binary string, so dropping the content keywords is the right outcome. The full diff remains well-targeted, and the change is only consulted for untyped schemas. Ran vitest run packages/downgrader/tests/v3.1-to-v3.0.test.ts (113 passing, including the new case).
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Requested by dinwwwh · project thread
What
Some real 3.1 documents mark a JSON or XML body schema with its media type:
{ "allOf": [{ "$ref": "#/components/schemas/AbuseTicketCreate" }, { "description": "..." }], "contentMediaType": "application/json" }In 2020-12,
contentMediaTypeonly applies to strings, so this is just the object. The schema has notype, sofinishSchemagave itformat: "binary"andtype: "string". In 3.0 nothing matched that (a value had to be a string and the object at once), and tools read the body as a file upload. A bare{ $ref, contentMediaType }went the same way.Change
An untyped schema gains
formatandtype: "string"from the content keywords only when it has none of$ref,allOf,anyOf,oneOf,properties,itemsorprefixItems. Otherwise the content keywords are just dropped, as they already were besidetype: "object". Bare file parts such as{ contentMediaType: "image/png" }keep becoming a binary string. The README row forcontentEncodingandcontentMediaTypesays so; the Limitations line on untyped schemas gainingtype: "string"still holds as written.Checks
pnpm run check,pnpm testpass, coverage stays 100%, no snapshot changes.@itentialopensource/adapter-godaddy1.0.12,report/adapter-openapi.yaml, 3.1.0):format: binarybesideallOfgoes from 606 to 0, and request bodies that were binary strings from 21 to 0. The 594 left are bare{ contentMediaType: "application/javascript" }responses, which stay as they were.🤖 Generated with Claude Code
https://claude.ai/code/session_01VVaw7RSkvUE8NjM89RakVV