Skip to content

fix(downgrader): ignore keys holding undefined in 3.0 media type and propertyNames checks - #80

Merged
dinwwwh merged 1 commit into
mainfrom
claude/project-thread-6ztq09
Oct 24, 2026
Merged

dinwwwh merged 1 commit into
mainfrom
claude/project-thread-6ztq09

Conversation

@dinwwwh

@dinwwwh dinwwwh commented Oct 24, 2026

Copy link
Copy Markdown
Member

Requested by dinwwwh · project thread

The README promises that a key holding undefined counts as missing, but two checks in the 3.1 to 3.0 converter counted such keys:

  • isMediaTypeOnly used Object.keys(value).length === 1, so a Zod-style anyOf branch like { contentMediaType: 'image/png', description: undefined } was not recognized and became a binary string branch instead of being dropped.
  • losesRestriction for propertyNames treated { type: 'string', x: undefined } as a lost restriction, so an enclosing oneOf (directly or through a $ref) became anyOf.

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: undefined key in every object (the withUndefined twin 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

…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
@dinwwwh dinwwwh self-assigned this Oct 24, 2026
@codecov

codecov Bot commented Oct 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@macroscopeapp

macroscopeapp Bot commented Oct 24, 2026

Copy link
Copy Markdown

Approvability

Verdict: Approved at 9ba26e6

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 undefined as missing. The accompanying tests cover both affected conversion paths, with no broader API, infrastructure, or sensitive-data impact.

You can add or adjust custom eligibility rules. Learn more.

@codspeed

codspeed Bot commented Oct 24, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 21 untouched benchmarks


Comparing claude/project-thread-6ztq09 (9ba26e6) with main (f9427cd)

Open in CodSpeed

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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"):

  • isMediaTypeOnly now ignores undefined-valued siblings (packages/downgrader/src/v3.1-to-v3.0.ts:489). It no longer requires exactly one own key; contentMediaType must be a string and every other entry must hold undefined. A Zod-style branch like { contentMediaType: 'image/png', description: undefined } is now recognized as media-type-only, so the enclosing anyOf is dropped rather than each branch turning into a 3.0 binary string.
  • propertyNames restriction 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 enclosing oneOf stays oneOf instead of widening to anyOf.
  • 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.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@dinwwwh
dinwwwh merged commit 7cd17bc into main Oct 24, 2026
11 checks passed
dinwwwh pushed a commit that referenced this pull request Oct 24, 2026
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
dinwwwh added a commit that referenced this pull request Oct 24, 2026
<!-- 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>
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.

2 participants