fix(lint): mode:'file' for the components-foundation Icon.vue bridge
Plan-1 Task-4 added { type:'components-foundation', pattern:
'src/components/Icon.vue' } without mode:'file'. eslint-plugin-boundaries
defaults to folder mode, so the single-file pattern never matched and
Icon.vue fell through to the generic `components` catch-all — breaking
the sanctioned components-v2 -> Icon bridge (RFC AD-G5) for every v2
shell component. Plan-1's boundary test only exercised the forms/**
folder-glob edge so the gap was latent. Adds mode:'file' + a regression
test locking the components-v2 -> Icon.vue edge.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -306,7 +306,13 @@ module.exports = {
|
|||||||
// same `type` so both src/components/forms/** and src/components/Icon.vue
|
// same `type` so both src/components/forms/** and src/components/Icon.vue
|
||||||
// are captured before the generic `components` catch-all.
|
// are captured before the generic `components` catch-all.
|
||||||
{ type: 'components-foundation', pattern: 'src/components/forms/**' },
|
{ type: 'components-foundation', pattern: 'src/components/forms/**' },
|
||||||
{ type: 'components-foundation', pattern: 'src/components/Icon.vue' },
|
// mode:'file' is REQUIRED for a single-file pattern. Without it
|
||||||
|
// eslint-plugin-boundaries matches in the default 'folder' mode,
|
||||||
|
// so 'src/components/Icon.vue' never matches and Icon.vue falls
|
||||||
|
// through to the generic `components` catch-all below — breaking
|
||||||
|
// the sanctioned components-v2 → Icon bridge (RFC AD-G5). The
|
||||||
|
// forms/** entry above is a folder glob so it is unaffected.
|
||||||
|
{ type: 'components-foundation', pattern: 'src/components/Icon.vue', mode: 'file' },
|
||||||
{ type: 'components-v2', pattern: 'src/components-v2/**' },
|
{ type: 'components-v2', pattern: 'src/components-v2/**' },
|
||||||
{ type: 'components', pattern: 'src/components/**' },
|
{ type: 'components', pattern: 'src/components/**' },
|
||||||
{ type: 'layouts', pattern: 'src/layouts/**' },
|
{ type: 'layouts', pattern: 'src/layouts/**' },
|
||||||
|
|||||||
@@ -38,6 +38,18 @@ describe('boundaries — v2 zones', () => {
|
|||||||
expect(errs).toHaveLength(0)
|
expect(errs).toHaveLength(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('allows components-v2 → components-foundation (Icon.vue bridge, single-file mode:file)', async () => {
|
||||||
|
// Regression lock: the single-file element needs mode:'file' or
|
||||||
|
// Icon.vue falls through to the generic `components` catch-all and
|
||||||
|
// every v2 shell component's Icon import breaks (RFC AD-G5 bridge).
|
||||||
|
const errs = await boundaryErrors(
|
||||||
|
'src/components-v2/layout/SidebarNav.vue',
|
||||||
|
'<script setup lang="ts">import Icon from \'@/components/Icon.vue\'</script><template><Icon name="x" /></template>',
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(errs).toHaveLength(0)
|
||||||
|
})
|
||||||
|
|
||||||
it('allows components-v2 → components-foundation (FormField bridge)', async () => {
|
it('allows components-v2 → components-foundation (FormField bridge)', async () => {
|
||||||
const errs = await boundaryErrors(
|
const errs = await boundaryErrors(
|
||||||
'src/components-v2/forms/Demo.vue',
|
'src/components-v2/forms/Demo.vue',
|
||||||
|
|||||||
Reference in New Issue
Block a user