uilint-eslint 0.2.9 → 0.2.11
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/dist/{chunk-IL6RYCMD.js → chunk-6EI7LWV5.js} +6 -2
- package/dist/chunk-6EI7LWV5.js.map +1 -0
- package/dist/chunk-MFIU3O2I.js +201 -0
- package/dist/chunk-MFIU3O2I.js.map +1 -0
- package/dist/index.d.ts +175 -57
- package/dist/index.js +2515 -200
- package/dist/index.js.map +1 -1
- package/dist/rules/consistent-dark-mode.js +79 -3
- package/dist/rules/consistent-dark-mode.js.map +1 -1
- package/dist/rules/consistent-spacing.js +66 -3
- package/dist/rules/consistent-spacing.js.map +1 -1
- package/dist/rules/enforce-absolute-imports.js +181 -0
- package/dist/rules/enforce-absolute-imports.js.map +1 -0
- package/dist/rules/no-any-in-props.js +355 -0
- package/dist/rules/no-any-in-props.js.map +1 -0
- package/dist/rules/no-arbitrary-tailwind.js +50 -3
- package/dist/rules/no-arbitrary-tailwind.js.map +1 -1
- package/dist/rules/no-direct-store-import.js +79 -3
- package/dist/rules/no-direct-store-import.js.map +1 -1
- package/dist/rules/no-mixed-component-libraries.js +91 -192
- package/dist/rules/no-mixed-component-libraries.js.map +1 -1
- package/dist/rules/no-prop-drilling-depth.js +370 -0
- package/dist/rules/no-prop-drilling-depth.js.map +1 -0
- package/dist/rules/no-secrets-in-code.js +360 -0
- package/dist/rules/no-secrets-in-code.js.map +1 -0
- package/dist/rules/prefer-zustand-state-management.js +114 -3
- package/dist/rules/prefer-zustand-state-management.js.map +1 -1
- package/dist/rules/require-input-validation.js +321 -0
- package/dist/rules/require-input-validation.js.map +1 -0
- package/dist/rules/semantic-vision.js +78 -3
- package/dist/rules/semantic-vision.js.map +1 -1
- package/dist/rules/semantic.js +91 -3
- package/dist/rules/semantic.js.map +1 -1
- package/dist/rules/zustand-use-selectors.js +234 -0
- package/dist/rules/zustand-use-selectors.js.map +1 -0
- package/package.json +2 -2
- package/src/index.ts +133 -1
- package/src/rule-registry.ts +68 -256
- package/src/rules/consistent-dark-mode.ts +79 -1
- package/src/rules/consistent-spacing.ts +66 -1
- package/src/rules/enforce-absolute-imports.test.ts +429 -0
- package/src/rules/enforce-absolute-imports.ts +233 -0
- package/src/rules/no-any-in-props.test.ts +418 -0
- package/src/rules/no-any-in-props.ts +486 -0
- package/src/rules/no-arbitrary-tailwind.ts +50 -1
- package/src/rules/no-direct-store-import.ts +79 -1
- package/src/rules/no-mixed-component-libraries.ts +86 -1
- package/src/rules/no-prop-drilling-depth.test.ts +518 -0
- package/src/rules/no-prop-drilling-depth.ts +538 -0
- package/src/rules/no-secrets-in-code.test.ts +366 -0
- package/src/rules/no-secrets-in-code.ts +462 -0
- package/src/rules/prefer-zustand-state-management.ts +114 -1
- package/src/rules/require-input-validation.test.ts +507 -0
- package/src/rules/require-input-validation.ts +466 -0
- package/src/rules/semantic-vision.ts +78 -1
- package/src/rules/semantic.ts +91 -1
- package/src/rules/zustand-use-selectors.test.ts +362 -0
- package/src/rules/zustand-use-selectors.ts +314 -0
- package/src/utils/create-rule.ts +77 -0
- package/dist/chunk-IL6RYCMD.js.map +0 -1
|
@@ -3,8 +3,12 @@ import { ESLintUtils } from "@typescript-eslint/utils";
|
|
|
3
3
|
var createRule = ESLintUtils.RuleCreator(
|
|
4
4
|
(name) => `https://github.com/peter-suggate/uilint/blob/main/packages/uilint-eslint/docs/rules/${name}.md`
|
|
5
5
|
);
|
|
6
|
+
function defineRuleMeta(meta) {
|
|
7
|
+
return meta;
|
|
8
|
+
}
|
|
6
9
|
|
|
7
10
|
export {
|
|
8
|
-
createRule
|
|
11
|
+
createRule,
|
|
12
|
+
defineRuleMeta
|
|
9
13
|
};
|
|
10
|
-
//# sourceMappingURL=chunk-
|
|
14
|
+
//# sourceMappingURL=chunk-6EI7LWV5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/create-rule.ts"],"sourcesContent":["/**\n * Rule creation helper using @typescript-eslint/utils\n */\n\nimport { ESLintUtils } from \"@typescript-eslint/utils\";\n\nexport const createRule = ESLintUtils.RuleCreator(\n (name) =>\n `https://github.com/peter-suggate/uilint/blob/main/packages/uilint-eslint/docs/rules/${name}.md`\n);\n\n/**\n * Schema for prompting user to configure a rule option in the CLI\n */\nexport interface OptionFieldSchema {\n /** Field name in the options object */\n key: string;\n /** Display label for the prompt */\n label: string;\n /** Prompt type */\n type: \"text\" | \"number\" | \"boolean\" | \"select\" | \"multiselect\";\n /** Default value */\n defaultValue: unknown;\n /** Placeholder text (for text/number inputs) */\n placeholder?: string;\n /** Options for select/multiselect */\n options?: Array<{ value: string | number; label: string }>;\n /** Description/hint for the field */\n description?: string;\n}\n\n/**\n * Schema describing how to prompt for rule options during installation\n */\nexport interface RuleOptionSchema {\n /** Fields that can be configured for this rule */\n fields: OptionFieldSchema[];\n}\n\n/**\n * Colocated rule metadata - exported alongside each rule\n *\n * This structure keeps all rule metadata in the same file as the rule implementation,\n * making it easy to maintain and extend as new rules are added.\n */\nexport interface RuleMeta {\n /** Rule identifier (e.g., \"no-arbitrary-tailwind\") - must match filename */\n id: string;\n\n /** Display name for CLI (e.g., \"No Arbitrary Tailwind\") */\n name: string;\n\n /** Short description for CLI selection prompts (one line) */\n description: string;\n\n /** Default severity level */\n defaultSeverity: \"error\" | \"warn\" | \"off\";\n\n /** Category for grouping in CLI */\n category: \"static\" | \"semantic\";\n\n /** Whether this rule requires a styleguide file */\n requiresStyleguide?: boolean;\n\n /** Default options for the rule (passed as second element in ESLint config) */\n defaultOptions?: unknown[];\n\n /** Schema for prompting user to configure options during install */\n optionSchema?: RuleOptionSchema;\n\n /**\n * Detailed documentation in markdown format.\n * Should include:\n * - What the rule does\n * - Why it's useful\n * - Examples of incorrect and correct code\n * - Configuration options explained\n */\n docs: string;\n}\n\n/**\n * Helper to define rule metadata with type safety\n */\nexport function defineRuleMeta(meta: RuleMeta): RuleMeta {\n return meta;\n}\n"],"mappings":";AAIA,SAAS,mBAAmB;AAErB,IAAM,aAAa,YAAY;AAAA,EACpC,CAAC,SACC,uFAAuF,IAAI;AAC/F;AA2EO,SAAS,eAAe,MAA0B;AACvD,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// src/utils/export-resolver.ts
|
|
2
|
+
import { ResolverFactory } from "oxc-resolver";
|
|
3
|
+
import { parse } from "@typescript-eslint/typescript-estree";
|
|
4
|
+
import { readFileSync, existsSync } from "fs";
|
|
5
|
+
import { dirname, join } from "path";
|
|
6
|
+
var resolverFactory = null;
|
|
7
|
+
var exportCache = /* @__PURE__ */ new Map();
|
|
8
|
+
var astCache = /* @__PURE__ */ new Map();
|
|
9
|
+
var resolvedPathCache = /* @__PURE__ */ new Map();
|
|
10
|
+
function getResolverFactory() {
|
|
11
|
+
if (!resolverFactory) {
|
|
12
|
+
resolverFactory = new ResolverFactory({
|
|
13
|
+
extensions: [".tsx", ".ts", ".jsx", ".js"],
|
|
14
|
+
mainFields: ["module", "main"],
|
|
15
|
+
conditionNames: ["import", "require", "node", "default"],
|
|
16
|
+
// Enable TypeScript path resolution
|
|
17
|
+
tsconfig: {
|
|
18
|
+
configFile: "tsconfig.json",
|
|
19
|
+
references: "auto"
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return resolverFactory;
|
|
24
|
+
}
|
|
25
|
+
function resolveImportPath(importSource, fromFile) {
|
|
26
|
+
const cacheKey = `${fromFile}::${importSource}`;
|
|
27
|
+
if (resolvedPathCache.has(cacheKey)) {
|
|
28
|
+
return resolvedPathCache.get(cacheKey) ?? null;
|
|
29
|
+
}
|
|
30
|
+
if (importSource.startsWith("react") || importSource.startsWith("next") || !importSource.startsWith(".") && !importSource.startsWith("@/") && !importSource.startsWith("~/")) {
|
|
31
|
+
if (importSource.includes("@mui/") || importSource.includes("@chakra-ui/") || importSource.includes("antd") || importSource.includes("@radix-ui/")) {
|
|
32
|
+
resolvedPathCache.set(cacheKey, null);
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
resolvedPathCache.set(cacheKey, null);
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const factory = getResolverFactory();
|
|
40
|
+
const fromDir = dirname(fromFile);
|
|
41
|
+
const result = factory.sync(fromDir, importSource);
|
|
42
|
+
if (result.path) {
|
|
43
|
+
resolvedPathCache.set(cacheKey, result.path);
|
|
44
|
+
return result.path;
|
|
45
|
+
}
|
|
46
|
+
} catch {
|
|
47
|
+
const resolved = manualResolve(importSource, fromFile);
|
|
48
|
+
resolvedPathCache.set(cacheKey, resolved);
|
|
49
|
+
return resolved;
|
|
50
|
+
}
|
|
51
|
+
resolvedPathCache.set(cacheKey, null);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
function manualResolve(importSource, fromFile) {
|
|
55
|
+
const fromDir = dirname(fromFile);
|
|
56
|
+
const extensions = [".tsx", ".ts", ".jsx", ".js"];
|
|
57
|
+
if (importSource.startsWith("@/")) {
|
|
58
|
+
const projectRoot = findProjectRoot(fromFile);
|
|
59
|
+
if (projectRoot) {
|
|
60
|
+
const relativePath = importSource.slice(2);
|
|
61
|
+
for (const ext of extensions) {
|
|
62
|
+
const candidate = join(projectRoot, relativePath + ext);
|
|
63
|
+
if (existsSync(candidate)) {
|
|
64
|
+
return candidate;
|
|
65
|
+
}
|
|
66
|
+
const indexCandidate = join(projectRoot, relativePath, `index${ext}`);
|
|
67
|
+
if (existsSync(indexCandidate)) {
|
|
68
|
+
return indexCandidate;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (importSource.startsWith(".")) {
|
|
74
|
+
for (const ext of extensions) {
|
|
75
|
+
const candidate = join(fromDir, importSource + ext);
|
|
76
|
+
if (existsSync(candidate)) {
|
|
77
|
+
return candidate;
|
|
78
|
+
}
|
|
79
|
+
const indexCandidate = join(fromDir, importSource, `index${ext}`);
|
|
80
|
+
if (existsSync(indexCandidate)) {
|
|
81
|
+
return indexCandidate;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
function findProjectRoot(fromFile) {
|
|
88
|
+
let dir = dirname(fromFile);
|
|
89
|
+
const root = "/";
|
|
90
|
+
while (dir !== root) {
|
|
91
|
+
if (existsSync(join(dir, "tsconfig.json"))) {
|
|
92
|
+
return dir;
|
|
93
|
+
}
|
|
94
|
+
if (existsSync(join(dir, "package.json"))) {
|
|
95
|
+
return dir;
|
|
96
|
+
}
|
|
97
|
+
dir = dirname(dir);
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
function parseFile(filePath) {
|
|
102
|
+
if (astCache.has(filePath)) {
|
|
103
|
+
return astCache.get(filePath);
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
const content = readFileSync(filePath, "utf-8");
|
|
107
|
+
const ast = parse(content, {
|
|
108
|
+
jsx: true,
|
|
109
|
+
loc: true,
|
|
110
|
+
range: true
|
|
111
|
+
});
|
|
112
|
+
astCache.set(filePath, ast);
|
|
113
|
+
return ast;
|
|
114
|
+
} catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function extractExports(filePath) {
|
|
119
|
+
if (exportCache.has(filePath)) {
|
|
120
|
+
return exportCache.get(filePath);
|
|
121
|
+
}
|
|
122
|
+
const exports = /* @__PURE__ */ new Map();
|
|
123
|
+
const ast = parseFile(filePath);
|
|
124
|
+
if (!ast) {
|
|
125
|
+
exportCache.set(filePath, exports);
|
|
126
|
+
return exports;
|
|
127
|
+
}
|
|
128
|
+
for (const node of ast.body) {
|
|
129
|
+
if (node.type === "ExportNamedDeclaration" && node.declaration?.type === "FunctionDeclaration" && node.declaration.id) {
|
|
130
|
+
exports.set(node.declaration.id.name, {
|
|
131
|
+
localName: node.declaration.id.name
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
if (node.type === "ExportNamedDeclaration" && node.declaration?.type === "VariableDeclaration") {
|
|
135
|
+
for (const decl of node.declaration.declarations) {
|
|
136
|
+
if (decl.id.type === "Identifier") {
|
|
137
|
+
exports.set(decl.id.name, { localName: decl.id.name });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (node.type === "ExportNamedDeclaration" && node.specifiers.length > 0) {
|
|
142
|
+
const source = node.source?.value;
|
|
143
|
+
for (const spec of node.specifiers) {
|
|
144
|
+
if (spec.type === "ExportSpecifier") {
|
|
145
|
+
const exportedName = spec.exported.type === "Identifier" ? spec.exported.name : spec.exported.value;
|
|
146
|
+
const localName = spec.local.type === "Identifier" ? spec.local.name : spec.local.value;
|
|
147
|
+
exports.set(exportedName, {
|
|
148
|
+
localName,
|
|
149
|
+
reexportSource: source
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (node.type === "ExportDefaultDeclaration" && node.declaration.type === "FunctionDeclaration" && node.declaration.id) {
|
|
155
|
+
exports.set("default", { localName: node.declaration.id.name });
|
|
156
|
+
}
|
|
157
|
+
if (node.type === "ExportDefaultDeclaration" && node.declaration.type === "Identifier") {
|
|
158
|
+
exports.set("default", { localName: node.declaration.name });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
exportCache.set(filePath, exports);
|
|
162
|
+
return exports;
|
|
163
|
+
}
|
|
164
|
+
function resolveExport(exportName, filePath, visited = /* @__PURE__ */ new Set()) {
|
|
165
|
+
const key = `${filePath}::${exportName}`;
|
|
166
|
+
if (visited.has(key)) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
visited.add(key);
|
|
170
|
+
const exports = extractExports(filePath);
|
|
171
|
+
const exportInfo = exports.get(exportName);
|
|
172
|
+
if (!exportInfo) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
if (exportInfo.reexportSource) {
|
|
176
|
+
const resolvedPath = resolveImportPath(exportInfo.reexportSource, filePath);
|
|
177
|
+
if (resolvedPath) {
|
|
178
|
+
return resolveExport(exportInfo.localName, resolvedPath, visited);
|
|
179
|
+
}
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
name: exportName,
|
|
184
|
+
filePath,
|
|
185
|
+
localName: exportInfo.localName,
|
|
186
|
+
isReexport: false
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function clearResolverCaches() {
|
|
190
|
+
exportCache.clear();
|
|
191
|
+
astCache.clear();
|
|
192
|
+
resolvedPathCache.clear();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export {
|
|
196
|
+
resolveImportPath,
|
|
197
|
+
parseFile,
|
|
198
|
+
resolveExport,
|
|
199
|
+
clearResolverCaches
|
|
200
|
+
};
|
|
201
|
+
//# sourceMappingURL=chunk-MFIU3O2I.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/export-resolver.ts"],"sourcesContent":["/**\n * Export Resolver\n *\n * Resolves import paths and finds export definitions, following re-exports\n * to their original source files.\n */\n\nimport { ResolverFactory } from \"oxc-resolver\";\nimport { parse } from \"@typescript-eslint/typescript-estree\";\nimport { readFileSync, existsSync } from \"fs\";\nimport { dirname, join, extname } from \"path\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\n// Module-level resolver instance (reused across calls)\nlet resolverInstance: ReturnType<typeof ResolverFactory.prototype.sync> | null =\n null;\nlet resolverFactory: ResolverFactory | null = null;\n\n/**\n * Information about a resolved export\n */\nexport interface ResolvedExport {\n /** The name of the export (e.g., \"Button\") */\n name: string;\n /** Absolute path to the file containing the actual definition */\n filePath: string;\n /** The local name in the source file (may differ from export name) */\n localName: string;\n /** Whether this is a re-export (export { X } from './other') */\n isReexport: boolean;\n}\n\n/**\n * Cache for file exports to avoid re-parsing\n */\nconst exportCache = new Map<\n string,\n Map<string, { localName: string; reexportSource?: string }>\n>();\n\n/**\n * Cache for parsed ASTs\n */\nconst astCache = new Map<string, TSESTree.Program>();\n\n/**\n * Cache for resolved paths\n */\nconst resolvedPathCache = new Map<string, string | null>();\n\n/**\n * Get or create the resolver factory\n */\nfunction getResolverFactory(): ResolverFactory {\n if (!resolverFactory) {\n resolverFactory = new ResolverFactory({\n extensions: [\".tsx\", \".ts\", \".jsx\", \".js\"],\n mainFields: [\"module\", \"main\"],\n conditionNames: [\"import\", \"require\", \"node\", \"default\"],\n // Enable TypeScript path resolution\n tsconfig: {\n configFile: \"tsconfig.json\",\n references: \"auto\",\n },\n });\n }\n return resolverFactory;\n}\n\n/**\n * Resolve an import path to an absolute file path\n */\nexport function resolveImportPath(\n importSource: string,\n fromFile: string\n): string | null {\n const cacheKey = `${fromFile}::${importSource}`;\n\n if (resolvedPathCache.has(cacheKey)) {\n return resolvedPathCache.get(cacheKey) ?? null;\n }\n\n // Skip node_modules\n if (\n importSource.startsWith(\"react\") ||\n importSource.startsWith(\"next\") ||\n (!importSource.startsWith(\".\") &&\n !importSource.startsWith(\"@/\") &&\n !importSource.startsWith(\"~/\"))\n ) {\n // Check if it's a known external package\n if (\n importSource.includes(\"@mui/\") ||\n importSource.includes(\"@chakra-ui/\") ||\n importSource.includes(\"antd\") ||\n importSource.includes(\"@radix-ui/\")\n ) {\n // Return a marker for external packages - we don't resolve them but track them\n resolvedPathCache.set(cacheKey, null);\n return null;\n }\n resolvedPathCache.set(cacheKey, null);\n return null;\n }\n\n try {\n const factory = getResolverFactory();\n const fromDir = dirname(fromFile);\n const result = factory.sync(fromDir, importSource);\n\n if (result.path) {\n resolvedPathCache.set(cacheKey, result.path);\n return result.path;\n }\n } catch {\n // Fallback: try manual resolution for common patterns\n const resolved = manualResolve(importSource, fromFile);\n resolvedPathCache.set(cacheKey, resolved);\n return resolved;\n }\n\n resolvedPathCache.set(cacheKey, null);\n return null;\n}\n\n/**\n * Manual fallback resolution for common patterns\n */\nfunction manualResolve(importSource: string, fromFile: string): string | null {\n const fromDir = dirname(fromFile);\n const extensions = [\".tsx\", \".ts\", \".jsx\", \".js\"];\n\n // Handle @/ alias - find tsconfig and resolve\n if (importSource.startsWith(\"@/\")) {\n const projectRoot = findProjectRoot(fromFile);\n if (projectRoot) {\n const relativePath = importSource.slice(2); // Remove @/\n for (const ext of extensions) {\n const candidate = join(projectRoot, relativePath + ext);\n if (existsSync(candidate)) {\n return candidate;\n }\n // Try index file\n const indexCandidate = join(projectRoot, relativePath, `index${ext}`);\n if (existsSync(indexCandidate)) {\n return indexCandidate;\n }\n }\n }\n }\n\n // Handle relative imports\n if (importSource.startsWith(\".\")) {\n for (const ext of extensions) {\n const candidate = join(fromDir, importSource + ext);\n if (existsSync(candidate)) {\n return candidate;\n }\n // Try index file\n const indexCandidate = join(fromDir, importSource, `index${ext}`);\n if (existsSync(indexCandidate)) {\n return indexCandidate;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Find the project root by looking for tsconfig.json or package.json\n */\nfunction findProjectRoot(fromFile: string): string | null {\n let dir = dirname(fromFile);\n const root = \"/\";\n\n while (dir !== root) {\n if (existsSync(join(dir, \"tsconfig.json\"))) {\n return dir;\n }\n if (existsSync(join(dir, \"package.json\"))) {\n return dir;\n }\n dir = dirname(dir);\n }\n\n return null;\n}\n\n/**\n * Parse a file and cache the AST\n */\nexport function parseFile(filePath: string): TSESTree.Program | null {\n if (astCache.has(filePath)) {\n return astCache.get(filePath)!;\n }\n\n try {\n const content = readFileSync(filePath, \"utf-8\");\n const ast = parse(content, {\n jsx: true,\n loc: true,\n range: true,\n });\n astCache.set(filePath, ast);\n return ast;\n } catch {\n return null;\n }\n}\n\n/**\n * Extract export information from a file\n */\nfunction extractExports(\n filePath: string\n): Map<string, { localName: string; reexportSource?: string }> {\n if (exportCache.has(filePath)) {\n return exportCache.get(filePath)!;\n }\n\n const exports = new Map<\n string,\n { localName: string; reexportSource?: string }\n >();\n const ast = parseFile(filePath);\n\n if (!ast) {\n exportCache.set(filePath, exports);\n return exports;\n }\n\n for (const node of ast.body) {\n // Handle: export function Button() {}\n if (\n node.type === \"ExportNamedDeclaration\" &&\n node.declaration?.type === \"FunctionDeclaration\" &&\n node.declaration.id\n ) {\n exports.set(node.declaration.id.name, {\n localName: node.declaration.id.name,\n });\n }\n\n // Handle: export const Button = () => {}\n if (\n node.type === \"ExportNamedDeclaration\" &&\n node.declaration?.type === \"VariableDeclaration\"\n ) {\n for (const decl of node.declaration.declarations) {\n if (decl.id.type === \"Identifier\") {\n exports.set(decl.id.name, { localName: decl.id.name });\n }\n }\n }\n\n // Handle: export { Button } or export { Button as Btn }\n if (node.type === \"ExportNamedDeclaration\" && node.specifiers.length > 0) {\n const source = node.source?.value as string | undefined;\n for (const spec of node.specifiers) {\n if (spec.type === \"ExportSpecifier\") {\n const exportedName =\n spec.exported.type === \"Identifier\"\n ? spec.exported.name\n : spec.exported.value;\n const localName =\n spec.local.type === \"Identifier\"\n ? spec.local.name\n : spec.local.value;\n\n exports.set(exportedName, {\n localName,\n reexportSource: source,\n });\n }\n }\n }\n\n // Handle: export default function Button() {}\n if (\n node.type === \"ExportDefaultDeclaration\" &&\n node.declaration.type === \"FunctionDeclaration\" &&\n node.declaration.id\n ) {\n exports.set(\"default\", { localName: node.declaration.id.name });\n }\n\n // Handle: export default Button\n if (\n node.type === \"ExportDefaultDeclaration\" &&\n node.declaration.type === \"Identifier\"\n ) {\n exports.set(\"default\", { localName: node.declaration.name });\n }\n }\n\n exportCache.set(filePath, exports);\n return exports;\n}\n\n/**\n * Resolve an export to its original definition, following re-exports\n */\nexport function resolveExport(\n exportName: string,\n filePath: string,\n visited = new Set<string>()\n): ResolvedExport | null {\n // Cycle detection\n const key = `${filePath}::${exportName}`;\n if (visited.has(key)) {\n return null;\n }\n visited.add(key);\n\n const exports = extractExports(filePath);\n const exportInfo = exports.get(exportName);\n\n if (!exportInfo) {\n return null;\n }\n\n // If it's a re-export, follow the chain\n if (exportInfo.reexportSource) {\n const resolvedPath = resolveImportPath(exportInfo.reexportSource, filePath);\n if (resolvedPath) {\n return resolveExport(exportInfo.localName, resolvedPath, visited);\n }\n return null;\n }\n\n // This is the actual definition\n return {\n name: exportName,\n filePath,\n localName: exportInfo.localName,\n isReexport: false,\n };\n}\n\n/**\n * Clear all caches (useful for testing or watch mode)\n */\nexport function clearResolverCaches(): void {\n exportCache.clear();\n astCache.clear();\n resolvedPathCache.clear();\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,72 @@ import { ESLintUtils } from '@typescript-eslint/utils';
|
|
|
9
9
|
declare const createRule: <Options extends readonly unknown[], MessageIds extends string>({ meta, name, ...rule }: Readonly<ESLintUtils.RuleWithMetaAndName<Options, MessageIds, unknown>>) => ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener> & {
|
|
10
10
|
name: string;
|
|
11
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* Schema for prompting user to configure a rule option in the CLI
|
|
14
|
+
*/
|
|
15
|
+
interface OptionFieldSchema {
|
|
16
|
+
/** Field name in the options object */
|
|
17
|
+
key: string;
|
|
18
|
+
/** Display label for the prompt */
|
|
19
|
+
label: string;
|
|
20
|
+
/** Prompt type */
|
|
21
|
+
type: "text" | "number" | "boolean" | "select" | "multiselect";
|
|
22
|
+
/** Default value */
|
|
23
|
+
defaultValue: unknown;
|
|
24
|
+
/** Placeholder text (for text/number inputs) */
|
|
25
|
+
placeholder?: string;
|
|
26
|
+
/** Options for select/multiselect */
|
|
27
|
+
options?: Array<{
|
|
28
|
+
value: string | number;
|
|
29
|
+
label: string;
|
|
30
|
+
}>;
|
|
31
|
+
/** Description/hint for the field */
|
|
32
|
+
description?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Schema describing how to prompt for rule options during installation
|
|
36
|
+
*/
|
|
37
|
+
interface RuleOptionSchema {
|
|
38
|
+
/** Fields that can be configured for this rule */
|
|
39
|
+
fields: OptionFieldSchema[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Colocated rule metadata - exported alongside each rule
|
|
43
|
+
*
|
|
44
|
+
* This structure keeps all rule metadata in the same file as the rule implementation,
|
|
45
|
+
* making it easy to maintain and extend as new rules are added.
|
|
46
|
+
*/
|
|
47
|
+
interface RuleMeta {
|
|
48
|
+
/** Rule identifier (e.g., "no-arbitrary-tailwind") - must match filename */
|
|
49
|
+
id: string;
|
|
50
|
+
/** Display name for CLI (e.g., "No Arbitrary Tailwind") */
|
|
51
|
+
name: string;
|
|
52
|
+
/** Short description for CLI selection prompts (one line) */
|
|
53
|
+
description: string;
|
|
54
|
+
/** Default severity level */
|
|
55
|
+
defaultSeverity: "error" | "warn" | "off";
|
|
56
|
+
/** Category for grouping in CLI */
|
|
57
|
+
category: "static" | "semantic";
|
|
58
|
+
/** Whether this rule requires a styleguide file */
|
|
59
|
+
requiresStyleguide?: boolean;
|
|
60
|
+
/** Default options for the rule (passed as second element in ESLint config) */
|
|
61
|
+
defaultOptions?: unknown[];
|
|
62
|
+
/** Schema for prompting user to configure options during install */
|
|
63
|
+
optionSchema?: RuleOptionSchema;
|
|
64
|
+
/**
|
|
65
|
+
* Detailed documentation in markdown format.
|
|
66
|
+
* Should include:
|
|
67
|
+
* - What the rule does
|
|
68
|
+
* - Why it's useful
|
|
69
|
+
* - Examples of incorrect and correct code
|
|
70
|
+
* - Configuration options explained
|
|
71
|
+
*/
|
|
72
|
+
docs: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Helper to define rule metadata with type safety
|
|
76
|
+
*/
|
|
77
|
+
declare function defineRuleMeta(meta: RuleMeta): RuleMeta;
|
|
12
78
|
|
|
13
79
|
/**
|
|
14
80
|
* Styleguide loader for the LLM semantic rule
|
|
@@ -139,74 +205,36 @@ declare function clearCache(): void;
|
|
|
139
205
|
* Rule Registry
|
|
140
206
|
*
|
|
141
207
|
* Central registry of all UILint ESLint rules with metadata for CLI tooling.
|
|
142
|
-
*
|
|
143
|
-
*
|
|
208
|
+
* Metadata is now colocated with each rule file - this module re-exports
|
|
209
|
+
* the collected metadata for use by installers and other tools.
|
|
144
210
|
*/
|
|
145
|
-
|
|
146
|
-
* Schema for prompting user to configure a rule option
|
|
147
|
-
*/
|
|
148
|
-
interface OptionFieldSchema {
|
|
149
|
-
/** Field name in the options object */
|
|
150
|
-
key: string;
|
|
151
|
-
/** Display label for the prompt */
|
|
152
|
-
label: string;
|
|
153
|
-
/** Prompt type */
|
|
154
|
-
type: "text" | "number" | "boolean" | "select" | "multiselect";
|
|
155
|
-
/** Default value */
|
|
156
|
-
defaultValue: unknown;
|
|
157
|
-
/** Placeholder text (for text/number inputs) */
|
|
158
|
-
placeholder?: string;
|
|
159
|
-
/** Options for select/multiselect */
|
|
160
|
-
options?: Array<{
|
|
161
|
-
value: string | number;
|
|
162
|
-
label: string;
|
|
163
|
-
}>;
|
|
164
|
-
/** Description/hint for the field */
|
|
165
|
-
description?: string;
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Schema describing how to prompt for rule options during installation
|
|
169
|
-
*/
|
|
170
|
-
interface RuleOptionSchema {
|
|
171
|
-
/** Fields that can be configured for this rule */
|
|
172
|
-
fields: OptionFieldSchema[];
|
|
173
|
-
}
|
|
174
|
-
interface RuleMetadata {
|
|
175
|
-
/** Rule identifier (e.g., "no-arbitrary-tailwind") */
|
|
176
|
-
id: string;
|
|
177
|
-
/** Display name for CLI */
|
|
178
|
-
name: string;
|
|
179
|
-
/** Short description for CLI selection prompts */
|
|
180
|
-
description: string;
|
|
181
|
-
/** Default severity level */
|
|
182
|
-
defaultSeverity: "error" | "warn" | "off";
|
|
183
|
-
/** Default options for the rule */
|
|
184
|
-
defaultOptions?: unknown[];
|
|
185
|
-
/** Schema for prompting user to configure options during install */
|
|
186
|
-
optionSchema?: RuleOptionSchema;
|
|
187
|
-
/** Whether this rule requires a styleguide file */
|
|
188
|
-
requiresStyleguide?: boolean;
|
|
189
|
-
/** Category for grouping */
|
|
190
|
-
category: "static" | "semantic";
|
|
191
|
-
}
|
|
211
|
+
|
|
192
212
|
/**
|
|
193
213
|
* Registry of all available UILint ESLint rules
|
|
194
214
|
*
|
|
195
215
|
* When adding a new rule:
|
|
196
|
-
* 1.
|
|
197
|
-
* 2.
|
|
198
|
-
* 3.
|
|
199
|
-
* 4.
|
|
216
|
+
* 1. Create the rule file in src/rules/
|
|
217
|
+
* 2. Export a `meta` object using `defineRuleMeta()`
|
|
218
|
+
* 3. Import and add the meta to this array
|
|
219
|
+
* 4. Run `pnpm generate:index` to regenerate exports
|
|
200
220
|
*/
|
|
201
|
-
declare const ruleRegistry:
|
|
221
|
+
declare const ruleRegistry: RuleMeta[];
|
|
202
222
|
/**
|
|
203
223
|
* Get rule metadata by ID
|
|
204
224
|
*/
|
|
205
|
-
declare function getRuleMetadata(id: string):
|
|
225
|
+
declare function getRuleMetadata(id: string): RuleMeta | undefined;
|
|
206
226
|
/**
|
|
207
227
|
* Get all rules in a category
|
|
208
228
|
*/
|
|
209
|
-
declare function getRulesByCategory(category: "static" | "semantic"):
|
|
229
|
+
declare function getRulesByCategory(category: "static" | "semantic"): RuleMeta[];
|
|
230
|
+
/**
|
|
231
|
+
* Get documentation for a rule (useful for CLI help commands)
|
|
232
|
+
*/
|
|
233
|
+
declare function getRuleDocs(id: string): string | undefined;
|
|
234
|
+
/**
|
|
235
|
+
* Get all rule IDs
|
|
236
|
+
*/
|
|
237
|
+
declare function getAllRuleIds(): string[];
|
|
210
238
|
|
|
211
239
|
/**
|
|
212
240
|
* All available rules
|
|
@@ -256,6 +284,51 @@ declare const rules: {
|
|
|
256
284
|
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
257
285
|
name: string;
|
|
258
286
|
};
|
|
287
|
+
"enforce-absolute-imports": _typescript_eslint_utils_ts_eslint.RuleModule<"preferAbsoluteImport", [{
|
|
288
|
+
maxRelativeDepth?: number;
|
|
289
|
+
aliasPrefix?: string;
|
|
290
|
+
ignorePaths?: string[];
|
|
291
|
+
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
292
|
+
name: string;
|
|
293
|
+
};
|
|
294
|
+
"no-any-in-props": _typescript_eslint_utils_ts_eslint.RuleModule<"anyInProps" | "anyInPropsProperty", [{
|
|
295
|
+
checkFCGenerics?: boolean;
|
|
296
|
+
allowInGenericDefaults?: boolean;
|
|
297
|
+
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
298
|
+
name: string;
|
|
299
|
+
};
|
|
300
|
+
"zustand-use-selectors": _typescript_eslint_utils_ts_eslint.RuleModule<"missingSelector" | "useSelectorFunction", [{
|
|
301
|
+
storePattern?: string;
|
|
302
|
+
allowShallow?: boolean;
|
|
303
|
+
requireNamedSelectors?: boolean;
|
|
304
|
+
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
305
|
+
name: string;
|
|
306
|
+
};
|
|
307
|
+
"no-prop-drilling-depth": _typescript_eslint_utils_ts_eslint.RuleModule<"propDrilling", [{
|
|
308
|
+
maxDepth?: number;
|
|
309
|
+
ignoredProps?: string[];
|
|
310
|
+
ignoreComponents?: string[];
|
|
311
|
+
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
312
|
+
name: string;
|
|
313
|
+
};
|
|
314
|
+
"no-secrets-in-code": _typescript_eslint_utils_ts_eslint.RuleModule<"secretDetected" | "suspiciousVariable", [{
|
|
315
|
+
additionalPatterns?: Array<{
|
|
316
|
+
name: string;
|
|
317
|
+
pattern: string;
|
|
318
|
+
}>;
|
|
319
|
+
checkVariableNames?: boolean;
|
|
320
|
+
minSecretLength?: number;
|
|
321
|
+
allowInTestFiles?: boolean;
|
|
322
|
+
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
323
|
+
name: string;
|
|
324
|
+
};
|
|
325
|
+
"require-input-validation": _typescript_eslint_utils_ts_eslint.RuleModule<"missingValidation" | "unvalidatedBodyAccess", [{
|
|
326
|
+
httpMethods?: string[];
|
|
327
|
+
routePatterns?: string[];
|
|
328
|
+
allowManualValidation?: boolean;
|
|
329
|
+
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
330
|
+
name: string;
|
|
331
|
+
};
|
|
259
332
|
};
|
|
260
333
|
/**
|
|
261
334
|
* Plugin metadata
|
|
@@ -317,6 +390,51 @@ declare const plugin: {
|
|
|
317
390
|
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
318
391
|
name: string;
|
|
319
392
|
};
|
|
393
|
+
"enforce-absolute-imports": _typescript_eslint_utils_ts_eslint.RuleModule<"preferAbsoluteImport", [{
|
|
394
|
+
maxRelativeDepth?: number;
|
|
395
|
+
aliasPrefix?: string;
|
|
396
|
+
ignorePaths?: string[];
|
|
397
|
+
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
398
|
+
name: string;
|
|
399
|
+
};
|
|
400
|
+
"no-any-in-props": _typescript_eslint_utils_ts_eslint.RuleModule<"anyInProps" | "anyInPropsProperty", [{
|
|
401
|
+
checkFCGenerics?: boolean;
|
|
402
|
+
allowInGenericDefaults?: boolean;
|
|
403
|
+
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
404
|
+
name: string;
|
|
405
|
+
};
|
|
406
|
+
"zustand-use-selectors": _typescript_eslint_utils_ts_eslint.RuleModule<"missingSelector" | "useSelectorFunction", [{
|
|
407
|
+
storePattern?: string;
|
|
408
|
+
allowShallow?: boolean;
|
|
409
|
+
requireNamedSelectors?: boolean;
|
|
410
|
+
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
411
|
+
name: string;
|
|
412
|
+
};
|
|
413
|
+
"no-prop-drilling-depth": _typescript_eslint_utils_ts_eslint.RuleModule<"propDrilling", [{
|
|
414
|
+
maxDepth?: number;
|
|
415
|
+
ignoredProps?: string[];
|
|
416
|
+
ignoreComponents?: string[];
|
|
417
|
+
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
418
|
+
name: string;
|
|
419
|
+
};
|
|
420
|
+
"no-secrets-in-code": _typescript_eslint_utils_ts_eslint.RuleModule<"secretDetected" | "suspiciousVariable", [{
|
|
421
|
+
additionalPatterns?: Array<{
|
|
422
|
+
name: string;
|
|
423
|
+
pattern: string;
|
|
424
|
+
}>;
|
|
425
|
+
checkVariableNames?: boolean;
|
|
426
|
+
minSecretLength?: number;
|
|
427
|
+
allowInTestFiles?: boolean;
|
|
428
|
+
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
429
|
+
name: string;
|
|
430
|
+
};
|
|
431
|
+
"require-input-validation": _typescript_eslint_utils_ts_eslint.RuleModule<"missingValidation" | "unvalidatedBodyAccess", [{
|
|
432
|
+
httpMethods?: string[];
|
|
433
|
+
routePatterns?: string[];
|
|
434
|
+
allowManualValidation?: boolean;
|
|
435
|
+
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
436
|
+
name: string;
|
|
437
|
+
};
|
|
320
438
|
};
|
|
321
439
|
};
|
|
322
440
|
/**
|
|
@@ -337,4 +455,4 @@ interface UILintESLint {
|
|
|
337
455
|
*/
|
|
338
456
|
declare const uilintEslint: UILintESLint;
|
|
339
457
|
|
|
340
|
-
export { type CacheEntry, type CacheStore, type CachedIssue, type LibraryName, type OptionFieldSchema, type RuleMetadata, type RuleOptionSchema, type UILintESLint, clearCache$1 as clearCache, clearCacheEntry, clearCache as clearImportGraphCache, configs, createRule, uilintEslint as default, findStyleguidePath, getCacheEntry, getComponentLibrary, getRuleMetadata, getRulesByCategory, getStyleguide, hashContent, hashContentSync, loadCache, loadStyleguide, meta, plugin, ruleRegistry, rules, saveCache, setCacheEntry };
|
|
458
|
+
export { type CacheEntry, type CacheStore, type CachedIssue, type LibraryName, type OptionFieldSchema, type RuleMeta, type RuleMeta as RuleMetadata, type RuleOptionSchema, type UILintESLint, clearCache$1 as clearCache, clearCacheEntry, clearCache as clearImportGraphCache, configs, createRule, uilintEslint as default, defineRuleMeta, findStyleguidePath, getAllRuleIds, getCacheEntry, getComponentLibrary, getRuleDocs, getRuleMetadata, getRulesByCategory, getStyleguide, hashContent, hashContentSync, loadCache, loadStyleguide, meta, plugin, ruleRegistry, rules, saveCache, setCacheEntry };
|