zemdomu 1.3.3 → 1.3.5

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.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,89 @@
1
+ import { LintResult, LinterOptions } from './linter';
2
+ interface PerformanceRecorder {
3
+ record(filePath: string, timings: Record<string, number>): void;
4
+ }
5
+ interface ComponentReference {
6
+ name: string;
7
+ path: string | null;
8
+ rawImportPath: string | null;
9
+ sourceLocation: {
10
+ line: number;
11
+ column: number;
12
+ };
13
+ usageLocations: Array<{
14
+ line: number;
15
+ column: number;
16
+ }>;
17
+ }
18
+ interface HeadingInfo {
19
+ level: number;
20
+ line: number;
21
+ column: number;
22
+ filePath: string;
23
+ }
24
+ interface IdInfo {
25
+ id: string;
26
+ line: number;
27
+ column: number;
28
+ filePath: string;
29
+ }
30
+ interface NavInfo {
31
+ filePath: string;
32
+ line: number;
33
+ column: number;
34
+ hasLocalLink: boolean;
35
+ childComponents: ComponentReference[];
36
+ }
37
+ interface ComponentDefinition {
38
+ name: string;
39
+ filePath: string;
40
+ issues: Map<string, LintResult[]>;
41
+ usesComponents: ComponentReference[];
42
+ headings: HeadingInfo[];
43
+ ids: IdInfo[];
44
+ navs: NavInfo[];
45
+ hasLocalAnchor: boolean;
46
+ }
47
+ export declare class ComponentAnalyzer {
48
+ private componentRegistry;
49
+ private importToComponentMap;
50
+ private options;
51
+ private processingComponentStack;
52
+ private perf?;
53
+ private resolver;
54
+ private maxDepth;
55
+ constructor(options: LinterOptions & {
56
+ crossComponentAnalysis?: boolean;
57
+ crossComponentDepth?: number;
58
+ }, perf?: PerformanceRecorder);
59
+ analyzeFile(filePath: string): Promise<ComponentDefinition | null>;
60
+ private extractComponentInfo;
61
+ private resolveComponentPath;
62
+ registerComponent(component: ComponentDefinition, issues: LintResult[]): void;
63
+ private getRuleType;
64
+ analyzeComponentTree(): LintResult[];
65
+ private findCrossComponentH1Issues;
66
+ private findReferenceForComp;
67
+ /**
68
+ * Improved implementation to find heading order issues across components
69
+ */
70
+ private findCrossComponentHeadingOrderIssues;
71
+ /**
72
+ * Collects all headings from a component and its children in document order
73
+ * and checks for heading level issues
74
+ */
75
+ private analyzeHeadingHierarchy;
76
+ /**
77
+ * Collects all headings from a component and its children in document order
78
+ */
79
+ private collectHeadingsInDocumentOrder;
80
+ private findCrossComponentDuplicateIds;
81
+ private collectIds;
82
+ private findCrossComponentNavLinks;
83
+ private checkNavs;
84
+ private navHasLink;
85
+ private componentHasAnchor;
86
+ private findEntryPoints;
87
+ private findComponentsWithRule;
88
+ }
89
+ export {};
@@ -0,0 +1,19 @@
1
+ export declare class ComponentPathResolver {
2
+ private static resolveCache;
3
+ private static statCache;
4
+ private static aliasCache;
5
+ private static unresolved;
6
+ private static devMode;
7
+ private static tsconfigLoaded;
8
+ private static tsAliases;
9
+ private static readonly aliasFileLimit;
10
+ private static rootDir;
11
+ static setRootDir(dir: string): void;
12
+ static updateDevMode(dev: boolean): void;
13
+ private static loadTsconfig;
14
+ private tryExtensions;
15
+ private resolveWithTsconfig;
16
+ private static normalizeKey;
17
+ private fileExists;
18
+ resolve(importPath: string, currentPath: string): Promise<string | null>;
19
+ }
@@ -0,0 +1,5 @@
1
+ export interface HtmlVisitor {
2
+ enter?(node: import('./simpleHtmlParser').Node): void;
3
+ exit?(node: import('./simpleHtmlParser').Node): void;
4
+ }
5
+ export declare function visitHtml(node: import('./simpleHtmlParser').Node, visitor: HtmlVisitor): void;
package/out/index.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ export { lint } from "./linter";
2
+ export type { LinterOptions, LintResult, Rule } from "./linter";
3
+ export { ComponentAnalyzer } from "./component-analyzer";
4
+ export { ComponentPathResolver } from "./component-path-resolver";
5
+ export { ProjectLinter } from "./project-linter";
6
+ export type { ProjectLinterOptions } from "./project-linter";
7
+ export { PerformanceDiagnostics } from "./performance-diagnostics";
8
+ export type { Node, ElementNode, TextNode, CommentNode, } from "./simpleHtmlParser";
9
+ export { parse as parseHtml } from "./simpleHtmlParser";
10
+ export { getAttr, getJsxAttr, getTag } from "./rules/utils";
11
+ export type { HtmlVisitor } from "./html-visitor";
12
+ export { visitHtml } from "./html-visitor";
13
+ export { resultsToSarif, RULE_DOCS_BASE } from "./sarif";
14
+ export type { SarifLog } from "./sarif";
@@ -0,0 +1,38 @@
1
+ import { Node } from "./simpleHtmlParser";
2
+ import { NodePath } from "@babel/traverse";
3
+ import * as t from "@babel/types";
4
+ import type { PerformanceRecorder } from "./performance-diagnostics";
5
+ export type RuleSeverity = "error" | "warning" | "off";
6
+ export interface LinterOptions {
7
+ rules?: Record<string, RuleSeverity>;
8
+ customRules?: Rule[];
9
+ /** Optional file path for better error messages */
10
+ filePath?: string;
11
+ /** Optional performance recorder */
12
+ perf?: PerformanceRecorder;
13
+ }
14
+ export interface LintResult {
15
+ line: number;
16
+ column: number;
17
+ message: string;
18
+ rule: string;
19
+ severity?: RuleSeverity;
20
+ filePath?: string;
21
+ }
22
+ export interface Rule {
23
+ name: string;
24
+ /** Called before traversal begins */
25
+ init?: () => void;
26
+ enterHtml?: (node: Node) => LintResult[];
27
+ exitHtml?: (node: Node) => LintResult[];
28
+ enterJsx?: (path: NodePath<t.JSXElement>) => LintResult[];
29
+ exitJsx?: (path: NodePath<t.JSXElement>) => LintResult[];
30
+ /** Called after traversal finishes */
31
+ end?: () => LintResult[];
32
+ test?: (node: Node | t.Node) => boolean;
33
+ message?: string;
34
+ }
35
+ /**
36
+ * Lint HTML/JSX/TSX content.
37
+ */
38
+ export declare function lint(content: string, options?: LinterOptions): LintResult[];
@@ -0,0 +1,14 @@
1
+ export interface PerformanceRecorder {
2
+ record(filePath: string, timings: Record<string, number>): void;
3
+ }
4
+ export declare class PerformanceDiagnostics implements PerformanceRecorder {
5
+ private static latestMetrics;
6
+ static getLatestMetrics(): Map<string, Record<string, number>>;
7
+ static resetMetrics(): void;
8
+ record(filePath: string, timings: Record<string, number>): void;
9
+ getAsJSON(): string;
10
+ /**
11
+ * Log slowest file and phase to console for debugging.
12
+ */
13
+ logSlowest(): void;
14
+ }
@@ -0,0 +1,16 @@
1
+ import { LintResult, LinterOptions } from "./linter";
2
+ import type { PerformanceRecorder } from "./performance-diagnostics";
3
+ export interface ProjectLinterOptions extends LinterOptions {
4
+ crossComponentAnalysis?: boolean;
5
+ crossComponentDepth?: number;
6
+ perf?: PerformanceRecorder;
7
+ rootDir?: string;
8
+ }
9
+ export declare class ProjectLinter {
10
+ private analyzer;
11
+ private opts;
12
+ constructor(options?: ProjectLinterOptions);
13
+ clear(): void;
14
+ lintFile(filePath: string, content?: string): Promise<Map<string, LintResult[]>>;
15
+ lintFiles(filePaths: string[]): Promise<Map<string, LintResult[]>>;
16
+ }
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function enforceHeadingOrder(): Rule;
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function enforceListNesting(): Rule;
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function noTabindexGreaterThanZero(): Rule;
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function preventEmptyInlineTags(): Rule;
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function requireAltText(): Rule;
@@ -0,0 +1,4 @@
1
+ import { NodePath } from '@babel/traverse';
2
+ import * as t from '@babel/types';
3
+ import { LintResult } from '../linter';
4
+ export default function requireAltTextJSX(path: NodePath<t.JSXElement>): LintResult[];
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function requireButtonText(): Rule;
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function requireHrefOnAnchors(): Rule;
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function requireHtmlLang(): Rule;
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function requireIframeTitle(): Rule;
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function requireImageInputAlt(): Rule;
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function requireLabelForFormControls(): Rule;
@@ -0,0 +1,2 @@
1
+ import { Rule } from "../linter";
2
+ export default function requireLinkText(): Rule;
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function requireNavLinks(): Rule;
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function requireSectionHeading(): Rule;
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function requireTableCaption(): Rule;
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function singleH1(): Rule;
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../linter';
2
+ export default function uniqueIds(): Rule;
@@ -0,0 +1,6 @@
1
+ import * as t from '@babel/types';
2
+ import { NodePath } from '@babel/traverse';
3
+ import { ElementNode } from '../simpleHtmlParser';
4
+ export declare function getAttr(node: ElementNode, name: string): string | undefined;
5
+ export declare function getJsxAttr(opening: t.JSXOpeningElement, name: string): string | undefined;
6
+ export declare function getTag(path: NodePath<t.JSXElement>): string;
package/out/sarif.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ export interface SarifLog {
2
+ version: string;
3
+ runs: Array<{
4
+ tool: {
5
+ driver: {
6
+ name: string;
7
+ informationUri?: string;
8
+ rules: Array<{
9
+ id: string;
10
+ name: string;
11
+ helpUri: string;
12
+ }>;
13
+ };
14
+ };
15
+ results: Array<{
16
+ ruleId: string;
17
+ message: {
18
+ text: string;
19
+ };
20
+ locations: Array<{
21
+ physicalLocation: {
22
+ artifactLocation: {
23
+ uri: string;
24
+ };
25
+ region: {
26
+ startLine: number;
27
+ startColumn: number;
28
+ };
29
+ };
30
+ }>;
31
+ level: string;
32
+ }>;
33
+ }>;
34
+ }
35
+ import { LintResult } from './linter';
36
+ declare const RULE_DOCS_BASE = "https://github.com/ZemDomu/docs/blob/main/rules/";
37
+ export declare function resultsToSarif(results: Map<string, LintResult[]>): SarifLog;
38
+ export { RULE_DOCS_BASE };
@@ -0,0 +1,20 @@
1
+ export type Node = ElementNode | TextNode | CommentNode;
2
+ export interface ElementNode {
3
+ type: 'element';
4
+ tagName: string;
5
+ attrs: Record<string, string>;
6
+ children: Node[];
7
+ startIndex: number;
8
+ selfClosing?: boolean;
9
+ }
10
+ export interface TextNode {
11
+ type: 'text';
12
+ text: string;
13
+ startIndex: number;
14
+ }
15
+ export interface CommentNode {
16
+ type: 'comment';
17
+ text: string;
18
+ startIndex: number;
19
+ }
20
+ export declare function parse(html: string): ElementNode;
@@ -0,0 +1,7 @@
1
+ export type ResolveCtx = {
2
+ rootDir: string;
3
+ baseUrl?: string;
4
+ paths?: Record<string, string[]>;
5
+ maxDepth?: number;
6
+ };
7
+ export declare function collectLocalDeps(entries: string[], ctx: ResolveCtx): string[];
package/package.json CHANGED
@@ -1,12 +1,19 @@
1
1
  {
2
2
  "name": "zemdomu",
3
- "version": "1.3.3",
3
+ "version": "1.3.5",
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",
7
7
  "bin": {
8
8
  "zemdomu": "./out/cli.js"
9
9
  },
10
+ "exports": {
11
+ ".": {
12
+ "types": "./out/index.d.ts",
13
+ "default": "./out/index.js"
14
+ },
15
+ "./*": "./out/*"
16
+ },
10
17
  "files": [
11
18
  "out",
12
19
  "README.md",