Repository navigation
feat(form): accept AJV 8 instancePath in formatErrors (dual-shape) - #78
Merged
Merged
Conversation
formatErrors now reads error.instancePath (JSON Pointer, RFC 6901 — the AJV 8+ error shape) when present, and falls back to the legacy error.dataPath (dot/bracket notation, AJV <= 6) otherwise. With the bundled AJV 6 the behavior is strictly unchanged: the pre-existing dataPath tests are kept untouched and prove the non-regression. - new exported helper pointerToFieldPath(pointer): JSON Pointer -> dot-separated field path, with RFC 6901 escape decoding (~1 before ~0, so ~01 correctly yields a literal "~1") - the required-error concatenation is now conditional, so the root path no longer relies on stripping an orphan leading dot - mirror instancePath test set + pointer edge cases (root pointer, escapes, required inside arrays) Groundwork for the AJV 8 upgrade and a future Standard Schema adapter.
hugomallet
commented
Aug 8, 2026
hugomallet
left a comment
Collaborator
Author
There was a problem hiding this comment.
Tooled self-review (claude + review53 skill) — posted as comment, author and reviewer are the same account.
Verdict: LGTM, no correctness issue found. ESLint + tsc green on changed files, 124/124 tests pass, CI fully green (build + types React 16–19).
Verified beyond the suite:
- RFC 6901 edges (tested locally): lone
/→'',/a//b→a..b,/0→0,/~01→~1. All decode per the RFC; the/vs root-pointer collision (both →'') is a representational limit of dot paths, not a decoding bug. - dataPath equivalence: ran the old master implementation differentially against the new code on 8 dataPath cases, including
dataPath: '[0]'+required— outputs strictly identical, bug-for-bug (both keep the pre-existing leading dot on root-array dataPath,.0.x). - Dispatch predicate:
typeof instancePath === 'string'is the right choice — truthiness would misroute AJV 8's root''.
Minor, non-blocking:
- CHANGELOG overstates the export.
pointerToFieldPathis exported fromhelpers.jsonly; the packageexportsmap exposes justdist/index.js, which does not re-export it, so it is not user-visible. Reword ("internal helper") or re-export from the public barrel if intended. - Neither-shape error objects now always throw (
formatted.dataPath.replaceon undefined). Old code threw too, exceptrequirederrors which produced garbage"undefined.x". Loud failure on degenerate input is fine — just noting the divergence. - Inherited cross-shape quirk: root-array
dataPath '[0]'→.0(leading dot) vsinstancePath '/0'→0. Dies with the dataPath branch in PR 2 — no action. - Optional: pin lone
/and empty-segment (/a//b) behavior with two tests.
- treat an error carrying neither instancePath nor dataPath as pointing at the root instead of throwing (dataPath ?? '') - CHANGELOG: pointerToFieldPath is internal (not reachable through the package exports map), reworded accordingly - tests: degenerate no-path required error, lone-slash pointer '/' (documented root collision), empty mid-pointer segments '/a//b'
Collaborator
Author
|
Review comments addressed in 889c461 (single round-trip):
The cross-shape Suite: 124 → 127 tests, all green; lint and type-check green. |
This was referenced Aug 8, 2026
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.
Why
First brick of the AJV 8 track:
formatErrorsbecomes shape-agnostic so the future AJV 8 bump (separate PR, v1 branch) and a potential Standard Schema adapter only have to swap the validator, not the error plumbing. AJV 8 replaceddataPath(dot/bracket notation) withinstancePath(JSON Pointer, RFC 6901).What
formatErrorsreadserror.instancePathwhen it is a string, and falls back to the legacyerror.dataPathotherwise (the active branch with the bundled AJV 6).pointerToFieldPath(pointer)— JSON Pointer to dot-separated field path, with RFC 6901 escape decoding (~1before~0, so~01correctly decodes to a literal~1).requiredconcatenation is now conditional (field ? field + '.' + missing : missing), removing the orphan-leading-dot dance at the root.dataPath: 'arr[0].input'arr.0.inputarr.0.input(unchanged)dataPath: ''+ requiredinputinputinput(unchanged)instancePath: '/arr/0/input'arr.0.inputinstancePath: ''+ requiredinputinputinstancePath: '/a~01b'a~1bNon-breaking, proven
dataPathtests are untouched (the test file diff is purely additive) and still pass — strict non-regression under AJV 6.instancePathset (same cases as thedataPathset), pointer edge cases (root pointer,~0/~1escapes and their decoding order,requiredinside an array item), plus directpointerToFieldPathunit tests with literal expectations.~0/~1decoding order, dropping theslice(1), making therequiredconcat unconditional, and weakening thetypeofcheck to truthiness each make the corresponding tests fail for the expected reason.yarn lintandyarn type-checkgreen.