zemdomu 1.3.7 → 1.3.8

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.
package/out/cli.js CHANGED
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- const glob_1 = __importDefault(require("glob"));
7
+ const glob_1 = require("glob");
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const project_linter_1 = require("./project-linter");
10
10
  function parsePatterns(inputs) {
@@ -66,7 +66,7 @@ async function run() {
66
66
  }
67
67
  const files = new Set();
68
68
  for (const pattern of patterns) {
69
- const matches = glob_1.default.sync(pattern, { nodir: true });
69
+ const matches = (0, glob_1.globSync)(pattern, { nodir: true });
70
70
  for (const m of matches)
71
71
  files.add(m);
72
72
  }
@@ -63,7 +63,6 @@ export declare class ComponentAnalyzer {
63
63
  private getRuleType;
64
64
  analyzeComponentTree(): LintResult[];
65
65
  private findCrossComponentH1Issues;
66
- private findReferenceForComp;
67
66
  /**
68
67
  * Improved implementation to find heading order issues across components
69
68
  */
@@ -320,59 +320,46 @@ class ComponentAnalyzer {
320
320
  findCrossComponentH1Issues(results) {
321
321
  var _a;
322
322
  const entryPoints = this.findEntryPoints();
323
+ const emitted = new Set();
324
+ const getDisplayName = (component) => {
325
+ if (component.name)
326
+ return component.name;
327
+ return path.basename(component.filePath, path.extname(component.filePath));
328
+ };
323
329
  for (const entry of entryPoints) {
324
330
  const comps = this.findComponentsWithRule(entry, 'singleH1', 0);
325
- if (comps.length > 1) {
326
- for (let i = 1; i < comps.length; i++) {
327
- const comp = comps[i];
328
- if (!comp || !comp.name) {
329
- console.error('[ZemDomu] Missing component or name during cross-component analysis', comp);
331
+ if (comps.length <= 1)
332
+ continue;
333
+ for (const comp of comps) {
334
+ if (!comp)
335
+ continue;
336
+ const compName = getDisplayName(comp);
337
+ const issues = (_a = comp.issues.get('singleH1')) !== null && _a !== void 0 ? _a : [];
338
+ if (!issues.length)
339
+ continue;
340
+ const conflictingNames = comps
341
+ .filter(other => other.filePath !== comp.filePath)
342
+ .map(getDisplayName);
343
+ if (!conflictingNames.length)
344
+ continue;
345
+ const conflicts = conflictingNames.map(name => `'${name}'`).join(', ');
346
+ const context = `This <h1> in '${compName}' conflicts with ${conflicts}.`;
347
+ for (const issue of issues) {
348
+ const key = `${entry.filePath}|${comp.filePath}|${issue.line}|${issue.column}`;
349
+ if (emitted.has(key))
330
350
  continue;
331
- }
332
- const ref = this.findReferenceForComp(entry, comp.filePath, 0);
333
- if (ref) {
334
- // Use first JSX usage location instead of import location
335
- const location = ref.usageLocations[0] || ref.sourceLocation;
336
- results.push({
337
- filePath: entry.filePath,
338
- line: location.line,
339
- column: location.column,
340
- message: `Multiple <h1> tags: component '${comp.name}' brings an extra <h1>. Use a lower-level heading.`,
341
- rule: 'singleH1'
342
- });
343
- }
344
- else {
345
- const issue = (_a = comp.issues.get('singleH1')) === null || _a === void 0 ? void 0 : _a[0];
346
- if (issue) {
347
- results.push({
348
- filePath: comp.filePath,
349
- line: issue.line,
350
- column: issue.column,
351
- message: `Multiple <h1> across components - consider using lower-level headings.`,
352
- rule: 'singleH1'
353
- });
354
- }
355
- }
351
+ emitted.add(key);
352
+ results.push({
353
+ filePath: comp.filePath,
354
+ line: issue.line,
355
+ column: issue.column,
356
+ message: `Multiple <h1> tags across components. ${context}`,
357
+ rule: 'singleH1'
358
+ });
356
359
  }
357
360
  }
358
361
  }
359
362
  }
360
- findReferenceForComp(root, targetPath, depth = 0) {
361
- if (this.maxDepth !== undefined && depth > this.maxDepth)
362
- return null;
363
- for (const ref of root.usesComponents) {
364
- if (ref.path === targetPath)
365
- return ref;
366
- }
367
- for (const ref of root.usesComponents) {
368
- if (ref.path && this.componentRegistry.has(ref.path)) {
369
- const nested = this.findReferenceForComp(this.componentRegistry.get(ref.path), targetPath, depth + 1);
370
- if (nested)
371
- return ref;
372
- }
373
- }
374
- return null;
375
- }
376
363
  /**
377
364
  * Improved implementation to find heading order issues across components
378
365
  */
@@ -389,7 +376,7 @@ class ComponentAnalyzer {
389
376
  * and checks for heading level issues
390
377
  */
391
378
  analyzeHeadingHierarchy(component, results, depth = 0) {
392
- var _a, _b, _c, _d, _e, _f;
379
+ var _a, _b, _c, _d;
393
380
  if (this.maxDepth !== undefined && depth > this.maxDepth)
394
381
  return;
395
382
  if (this.processingComponentStack.has(component.filePath)) {
@@ -404,21 +391,44 @@ class ComponentAnalyzer {
404
391
  for (const heading of allHeadings) {
405
392
  if (lastLevel > 0) {
406
393
  if (heading.heading.level > lastLevel + 1) {
407
- // We found a heading level skip
394
+ const locationFile = heading.heading.filePath;
395
+ const locationLine = heading.heading.line;
396
+ const locationColumn = heading.heading.column;
397
+ const usageComponent = ((_a = heading.usageLocation) === null || _a === void 0 ? void 0 : _a.filePath)
398
+ ? this.componentRegistry.get(heading.usageLocation.filePath)
399
+ : null;
400
+ const usageName = usageComponent
401
+ ? path.basename(usageComponent.filePath, path.extname(usageComponent.filePath))
402
+ : ((_b = heading.usageLocation) === null || _b === void 0 ? void 0 : _b.filePath)
403
+ ? path.basename(heading.usageLocation.filePath, path.extname(heading.usageLocation.filePath))
404
+ : null;
405
+ const messageSuffix = usageName ? ` (rendered via '${usageName}')` : '';
408
406
  results.push({
409
- filePath: ((_a = heading.usageLocation) === null || _a === void 0 ? void 0 : _a.filePath) || heading.heading.filePath,
410
- line: ((_b = heading.usageLocation) === null || _b === void 0 ? void 0 : _b.line) || heading.heading.line,
411
- column: ((_c = heading.usageLocation) === null || _c === void 0 ? void 0 : _c.column) || heading.heading.column,
412
- message: `Cross-component heading level skipped: <h${heading.heading.level}> after <h${lastLevel}>`,
407
+ filePath: locationFile,
408
+ line: locationLine,
409
+ column: locationColumn,
410
+ message: `Cross-component heading level skipped: <h${heading.heading.level}> after <h${lastLevel}>${messageSuffix}`,
413
411
  rule: 'enforceHeadingOrder'
414
412
  });
415
413
  }
416
414
  else if (heading.heading.level === 1 && lastLevel !== 1) {
415
+ const locationFile = heading.heading.filePath;
416
+ const locationLine = heading.heading.line;
417
+ const locationColumn = heading.heading.column;
418
+ const usageComponent = ((_c = heading.usageLocation) === null || _c === void 0 ? void 0 : _c.filePath)
419
+ ? this.componentRegistry.get(heading.usageLocation.filePath)
420
+ : null;
421
+ const usageName = usageComponent
422
+ ? path.basename(usageComponent.filePath, path.extname(usageComponent.filePath))
423
+ : ((_d = heading.usageLocation) === null || _d === void 0 ? void 0 : _d.filePath)
424
+ ? path.basename(heading.usageLocation.filePath, path.extname(heading.usageLocation.filePath))
425
+ : null;
426
+ const messageSuffix = usageName ? ` (rendered via '${usageName}')` : '';
417
427
  results.push({
418
- filePath: ((_d = heading.usageLocation) === null || _d === void 0 ? void 0 : _d.filePath) || heading.heading.filePath,
419
- line: ((_e = heading.usageLocation) === null || _e === void 0 ? void 0 : _e.line) || heading.heading.line,
420
- column: ((_f = heading.usageLocation) === null || _f === void 0 ? void 0 : _f.column) || heading.heading.column,
421
- message: `Cross-component heading level skipped: <h${heading.heading.level}> after <h${lastLevel}>`,
428
+ filePath: locationFile,
429
+ line: locationLine,
430
+ column: locationColumn,
431
+ message: `Cross-component heading level skipped: <h${heading.heading.level}> after <h${lastLevel}>${messageSuffix}`,
422
432
  rule: 'enforceHeadingOrder'
423
433
  });
424
434
  }
@@ -36,8 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.ComponentPathResolver = void 0;
37
37
  const fs = __importStar(require("fs/promises"));
38
38
  const path = __importStar(require("path"));
39
- // eslint-disable-next-line @typescript-eslint/no-var-requires
40
- const glob = require('glob');
39
+ const glob_1 = require("glob");
41
40
  let vscodeApi;
42
41
  try {
43
42
  vscodeApi = require('vscode');
@@ -182,8 +181,10 @@ class ComponentPathResolver {
182
181
  let alias = ComponentPathResolver.aliasCache.get(prefix);
183
182
  if (!alias) {
184
183
  const pattern = `**/${prefix}/**/*.{tsx,jsx,ts,js}`;
185
- const files = await new Promise((resolve, reject) => {
186
- glob(pattern, { cwd: ComponentPathResolver.rootDir, ignore: '**/node_modules/**', nodir: true }, (err, matches) => (err ? reject(err) : resolve(matches)));
184
+ const files = await (0, glob_1.glob)(pattern, {
185
+ cwd: ComponentPathResolver.rootDir,
186
+ ignore: '**/node_modules/**',
187
+ nodir: true,
187
188
  });
188
189
  alias = new Map();
189
190
  for (const relPath of files.slice(0, ComponentPathResolver.aliasFileLimit)) {
@@ -218,8 +219,10 @@ class ComponentPathResolver {
218
219
  }
219
220
  continue;
220
221
  }
221
- const matches = await new Promise((resolve, reject) => {
222
- glob(ptn, { cwd: ComponentPathResolver.rootDir, ignore: '**/node_modules/**', nodir: true }, (err, files) => (err ? reject(err) : resolve(files)));
222
+ const matches = await (0, glob_1.glob)(ptn, {
223
+ cwd: ComponentPathResolver.rootDir,
224
+ ignore: '**/node_modules/**',
225
+ nodir: true,
223
226
  });
224
227
  if (matches.length) {
225
228
  result = path.resolve(ComponentPathResolver.rootDir, matches[0]);
package/out/src/cli.js CHANGED
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- const glob_1 = __importDefault(require("glob"));
7
+ const glob_1 = require("glob");
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const project_linter_1 = require("./project-linter");
10
10
  function parsePatterns(inputs) {
@@ -66,7 +66,7 @@ async function run() {
66
66
  }
67
67
  const files = new Set();
68
68
  for (const pattern of patterns) {
69
- const matches = glob_1.default.sync(pattern, { nodir: true });
69
+ const matches = (0, glob_1.globSync)(pattern, { nodir: true });
70
70
  for (const m of matches)
71
71
  files.add(m);
72
72
  }
@@ -320,59 +320,46 @@ class ComponentAnalyzer {
320
320
  findCrossComponentH1Issues(results) {
321
321
  var _a;
322
322
  const entryPoints = this.findEntryPoints();
323
+ const emitted = new Set();
324
+ const getDisplayName = (component) => {
325
+ if (component.name)
326
+ return component.name;
327
+ return path.basename(component.filePath, path.extname(component.filePath));
328
+ };
323
329
  for (const entry of entryPoints) {
324
330
  const comps = this.findComponentsWithRule(entry, 'singleH1', 0);
325
- if (comps.length > 1) {
326
- for (let i = 1; i < comps.length; i++) {
327
- const comp = comps[i];
328
- if (!comp || !comp.name) {
329
- console.error('[ZemDomu] Missing component or name during cross-component analysis', comp);
331
+ if (comps.length <= 1)
332
+ continue;
333
+ for (const comp of comps) {
334
+ if (!comp)
335
+ continue;
336
+ const compName = getDisplayName(comp);
337
+ const issues = (_a = comp.issues.get('singleH1')) !== null && _a !== void 0 ? _a : [];
338
+ if (!issues.length)
339
+ continue;
340
+ const conflictingNames = comps
341
+ .filter(other => other.filePath !== comp.filePath)
342
+ .map(getDisplayName);
343
+ if (!conflictingNames.length)
344
+ continue;
345
+ const conflicts = conflictingNames.map(name => `'${name}'`).join(', ');
346
+ const context = `This <h1> in '${compName}' conflicts with ${conflicts}.`;
347
+ for (const issue of issues) {
348
+ const key = `${entry.filePath}|${comp.filePath}|${issue.line}|${issue.column}`;
349
+ if (emitted.has(key))
330
350
  continue;
331
- }
332
- const ref = this.findReferenceForComp(entry, comp.filePath, 0);
333
- if (ref) {
334
- // Use first JSX usage location instead of import location
335
- const location = ref.usageLocations[0] || ref.sourceLocation;
336
- results.push({
337
- filePath: entry.filePath,
338
- line: location.line,
339
- column: location.column,
340
- message: `Multiple <h1> tags: component '${comp.name}' brings an extra <h1>. Use a lower-level heading.`,
341
- rule: 'singleH1'
342
- });
343
- }
344
- else {
345
- const issue = (_a = comp.issues.get('singleH1')) === null || _a === void 0 ? void 0 : _a[0];
346
- if (issue) {
347
- results.push({
348
- filePath: comp.filePath,
349
- line: issue.line,
350
- column: issue.column,
351
- message: `Multiple <h1> across components - consider using lower-level headings.`,
352
- rule: 'singleH1'
353
- });
354
- }
355
- }
351
+ emitted.add(key);
352
+ results.push({
353
+ filePath: comp.filePath,
354
+ line: issue.line,
355
+ column: issue.column,
356
+ message: `Multiple <h1> tags across components. ${context}`,
357
+ rule: 'singleH1'
358
+ });
356
359
  }
357
360
  }
358
361
  }
359
362
  }
360
- findReferenceForComp(root, targetPath, depth = 0) {
361
- if (this.maxDepth !== undefined && depth > this.maxDepth)
362
- return null;
363
- for (const ref of root.usesComponents) {
364
- if (ref.path === targetPath)
365
- return ref;
366
- }
367
- for (const ref of root.usesComponents) {
368
- if (ref.path && this.componentRegistry.has(ref.path)) {
369
- const nested = this.findReferenceForComp(this.componentRegistry.get(ref.path), targetPath, depth + 1);
370
- if (nested)
371
- return ref;
372
- }
373
- }
374
- return null;
375
- }
376
363
  /**
377
364
  * Improved implementation to find heading order issues across components
378
365
  */
@@ -389,7 +376,7 @@ class ComponentAnalyzer {
389
376
  * and checks for heading level issues
390
377
  */
391
378
  analyzeHeadingHierarchy(component, results, depth = 0) {
392
- var _a, _b, _c, _d, _e, _f;
379
+ var _a, _b, _c, _d;
393
380
  if (this.maxDepth !== undefined && depth > this.maxDepth)
394
381
  return;
395
382
  if (this.processingComponentStack.has(component.filePath)) {
@@ -404,21 +391,44 @@ class ComponentAnalyzer {
404
391
  for (const heading of allHeadings) {
405
392
  if (lastLevel > 0) {
406
393
  if (heading.heading.level > lastLevel + 1) {
407
- // We found a heading level skip
394
+ const locationFile = heading.heading.filePath;
395
+ const locationLine = heading.heading.line;
396
+ const locationColumn = heading.heading.column;
397
+ const usageComponent = ((_a = heading.usageLocation) === null || _a === void 0 ? void 0 : _a.filePath)
398
+ ? this.componentRegistry.get(heading.usageLocation.filePath)
399
+ : null;
400
+ const usageName = usageComponent
401
+ ? path.basename(usageComponent.filePath, path.extname(usageComponent.filePath))
402
+ : ((_b = heading.usageLocation) === null || _b === void 0 ? void 0 : _b.filePath)
403
+ ? path.basename(heading.usageLocation.filePath, path.extname(heading.usageLocation.filePath))
404
+ : null;
405
+ const messageSuffix = usageName ? ` (rendered via '${usageName}')` : '';
408
406
  results.push({
409
- filePath: ((_a = heading.usageLocation) === null || _a === void 0 ? void 0 : _a.filePath) || heading.heading.filePath,
410
- line: ((_b = heading.usageLocation) === null || _b === void 0 ? void 0 : _b.line) || heading.heading.line,
411
- column: ((_c = heading.usageLocation) === null || _c === void 0 ? void 0 : _c.column) || heading.heading.column,
412
- message: `Cross-component heading level skipped: <h${heading.heading.level}> after <h${lastLevel}>`,
407
+ filePath: locationFile,
408
+ line: locationLine,
409
+ column: locationColumn,
410
+ message: `Cross-component heading level skipped: <h${heading.heading.level}> after <h${lastLevel}>${messageSuffix}`,
413
411
  rule: 'enforceHeadingOrder'
414
412
  });
415
413
  }
416
414
  else if (heading.heading.level === 1 && lastLevel !== 1) {
415
+ const locationFile = heading.heading.filePath;
416
+ const locationLine = heading.heading.line;
417
+ const locationColumn = heading.heading.column;
418
+ const usageComponent = ((_c = heading.usageLocation) === null || _c === void 0 ? void 0 : _c.filePath)
419
+ ? this.componentRegistry.get(heading.usageLocation.filePath)
420
+ : null;
421
+ const usageName = usageComponent
422
+ ? path.basename(usageComponent.filePath, path.extname(usageComponent.filePath))
423
+ : ((_d = heading.usageLocation) === null || _d === void 0 ? void 0 : _d.filePath)
424
+ ? path.basename(heading.usageLocation.filePath, path.extname(heading.usageLocation.filePath))
425
+ : null;
426
+ const messageSuffix = usageName ? ` (rendered via '${usageName}')` : '';
417
427
  results.push({
418
- filePath: ((_d = heading.usageLocation) === null || _d === void 0 ? void 0 : _d.filePath) || heading.heading.filePath,
419
- line: ((_e = heading.usageLocation) === null || _e === void 0 ? void 0 : _e.line) || heading.heading.line,
420
- column: ((_f = heading.usageLocation) === null || _f === void 0 ? void 0 : _f.column) || heading.heading.column,
421
- message: `Cross-component heading level skipped: <h${heading.heading.level}> after <h${lastLevel}>`,
428
+ filePath: locationFile,
429
+ line: locationLine,
430
+ column: locationColumn,
431
+ message: `Cross-component heading level skipped: <h${heading.heading.level}> after <h${lastLevel}>${messageSuffix}`,
422
432
  rule: 'enforceHeadingOrder'
423
433
  });
424
434
  }
@@ -36,8 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.ComponentPathResolver = void 0;
37
37
  const fs = __importStar(require("fs/promises"));
38
38
  const path = __importStar(require("path"));
39
- // eslint-disable-next-line @typescript-eslint/no-var-requires
40
- const glob = require('glob');
39
+ const glob_1 = require("glob");
41
40
  let vscodeApi;
42
41
  try {
43
42
  vscodeApi = require('vscode');
@@ -182,8 +181,10 @@ class ComponentPathResolver {
182
181
  let alias = ComponentPathResolver.aliasCache.get(prefix);
183
182
  if (!alias) {
184
183
  const pattern = `**/${prefix}/**/*.{tsx,jsx,ts,js}`;
185
- const files = await new Promise((resolve, reject) => {
186
- glob(pattern, { cwd: ComponentPathResolver.rootDir, ignore: '**/node_modules/**', nodir: true }, (err, matches) => (err ? reject(err) : resolve(matches)));
184
+ const files = await (0, glob_1.glob)(pattern, {
185
+ cwd: ComponentPathResolver.rootDir,
186
+ ignore: '**/node_modules/**',
187
+ nodir: true,
187
188
  });
188
189
  alias = new Map();
189
190
  for (const relPath of files.slice(0, ComponentPathResolver.aliasFileLimit)) {
@@ -218,8 +219,10 @@ class ComponentPathResolver {
218
219
  }
219
220
  continue;
220
221
  }
221
- const matches = await new Promise((resolve, reject) => {
222
- glob(ptn, { cwd: ComponentPathResolver.rootDir, ignore: '**/node_modules/**', nodir: true }, (err, files) => (err ? reject(err) : resolve(files)));
222
+ const matches = await (0, glob_1.glob)(ptn, {
223
+ cwd: ComponentPathResolver.rootDir,
224
+ ignore: '**/node_modules/**',
225
+ nodir: true,
223
226
  });
224
227
  if (matches.length) {
225
228
  result = path.resolve(ComponentPathResolver.rootDir, matches[0]);
@@ -1,41 +1,7 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  exports.default = Button;
37
4
  const jsx_runtime_1 = require("react/jsx-runtime");
38
- const React = __importStar(require("react"));
39
5
  function Button() {
40
6
  return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { children: "Button" }), (0, jsx_runtime_1.jsx)("h5", { children: "Subsection" })] }));
41
7
  }
@@ -1,44 +1,10 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
36
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
4
  };
38
5
  Object.defineProperty(exports, "__esModule", { value: true });
39
6
  exports.default = Page;
40
7
  const jsx_runtime_1 = require("react/jsx-runtime");
41
- const React = __importStar(require("react"));
42
8
  const Section_1 = __importDefault(require("@alias/Section"));
43
9
  function Page() {
44
10
  return ((0, jsx_runtime_1.jsxs)("main", { children: [(0, jsx_runtime_1.jsx)("h1", { children: "Hello" }), (0, jsx_runtime_1.jsx)(Section_1.default, {})] }));
@@ -1,44 +1,10 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
36
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
4
  };
38
5
  Object.defineProperty(exports, "__esModule", { value: true });
39
6
  exports.default = Section;
40
7
  const jsx_runtime_1 = require("react/jsx-runtime");
41
- const React = __importStar(require("react"));
42
8
  const SubSection_1 = __importDefault(require("@alias/SubSection"));
43
9
  function Section() {
44
10
  return ((0, jsx_runtime_1.jsxs)("section", { children: [(0, jsx_runtime_1.jsx)("h2", { children: "Section Title" }), (0, jsx_runtime_1.jsx)(SubSection_1.default, {})] }));
@@ -1,44 +1,10 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
36
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
4
  };
38
5
  Object.defineProperty(exports, "__esModule", { value: true });
39
6
  exports.default = SubSection;
40
7
  const jsx_runtime_1 = require("react/jsx-runtime");
41
- const React = __importStar(require("react"));
42
8
  const Button_1 = __importDefault(require("@alias/Button"));
43
9
  function SubSection() {
44
10
  return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { children: "SubSection" }), (0, jsx_runtime_1.jsx)(Button_1.default, {})] }));
@@ -41,9 +41,14 @@ describe("cross component heading order", () => {
41
41
  assert_1.default.ok(((_a = byRule["singleH1"]) !== null && _a !== void 0 ? _a : 0) >= 1, "Expected at least one singleH1");
42
42
  assert_1.default.ok(((_b = byRule["enforceHeadingOrder"]) !== null && _b !== void 0 ? _b : 0) >= 1, // set to >=2 if you expect more
43
43
  "Expected at least one enforceHeadingOrder");
44
- const usageLocations = results
45
- .filter((r) => r.rule === "enforceHeadingOrder" && "filePath" in r && r.filePath)
44
+ const singleH1Files = new Set(results
45
+ .filter((r) => r.rule === "singleH1" && r.filePath)
46
+ .map((r) => path_1.default.basename(r.filePath)));
47
+ assert_1.default.ok(singleH1Files.has("Page.tsx"), "Expected cross-component singleH1 to surface on Page.tsx");
48
+ assert_1.default.ok(singleH1Files.has("Button.tsx"), "Expected cross-component singleH1 to surface on Button.tsx");
49
+ const headingLocations = results
50
+ .filter((r) => r.rule === "enforceHeadingOrder" && r.filePath)
46
51
  .map((r) => path_1.default.basename(r.filePath));
47
- assert_1.default.ok(usageLocations.includes("SubSection.tsx"), "Expected heading order issue to surface on the component that renders the offending child");
52
+ assert_1.default.ok(headingLocations.includes("Button.tsx"), "Expected heading order issue to highlight the component containing the offending heading");
48
53
  });
49
54
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zemdomu",
3
- "version": "1.3.7",
3
+ "version": "1.3.8",
4
4
  "description": "Semantic HTML linter for HTML, JSX, and TSX. Detects accessibility, SEO, and structure issues before deployment.",
5
5
  "main": "./out/index.js",
6
6
  "types": "./out/index.d.ts",
@@ -42,25 +42,24 @@
42
42
  "author": "Zacharias Eryd Berlin",
43
43
  "license": "ISC",
44
44
  "devDependencies": {
45
- "@types/babel__traverse": "^7.20.7",
45
+ "@types/babel__traverse": "^7.28.0",
46
46
  "@types/babel-traverse": "^6.25.10",
47
47
  "@types/babel-types": "^7.0.16",
48
- "@types/glob": "^8.1.0",
49
48
  "@types/mocha": "^10.0.10",
50
- "@types/node": "^22.15.17",
51
- "@types/react": "^19.1.9",
52
- "@types/react-dom": "^19.1.7",
53
- "esbuild": "^0.25.5",
54
- "mocha": "^10.8.2",
55
- "typescript": "^5.8.2"
49
+ "@types/node": "^24.9.1",
50
+ "@types/react": "^19.2.2",
51
+ "@types/react-dom": "^19.2.2",
52
+ "esbuild": "^0.25.11",
53
+ "mocha": "^11.7.4",
54
+ "typescript": "^5.9.3"
56
55
  },
57
56
  "dependencies": {
58
- "@babel/parser": "^7.27.0",
59
- "@babel/traverse": "^7.27.0",
60
- "@babel/types": "^7.27.0",
61
- "glob": "^7.2.3",
62
- "react": "^19.1.1",
63
- "react-dom": "^19.1.1"
57
+ "@babel/parser": "^7.28.4",
58
+ "@babel/traverse": "^7.28.4",
59
+ "@babel/types": "^7.28.4",
60
+ "glob": "^11.0.3",
61
+ "react": "^19.2.0",
62
+ "react-dom": "^19.2.0"
64
63
  },
65
64
  "jest": {
66
65
  "transform": {