fix: warn on self-scoped composition selectors#562
Conversation
jrusso1020
left a comment
There was a problem hiding this comment.
LGTM — preventive lint rule paired with #561's runtime fix.
Rule: composition_self_attribute_selector walks each style block via postcss, fires on selectors targeting the file's own root composition id. Skips :root, html, body, *. Recommends #<root-id> in the fixHint when the root has an id, with #556 reference.
External CSS now in scope: lintProject.ts collects local <link rel="stylesheet"> files and feeds them through the lint context's externalStyles. Skips remote/data URLs. Resolves relative to the composition file. This is a solid expansion — previously the linter was inline-only.
Symmetric proof: reverted only core.ts + context.ts + types.ts while keeping the new tests → "warns when inline CSS targets the root composition id" + "warns when external CSS targets the root composition id" both fail red. The "does not warn when CSS targets a different composition id" test still passes (no rule = no findings, as expected). Restoring → 564/564 pass.
One nit, non-blocking: the fixHint message references #556 and says "until per-instance scoping is supported." With #561 landing alongside, per-instance scoping IS now supported in the bundled flow, so the message is slightly stale. The rule is still valuable as preventive guidance (the docs pattern depends on the bundler's rewrite — #<id> is more direct), but the fixHint copy could be updated post-merge to reflect "rely on #<id> for clearer authoring intent" rather than implying scoping doesn't exist.
— Review by Rames Jusso
f918f82 to
1540efb
Compare
|
Addressed the copy nit: refreshed the fixHint so it recommends using the root id for clearer authoring intent / instance-isolated styling without implying per-instance scoping is unsupported, and added a regression assertion that the stale #556 wording is gone. |
Problem
Closes #557.
Authors can follow the documented
[data-composition-id="<self>"]CSS pattern and accidentally create selectors that are unsafe when the same block is embedded more than once. The existing linter did not flag that authoring risk, including when the selector lived in a linked local stylesheet.What this fixes
composition_self_attribute_selectoras a warning when CSS targets the current file's root composition id.hyperframes lintfor root and sub-composition files.Root cause
The linter only extracted composition ids from inline
<style>blocks for wrapper existence checks. It did not parse selectors against the current root id, and the CLI did not pass linked local CSS into the core linter at all.Verification
Local checks
bun run --filter @hyperframes/core test src/lint/rules/core.test.tsbun test packages/cli/src/utils/lintProject.test.tsbun run build:hyperframes-runtimebefore the CLI test in this cold worktreebun run --filter @hyperframes/core typecheckbun run --filter @hyperframes/cli typecheckbunx oxlint packages/core/src/lint/types.ts packages/core/src/lint/context.ts packages/core/src/lint/rules/core.ts packages/core/src/lint/rules/core.test.ts packages/cli/src/utils/lintProject.ts packages/cli/src/utils/lintProject.test.tsbunx oxfmt --check packages/core/src/lint/types.ts packages/core/src/lint/context.ts packages/core/src/lint/rules/core.ts packages/core/src/lint/rules/core.test.ts packages/cli/src/utils/lintProject.ts packages/cli/src/utils/lintProject.test.tsBrowser verification
/tmp/hf-self-selector-lint-qawith[data-composition-id="scene"] .titlein inline CSS.bun run --filter @hyperframes/cli dev -- lint /tmp/hf-self-selector-lint-qareportedcomposition_self_attribute_selectoras a warning.http://localhost:5195and verified the Lint panel shows the warning.qa-artifacts/issue-557/self-selector-lint-panel.pngqa-artifacts/issue-557/self-selector-lint-panel.webmNotes
The QA artifacts are local only and not included in the PR.