mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-12 22:26:38 +03:00
Five related bugs that surfaced in a real Next.js App Router project
(EAC) all rooted in live-wrap.mjs treating source as line-anchored HTML:
1. findElement matched on raw substring anywhere, so it landed on a
className continuation line of a multi-line JSX tag whose class
happened to collide with a later target. The wrong tag got wrapped
(really, its attribute line got wrapped, producing broken JSX).
2. findClosingLine's opener regex required whitespace or `>` after the
tag name, so a bare `<section\n className="..."\n>` opener was
unrecognised; it returned `start` silently, capturing only one line.
3. buildSearchQueries only emitted `class="..."`, missing React's
`className="..."`. The full-combo query never fired in JSX, so
search silently degraded to single-class substring matching.
4. Wrapper output used `style="display: contents"` unconditionally,
which is invalid JSX (type error in strict setups, parser hazard
in production transforms).
5. --tag was ignored during the primary class search. Ambiguous class
hits inside the wrong element type weren't filtered out.
## Fixes
- New OPENER_RE `/<([A-Za-z][A-Za-z0-9]*)(?=[\s/>]|$)/` recognises
tag openers at end-of-line too.
- New findOpenerLine(lines, matchLine, tag): walks up to 10 lines
backward to the enclosing opener when the match lands on a
continuation line. Aborts the walk if it hits a different tag.
- findElement now iterates all matches (not just the first), takes
a tag parameter, and routes through findOpenerLine; wrapCli passes
--tag through.
- buildSearchQueries emits both `class="..."` and `className="..."`
for multi-class queries, and both `<tag class="..."` /
`<tag className="..."` for tag+class combos.
- Wrapper builder emits `style={{ display: "contents" }}` when
commentSyntax is JSX and `style="display: contents"` otherwise.
- findClosingLine uses the same OPENER_RE so its tag-name extraction
works on multi-line openers too.
## Tests
Five new regression tests in tests/live-wrap.test.mjs, all failing
before the fix, all passing after:
- wraps the correct <section> when a class collides with a multi-line
tag elsewhere
- emits JSX-safe style attribute ({{ }}) in .tsx files
- finds elements via className= (React) when the exact class combo is
unique there
- respects --tag to reject matches inside the wrong element type
- findClosingLine recognises an opener line where the tag sits at
end-of-line (multi-line JSX)
31/31 in tests/live-wrap.test.mjs and 54/54 in
tests/framework-fixtures.test.mjs pass.
Credit: precise bug report from the other agent in the EAC session
made diagnosis and test design straightforward.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>