eslint-plugin-kerfjs 5.0.0-beta.58 → 5.0.0-beta.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -30,7 +30,9 @@ cataloged roots, or nothing) is checked as those roots:
30
30
 
31
31
  - **Zones (`KUI-L202`):** the zone must accept every declared root.
32
32
  - **Parents (`KUI-L201`):** each root's listed parents apply where the wrapper
33
- is placed, and a wrapper used as a parent counts as each of its roots.
33
+ is placed, and a wrapper used as a parent counts as each of its roots. A
34
+ placement reports once, using the first violated root requirement before a
35
+ separate wrapper requirement if both apply.
34
36
  - **Cardinality (`KUI-L203`):** the wrapper counts as zero or one child, since
35
37
  it may render nothing.
36
38
 
package/index.js CHANGED
@@ -14,7 +14,7 @@ import uiPublicBoundaries from './lib/rules/ui-public-boundaries.js';
14
14
  import uiWiring from './lib/rules/ui-wiring.js';
15
15
 
16
16
  const plugin = {
17
- meta: { name: 'eslint-plugin-kerfjs', version: '5.0.0-beta.58' },
17
+ meta: { name: 'eslint-plugin-kerfjs', version: '5.0.0-beta.59' },
18
18
  rules: {
19
19
  'no-inline-jsx-event-handlers': noInlineJsxEventHandlers,
20
20
  'no-raw-with-dynamic-arg': noRawWithDynamicArg,
@@ -167,34 +167,37 @@ export default {
167
167
  const entry = contract.entries.get(key);
168
168
  if (!entry) return;
169
169
  // A wrapper answers to its own parent contract and to each root's.
170
+ // Report one violated requirement per placement, with roots first.
170
171
  const placed = [
171
- { entry, child: key },
172
172
  ...(entry.rendersAs ?? []).flatMap((root) => {
173
173
  const rootEntry = contract.entries.get(root);
174
174
  return rootEntry
175
175
  ? [{ entry: rootEntry, child: `${key} (renders ${root})` }]
176
176
  : [];
177
177
  }),
178
+ { entry, child: key },
178
179
  ].filter(
179
180
  ({ entry: placedEntry }) => placedEntry.parents?.mode === 'listed',
180
181
  );
181
182
  if (placed.length && !isExcepted(contract, PARENT_CODE, filename)) {
182
183
  const parent = directParentKey(node, registry, contract);
183
- if (parent)
184
- for (const { entry: placedEntry, child } of placed)
185
- if (
184
+ if (parent) {
185
+ const violation = placed.find(
186
+ ({ entry: placedEntry }) =>
186
187
  !rootsOf(parent.key, contract).every((root) =>
187
188
  placedEntry.parents.entries.includes(root),
188
- )
189
- )
190
- context.report({
191
- node: node.name,
192
- messageId: 'parent',
193
- data: {
194
- child,
195
- parents: placedEntry.parents.entries.join(', '),
196
- },
197
- });
189
+ ),
190
+ );
191
+ if (violation)
192
+ context.report({
193
+ node: node.name,
194
+ messageId: 'parent',
195
+ data: {
196
+ child: violation.child,
197
+ parents: violation.entry.parents.entries.join(', '),
198
+ },
199
+ });
200
+ }
198
201
  }
199
202
  for (const zone of entry.zones ?? []) {
200
203
  const bound = boundZone(node, zone, registry, contract);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-kerfjs",
3
- "version": "5.0.0-beta.58",
3
+ "version": "5.0.0-beta.59",
4
4
  "description": "ESLint rules that enforce kerf's hard rules — catches AI-shaped bugs at edit time.",
5
5
  "type": "module",
6
6
  "license": "MIT",