fix(compare): apply cleanDataKeys normalization before conflict comparison#483
Draft
hendrikheil wants to merge 1 commit into
Draft
Conversation
…rison When @nuxt/content stores frontmatter fields in `meta` rather than as top-level columns (because they aren't defined in the collection schema), `isDocumentMatchingContent` was returning false for unchanged files — causing Studio to show a spurious conflict dialog on every open. The freshly-parsed document (from `documentFromContent`) has all frontmatter at top level, while the stored document may have some fields inside `meta`. `doObjectsMatch` iterated the generated doc's keys and found mismatches against `undefined` on the stored side. The rendering path (`contentFromMarkdownDocument`) already calls `cleanDataKeys` which expands `meta` to root and strips nulls/reserved keys. Apply the same normalization to both sides inside `isDocumentMatchingContent` so the comparison is consistent with what the rest of the pipeline sees. Adds a regression test covering documents where `navigation` and `sitemap` are stored in `meta` by @nuxt/content. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
|
@hendrikheil is attempting to deploy a commit to the Nuxt Team on Vercel. A member of the Team first needs to authorize it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When opening certain pages in Studio, a false conflict dialog appeared showing a diff between the "GitHub" and "Website" versions — even though the file hadn't actually changed remotely.
The root cause:
@nuxt/contentstores frontmatter fields that aren't defined in the collection schema insidedocument.metarather than as top-level columns. For example, a page withnavigation: hiddenand asitemap:block in its frontmatter would end up with those fields atdocument.meta.navigationanddocument.meta.sitemaprather thandocument.navigation/document.sitemap.checkConflictcallsisDocumentMatchingContentto check whether the stored document still matches the remote file. This function re-parses the raw remote markdown viadocumentFromContent, which puts all frontmatter at top level. It then calleddoObjectsMatch(generatedDocumentData, documentData), wheregeneratedDocumentDatahad all keys at the top level butdocumentData(the stored document) had some of them tucked insidemeta.doObjectsMatchiterates over thebase(generated) side's keys and treats missing values on thetarget(stored) side as mismatches — so it returnedfalse, triggering the conflict path, even though no real change had occurred.Fix
The rendering path (
contentFromMarkdownDocument) already callscleanDataKeyson the stored document before producing markdown from it.cleanDataKeysexpandsmetato root level, strips reserved keys (id,stem,path,__hash__, etc.), removes top-level nulls and empty arrays, and normalises navigation/seo defaults.I applied the same normalization to both sides inside
isDocumentMatchingContent:This brings the conflict check in line with what the rest of the pipeline sees, so a stored document and a freshly-parsed document of the same content are structurally equivalent before comparison — regardless of whether @nuxt/content chose to store certain fields at top level or inside
meta.Note that
areDocumentsEqual(used elsewhere) already handled this correctly by spreading{ ...documentData, ...(meta || {}) }before comparing.isDocumentMatchingContentwas the outlier.Test
Added a regression test in
document.test.tsthat reproduces the exact shape of document that was triggering false conflicts: frontmatter containsnavigationandsitemapkeys that @nuxt/content stored insidemetarather than at the top level. The test was failing before this fix and passes after.Checklist
draft.ts/checkConflict— the fix is in the right layerpnpm test document→ 19/19)🤖 Generated with Claude Code