Repository navigation
fix(downgrader): ignore keys holding undefined in 3.0 media type and propertyNames checks - #80
Conversation
…propertyNames checks
A branch like `{ contentMediaType, description: undefined }` was not seen as
media-type only, and `propertyNames: { type: 'string', x: undefined }` counted
as a lost restriction, turning an enclosing `oneOf` into `anyOf`. Both now skip
keys holding undefined, so such a document converts like its JSON twin.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0129me54jxy7ZKsYhwWvAmPP
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a small, well-scoped downgrader bug fix that makes two checks consistently treat JavaScript properties holding You can add or adjust custom eligibility rules. Learn more. |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — two checks in the 3.1→3.0 converter now treat keys holding undefined as missing, matching the README contract ("a key holding undefined ... counts as missing"):
isMediaTypeOnlynow ignores undefined-valued siblings (packages/downgrader/src/v3.1-to-v3.0.ts:489). It no longer requires exactly one own key;contentMediaTypemust be a string and every other entry must holdundefined. A Zod-style branch like{ contentMediaType: 'image/png', description: undefined }is now recognized as media-type-only, so the enclosinganyOfis dropped rather than each branch turning into a 3.0 binary string.propertyNamesrestriction check ignores undefined-valued keywords (packages/downgrader/src/v3.1-to-v3.0.ts:367).propertyNames: { type: 'string', description: undefined }no longer counts as a lost restriction, so an enclosingoneOfstaysoneOfinstead of widening toanyOf.- Regression test added at
packages/downgrader/tests/v3.1-to-v3.0.test.ts:1076, covering both paths.
Both edits are strictly more faithful to the undefined-as-missing contract — a key holding undefined is absent, so the previous pessimistic result was the only divergence, and neither change drops a restriction that should have been kept. I verified the full suite (202 tests) passes on head, and that the new test fails when either source edit is reverted, so this is genuine coverage rather than theatre; uncheck (oxlint/oxfmt/tsc) is clean on both touched files.
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
Now that the 3.0 checks skip keys holding undefined (#80), the twin with a key holding undefined in every object converts to 3.0 like the plain one. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0129me54jxy7ZKsYhwWvAmPP
<!-- claude-projects-attribution: {"github_login":"dinwwwh"} -->
_Requested by **dinwwwh** · [project
thread](https://claude.ai/code/project/chan_01UcKMz91tMarPV1kWLVgLYE?thread=cmsg_01UcKMz91tMarPV1kWLVgLYENrRmND8vTmDypUMYJpJSLE)_
Test-only follow-up to #79 and #80. #79 checked the `withUndefined` twin
of the oRPC document only for the 3.2 to 3.1 step, because 3.1 to 3.0
counted keys holding `undefined`. #80 fixed that, so the 3.0 twin test
now runs over both `nullPrototype` and `withUndefined`.
The new case fails on the commit before #80 and passes on main.
---
_Generated by [Claude
Code](https://claude.ai/code/session_0129me54jxy7ZKsYhwWvAmPP)_
Co-authored-by: Claude <noreply@anthropic.com>

Requested by dinwwwh · project thread
The README promises that a key holding
undefinedcounts as missing, but two checks in the 3.1 to 3.0 converter counted such keys:isMediaTypeOnlyusedObject.keys(value).length === 1, so a Zod-styleanyOfbranch like{ contentMediaType: 'image/png', description: undefined }was not recognized and became a binary string branch instead of being dropped.losesRestrictionforpropertyNamestreated{ type: 'string', x: undefined }as a lost restriction, so an enclosingoneOf(directly or through a$ref) becameanyOf.Both checks now skip entries holding
undefined.A unit test covers both cases. I also checked that the oRPC document rebuilt with an extra
missing: undefinedkey in every object (thewithUndefinedtwin from #79) converts to 3.0 exactly like the plain one: it fails on main and passes with this change. Once #79 lands, that twin can be extended to 3.0.Generated by Claude Code