uilint-eslint 0.2.67 → 0.2.69
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/README.md +0 -6
- package/dist/index.d.ts +1 -7
- package/dist/index.js +44 -168
- package/dist/index.js.map +1 -1
- package/dist/rules/consistent-dark-mode.js.map +1 -1
- package/dist/rules/enforce-absolute-imports.js.map +1 -1
- package/dist/rules/no-any-in-props.js.map +1 -1
- package/dist/rules/no-direct-store-import.js.map +1 -1
- package/dist/rules/no-mixed-component-libraries.js.map +1 -1
- package/dist/rules/no-prop-drilling-depth.js.map +1 -1
- package/dist/rules/no-secrets-in-code.js.map +1 -1
- package/dist/rules/no-semantic-duplicates.js.map +1 -1
- package/dist/rules/prefer-tailwind.js.map +1 -1
- package/dist/rules/prefer-zustand-state-management.js.map +1 -1
- package/dist/rules/require-input-validation.js.map +1 -1
- package/dist/rules/require-test-coverage.js.map +1 -1
- package/dist/rules/semantic-vision.js.map +1 -1
- package/dist/rules/semantic.js.map +1 -1
- package/dist/rules/zustand-use-selectors.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +0 -4
- package/src/rule-registry.test.ts +3 -3
- package/src/rule-registry.ts +0 -2
- package/src/utils/create-rule.ts +1 -1
- package/dist/rules/no-arbitrary-tailwind.js +0 -133
- package/dist/rules/no-arbitrary-tailwind.js.map +0 -1
- package/src/rules/no-arbitrary-tailwind.ts +0 -160
package/README.md
CHANGED
|
@@ -27,7 +27,6 @@ export default [
|
|
|
27
27
|
{
|
|
28
28
|
plugins: { uilint: uilint.plugin },
|
|
29
29
|
rules: {
|
|
30
|
-
"uilint/no-arbitrary-tailwind": "error",
|
|
31
30
|
"uilint/consistent-spacing": [
|
|
32
31
|
"warn",
|
|
33
32
|
{ scale: [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16] },
|
|
@@ -48,7 +47,6 @@ export default [
|
|
|
48
47
|
|
|
49
48
|
| Rule | Description |
|
|
50
49
|
| ------------------------------ | ------------------------------------------------------- |
|
|
51
|
-
| `no-arbitrary-tailwind` | Forbid arbitrary Tailwind values like `w-[123px]` |
|
|
52
50
|
| `consistent-spacing` | Enforce spacing scale (no magic numbers in gap/padding) |
|
|
53
51
|
| `no-direct-store-import` | Forbid direct Zustand store imports (use hooks) |
|
|
54
52
|
| `no-mixed-component-libraries` | Forbid mixing shadcn and MUI components in same file |
|
|
@@ -63,10 +61,6 @@ The `semantic` rule reads `.uilint/styleguide.md` and uses Ollama to analyze you
|
|
|
63
61
|
|
|
64
62
|
## Configuration
|
|
65
63
|
|
|
66
|
-
### `no-arbitrary-tailwind`
|
|
67
|
-
|
|
68
|
-
No options. Reports any use of Tailwind arbitrary values like `w-[100px]`, `bg-[#fff]`, etc.
|
|
69
|
-
|
|
70
64
|
### `consistent-spacing`
|
|
71
65
|
|
|
72
66
|
```javascript
|
package/dist/index.d.ts
CHANGED
|
@@ -72,7 +72,7 @@ interface RuleMigration {
|
|
|
72
72
|
* making it easy to maintain and extend as new rules are added.
|
|
73
73
|
*/
|
|
74
74
|
interface RuleMeta {
|
|
75
|
-
/** Rule identifier (e.g., "
|
|
75
|
+
/** Rule identifier (e.g., "consistent-dark-mode") - must match filename */
|
|
76
76
|
id: string;
|
|
77
77
|
/** Semantic version of the rule (e.g., "1.0.0") */
|
|
78
78
|
version: string;
|
|
@@ -672,9 +672,6 @@ declare function analyzeJSXElementCoverage(jsxNode: TSESTree.JSXElement, filePat
|
|
|
672
672
|
* All available rules
|
|
673
673
|
*/
|
|
674
674
|
declare const rules: {
|
|
675
|
-
"no-arbitrary-tailwind": _typescript_eslint_utils_ts_eslint.RuleModule<"noArbitraryValue", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
676
|
-
name: string;
|
|
677
|
-
};
|
|
678
675
|
"consistent-dark-mode": _typescript_eslint_utils_ts_eslint.RuleModule<"inconsistentDarkMode" | "missingDarkMode", [({
|
|
679
676
|
warnOnMissingDarkMode?: boolean;
|
|
680
677
|
} | undefined)?], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
@@ -818,9 +815,6 @@ declare const plugin: {
|
|
|
818
815
|
version: string;
|
|
819
816
|
};
|
|
820
817
|
rules: {
|
|
821
|
-
"no-arbitrary-tailwind": _typescript_eslint_utils_ts_eslint.RuleModule<"noArbitraryValue", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
822
|
-
name: string;
|
|
823
|
-
};
|
|
824
818
|
"consistent-dark-mode": _typescript_eslint_utils_ts_eslint.RuleModule<"inconsistentDarkMode" | "missingDarkMode", [({
|
|
825
819
|
warnOnMissingDarkMode?: boolean;
|
|
826
820
|
} | undefined)?], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
package/dist/index.js
CHANGED
|
@@ -3,132 +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(
|
|
7
|
-
return
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
// src/rules/no-arbitrary-tailwind.ts
|
|
11
|
-
var meta = defineRuleMeta({
|
|
12
|
-
id: "no-arbitrary-tailwind",
|
|
13
|
-
version: "1.0.0",
|
|
14
|
-
name: "No Arbitrary Tailwind",
|
|
15
|
-
description: "Forbid arbitrary values like w-[123px], bg-[#fff]",
|
|
16
|
-
defaultSeverity: "error",
|
|
17
|
-
category: "static",
|
|
18
|
-
icon: "\u{1F3A8}",
|
|
19
|
-
hint: "Enforces design system tokens",
|
|
20
|
-
defaultEnabled: true,
|
|
21
|
-
docs: `
|
|
22
|
-
## What it does
|
|
23
|
-
|
|
24
|
-
Prevents the use of arbitrary Tailwind CSS values (bracket notation) in your codebase.
|
|
25
|
-
Arbitrary values like \`w-[123px]\`, \`bg-[#ff5500]\`, or \`text-[14px]\` bypass Tailwind's
|
|
26
|
-
design system and can lead to inconsistent UI.
|
|
27
|
-
|
|
28
|
-
## Why it's useful
|
|
29
|
-
|
|
30
|
-
- **Consistency**: Forces use of your design system's spacing, colors, and typography scales
|
|
31
|
-
- **Maintainability**: Changes to design tokens automatically propagate everywhere
|
|
32
|
-
- **Performance**: Arbitrary values generate extra CSS that can't be deduplicated
|
|
33
|
-
|
|
34
|
-
## Examples
|
|
35
|
-
|
|
36
|
-
### \u274C Incorrect
|
|
37
|
-
|
|
38
|
-
\`\`\`tsx
|
|
39
|
-
<div className="w-[123px] h-[456px]"> // Arbitrary dimensions
|
|
40
|
-
<div className="bg-[#ff5500]"> // Arbitrary color
|
|
41
|
-
<div className="text-[14px]"> // Arbitrary font size
|
|
42
|
-
<div className="p-[7px]"> // Arbitrary padding
|
|
43
|
-
\`\`\`
|
|
44
|
-
|
|
45
|
-
### \u2705 Correct
|
|
46
|
-
|
|
47
|
-
\`\`\`tsx
|
|
48
|
-
<div className="w-32 h-96"> // Use spacing scale
|
|
49
|
-
<div className="bg-orange-500"> // Use color palette
|
|
50
|
-
<div className="text-sm"> // Use typography scale
|
|
51
|
-
<div className="p-2"> // Use spacing scale
|
|
52
|
-
\`\`\`
|
|
53
|
-
|
|
54
|
-
## Notes
|
|
55
|
-
|
|
56
|
-
- Data attributes like \`data-[state=open]\` are allowed as they don't affect styling
|
|
57
|
-
- If you need a truly custom value, consider extending your Tailwind config instead
|
|
58
|
-
`
|
|
59
|
-
});
|
|
60
|
-
var ARBITRARY_VALUE_REGEX = /\b[\w-]+-\[[^\]]+\]/g;
|
|
61
|
-
var no_arbitrary_tailwind_default = createRule({
|
|
62
|
-
name: "no-arbitrary-tailwind",
|
|
63
|
-
meta: {
|
|
64
|
-
type: "problem",
|
|
65
|
-
docs: {
|
|
66
|
-
description: "Forbid arbitrary Tailwind values like w-[123px]"
|
|
67
|
-
},
|
|
68
|
-
messages: {
|
|
69
|
-
noArbitraryValue: "Avoid arbitrary Tailwind value '{{value}}'. Use the spacing/color scale instead."
|
|
70
|
-
},
|
|
71
|
-
schema: []
|
|
72
|
-
},
|
|
73
|
-
defaultOptions: [],
|
|
74
|
-
create(context) {
|
|
75
|
-
return {
|
|
76
|
-
// Check className attributes in JSX
|
|
77
|
-
JSXAttribute(node) {
|
|
78
|
-
if (node.name.type === "JSXIdentifier" && (node.name.name === "className" || node.name.name === "class")) {
|
|
79
|
-
const value = node.value;
|
|
80
|
-
if (value?.type === "Literal" && typeof value.value === "string") {
|
|
81
|
-
checkClassString(context, value, value.value);
|
|
82
|
-
}
|
|
83
|
-
if (value?.type === "JSXExpressionContainer") {
|
|
84
|
-
const expr = value.expression;
|
|
85
|
-
if (expr.type === "Literal" && typeof expr.value === "string") {
|
|
86
|
-
checkClassString(context, expr, expr.value);
|
|
87
|
-
}
|
|
88
|
-
if (expr.type === "TemplateLiteral") {
|
|
89
|
-
for (const quasi of expr.quasis) {
|
|
90
|
-
checkClassString(context, quasi, quasi.value.raw);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
// Check cn(), clsx(), classnames() calls
|
|
97
|
-
CallExpression(node) {
|
|
98
|
-
if (node.callee.type !== "Identifier") return;
|
|
99
|
-
const name = node.callee.name;
|
|
100
|
-
if (name === "cn" || name === "clsx" || name === "classnames") {
|
|
101
|
-
for (const arg of node.arguments) {
|
|
102
|
-
if (arg.type === "Literal" && typeof arg.value === "string") {
|
|
103
|
-
checkClassString(context, arg, arg.value);
|
|
104
|
-
}
|
|
105
|
-
if (arg.type === "TemplateLiteral") {
|
|
106
|
-
for (const quasi of arg.quasis) {
|
|
107
|
-
checkClassString(context, quasi, quasi.value.raw);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
function checkClassString(context, node, classString) {
|
|
117
|
-
const matches = classString.matchAll(ARBITRARY_VALUE_REGEX);
|
|
118
|
-
for (const match of matches) {
|
|
119
|
-
if (match[0].startsWith("data-")) {
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
context.report({
|
|
123
|
-
node,
|
|
124
|
-
messageId: "noArbitraryValue",
|
|
125
|
-
data: { value: match[0] }
|
|
126
|
-
});
|
|
127
|
-
}
|
|
6
|
+
function defineRuleMeta(meta17) {
|
|
7
|
+
return meta17;
|
|
128
8
|
}
|
|
129
9
|
|
|
130
10
|
// src/rules/consistent-dark-mode.ts
|
|
131
|
-
var
|
|
11
|
+
var meta = defineRuleMeta({
|
|
132
12
|
id: "consistent-dark-mode",
|
|
133
13
|
version: "1.0.0",
|
|
134
14
|
name: "Consistent Dark Mode",
|
|
@@ -352,7 +232,7 @@ var consistent_dark_mode_default = createRule({
|
|
|
352
232
|
let fileHasColorClasses = false;
|
|
353
233
|
let fileHasDarkMode = false;
|
|
354
234
|
const reportedNodes = /* @__PURE__ */ new Set();
|
|
355
|
-
function
|
|
235
|
+
function checkClassString(node, classString) {
|
|
356
236
|
const classes = classString.split(/\s+/).filter(Boolean);
|
|
357
237
|
if (classes.length === 0) return;
|
|
358
238
|
const prefixUsage = /* @__PURE__ */ new Map();
|
|
@@ -401,11 +281,11 @@ var consistent_dark_mode_default = createRule({
|
|
|
401
281
|
}
|
|
402
282
|
}
|
|
403
283
|
function processStringValue(node, value) {
|
|
404
|
-
|
|
284
|
+
checkClassString(node, value);
|
|
405
285
|
}
|
|
406
286
|
function processTemplateLiteral(node) {
|
|
407
287
|
for (const quasi of node.quasis) {
|
|
408
|
-
|
|
288
|
+
checkClassString(quasi, quasi.value.raw);
|
|
409
289
|
}
|
|
410
290
|
}
|
|
411
291
|
return {
|
|
@@ -466,7 +346,7 @@ var consistent_dark_mode_default = createRule({
|
|
|
466
346
|
});
|
|
467
347
|
|
|
468
348
|
// src/rules/no-direct-store-import.ts
|
|
469
|
-
var
|
|
349
|
+
var meta2 = defineRuleMeta({
|
|
470
350
|
id: "no-direct-store-import",
|
|
471
351
|
version: "1.0.0",
|
|
472
352
|
name: "No Direct Store Import",
|
|
@@ -608,7 +488,7 @@ var no_direct_store_import_default = createRule({
|
|
|
608
488
|
});
|
|
609
489
|
|
|
610
490
|
// src/rules/prefer-zustand-state-management.ts
|
|
611
|
-
var
|
|
491
|
+
var meta3 = defineRuleMeta({
|
|
612
492
|
id: "prefer-zustand-state-management",
|
|
613
493
|
version: "1.0.0",
|
|
614
494
|
name: "Prefer Zustand State Management",
|
|
@@ -1391,7 +1271,7 @@ function clearCache() {
|
|
|
1391
1271
|
}
|
|
1392
1272
|
|
|
1393
1273
|
// src/rules/no-mixed-component-libraries/index.ts
|
|
1394
|
-
var
|
|
1274
|
+
var meta4 = defineRuleMeta({
|
|
1395
1275
|
id: "no-mixed-component-libraries",
|
|
1396
1276
|
version: "1.0.0",
|
|
1397
1277
|
name: "No Mixed Component Libraries",
|
|
@@ -1778,7 +1658,7 @@ function getStyleguide(startDir, explicitPath) {
|
|
|
1778
1658
|
// src/rules/semantic/index.ts
|
|
1779
1659
|
import { UILINT_DEFAULT_OLLAMA_MODEL } from "uilint-core";
|
|
1780
1660
|
import { buildSourceScanPrompt } from "uilint-core";
|
|
1781
|
-
var
|
|
1661
|
+
var meta5 = defineRuleMeta({
|
|
1782
1662
|
id: "semantic",
|
|
1783
1663
|
version: "1.0.0",
|
|
1784
1664
|
name: "Semantic Analysis",
|
|
@@ -2123,7 +2003,7 @@ function runSemanticAnalysisSync(sourceCode, styleguide, model, filePath) {
|
|
|
2123
2003
|
// src/rules/semantic-vision.ts
|
|
2124
2004
|
import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync5 } from "fs";
|
|
2125
2005
|
import { dirname as dirname5, join as join5, relative as relative2 } from "path";
|
|
2126
|
-
var
|
|
2006
|
+
var meta6 = defineRuleMeta({
|
|
2127
2007
|
id: "semantic-vision",
|
|
2128
2008
|
version: "1.0.0",
|
|
2129
2009
|
name: "Vision Analysis",
|
|
@@ -2347,7 +2227,7 @@ var semantic_vision_default = createRule({
|
|
|
2347
2227
|
});
|
|
2348
2228
|
|
|
2349
2229
|
// src/rules/enforce-absolute-imports.ts
|
|
2350
|
-
var
|
|
2230
|
+
var meta7 = defineRuleMeta({
|
|
2351
2231
|
id: "enforce-absolute-imports",
|
|
2352
2232
|
version: "1.0.0",
|
|
2353
2233
|
name: "Enforce Absolute Imports",
|
|
@@ -2523,7 +2403,7 @@ var enforce_absolute_imports_default = createRule({
|
|
|
2523
2403
|
});
|
|
2524
2404
|
|
|
2525
2405
|
// src/rules/no-any-in-props.ts
|
|
2526
|
-
var
|
|
2406
|
+
var meta8 = defineRuleMeta({
|
|
2527
2407
|
id: "no-any-in-props",
|
|
2528
2408
|
version: "1.0.0",
|
|
2529
2409
|
name: "No Any in Props",
|
|
@@ -2873,7 +2753,7 @@ var no_any_in_props_default = createRule({
|
|
|
2873
2753
|
});
|
|
2874
2754
|
|
|
2875
2755
|
// src/rules/zustand-use-selectors.ts
|
|
2876
|
-
var
|
|
2756
|
+
var meta9 = defineRuleMeta({
|
|
2877
2757
|
id: "zustand-use-selectors",
|
|
2878
2758
|
version: "1.0.0",
|
|
2879
2759
|
name: "Zustand Use Selectors",
|
|
@@ -3102,7 +2982,7 @@ var zustand_use_selectors_default = createRule({
|
|
|
3102
2982
|
});
|
|
3103
2983
|
|
|
3104
2984
|
// src/rules/no-prop-drilling-depth.ts
|
|
3105
|
-
var
|
|
2985
|
+
var meta10 = defineRuleMeta({
|
|
3106
2986
|
id: "no-prop-drilling-depth",
|
|
3107
2987
|
version: "1.0.0",
|
|
3108
2988
|
name: "No Prop Drilling Depth",
|
|
@@ -3458,7 +3338,7 @@ var no_prop_drilling_depth_default = createRule({
|
|
|
3458
3338
|
});
|
|
3459
3339
|
|
|
3460
3340
|
// src/rules/no-secrets-in-code.ts
|
|
3461
|
-
var
|
|
3341
|
+
var meta11 = defineRuleMeta({
|
|
3462
3342
|
id: "no-secrets-in-code",
|
|
3463
3343
|
version: "1.0.0",
|
|
3464
3344
|
name: "No Secrets in Code",
|
|
@@ -3813,7 +3693,7 @@ var no_secrets_in_code_default = createRule({
|
|
|
3813
3693
|
});
|
|
3814
3694
|
|
|
3815
3695
|
// src/rules/require-input-validation.ts
|
|
3816
|
-
var
|
|
3696
|
+
var meta12 = defineRuleMeta({
|
|
3817
3697
|
id: "require-input-validation",
|
|
3818
3698
|
version: "1.0.0",
|
|
3819
3699
|
name: "Require Input Validation",
|
|
@@ -4155,7 +4035,7 @@ function log(message) {
|
|
|
4155
4035
|
} catch {
|
|
4156
4036
|
}
|
|
4157
4037
|
}
|
|
4158
|
-
var
|
|
4038
|
+
var meta13 = defineRuleMeta({
|
|
4159
4039
|
id: "no-semantic-duplicates",
|
|
4160
4040
|
version: "1.0.0",
|
|
4161
4041
|
name: "No Semantic Duplicates",
|
|
@@ -4316,8 +4196,8 @@ function loadIndex(projectRoot, indexPath) {
|
|
|
4316
4196
|
log(`Loaded metadata.json: ${Object.keys(entries).length} entries`);
|
|
4317
4197
|
const metadataStore = /* @__PURE__ */ new Map();
|
|
4318
4198
|
const fileToChunks = /* @__PURE__ */ new Map();
|
|
4319
|
-
for (const [id,
|
|
4320
|
-
const m =
|
|
4199
|
+
for (const [id, meta17] of Object.entries(entries)) {
|
|
4200
|
+
const m = meta17;
|
|
4321
4201
|
metadataStore.set(id, {
|
|
4322
4202
|
filePath: m.filePath,
|
|
4323
4203
|
startLine: m.startLine,
|
|
@@ -4407,9 +4287,9 @@ function findSimilarChunks(index, chunkId, threshold) {
|
|
|
4407
4287
|
const sortedAll = allScores.sort((a, b) => b.score - a.score).slice(0, 10);
|
|
4408
4288
|
log(` Top 10 similarity scores (threshold=${threshold}):`);
|
|
4409
4289
|
for (const { id, score } of sortedAll) {
|
|
4410
|
-
const
|
|
4290
|
+
const meta17 = index.metadataStore.get(id);
|
|
4411
4291
|
const meetsThreshold = score >= threshold ? "\u2713" : "\u2717";
|
|
4412
|
-
log(` ${meetsThreshold} ${(score * 100).toFixed(1)}% - ${id} (${
|
|
4292
|
+
log(` ${meetsThreshold} ${(score * 100).toFixed(1)}% - ${id} (${meta17?.name || "anonymous"} in ${meta17?.filePath})`);
|
|
4413
4293
|
}
|
|
4414
4294
|
log(` Found ${results.length} chunks above threshold`);
|
|
4415
4295
|
return results.sort((a, b) => b.score - a.score);
|
|
@@ -4498,20 +4378,20 @@ var no_semantic_duplicates_default = createRule({
|
|
|
4498
4378
|
log(` Chunk ${chunkId} already reported, skipping`);
|
|
4499
4379
|
continue;
|
|
4500
4380
|
}
|
|
4501
|
-
const
|
|
4502
|
-
if (!
|
|
4381
|
+
const meta17 = index.metadataStore.get(chunkId);
|
|
4382
|
+
if (!meta17) {
|
|
4503
4383
|
log(` No metadata for chunk ${chunkId}`);
|
|
4504
4384
|
continue;
|
|
4505
4385
|
}
|
|
4506
|
-
log(` Checking chunk ${chunkId}: lines ${
|
|
4507
|
-
if (nodeLine >=
|
|
4386
|
+
log(` Checking chunk ${chunkId}: lines ${meta17.startLine}-${meta17.endLine} (node at line ${nodeLine})`);
|
|
4387
|
+
if (nodeLine >= meta17.startLine && nodeLine <= meta17.endLine) {
|
|
4508
4388
|
log(` Node is within chunk range, searching for similar chunks...`);
|
|
4509
4389
|
const similar = findSimilarChunks(index, chunkId, threshold);
|
|
4510
4390
|
if (similar.length > 0) {
|
|
4511
4391
|
const best = similar[0];
|
|
4512
4392
|
const bestMeta = index.metadataStore.get(best.id);
|
|
4513
4393
|
if (bestMeta) {
|
|
4514
|
-
const chunkLines =
|
|
4394
|
+
const chunkLines = meta17.endLine - meta17.startLine + 1;
|
|
4515
4395
|
if (chunkLines < minLines) {
|
|
4516
4396
|
log(` Skipping: chunk has ${chunkLines} lines, below minLines=${minLines}`);
|
|
4517
4397
|
continue;
|
|
@@ -4519,17 +4399,17 @@ var no_semantic_duplicates_default = createRule({
|
|
|
4519
4399
|
reportedChunks.add(chunkId);
|
|
4520
4400
|
const relPath = relative3(projectRoot, bestMeta.filePath);
|
|
4521
4401
|
const similarity = Math.round(best.score * 100);
|
|
4522
|
-
log(` REPORTING: ${
|
|
4402
|
+
log(` REPORTING: ${meta17.kind} '${name || meta17.name}' is ${similarity}% similar to '${bestMeta.name}' at ${relPath}:${bestMeta.startLine}`);
|
|
4523
4403
|
context.report({
|
|
4524
4404
|
node,
|
|
4525
4405
|
loc: {
|
|
4526
|
-
start: { line:
|
|
4527
|
-
end: { line:
|
|
4406
|
+
start: { line: meta17.startLine, column: meta17.startColumn },
|
|
4407
|
+
end: { line: meta17.endLine, column: meta17.endColumn }
|
|
4528
4408
|
},
|
|
4529
4409
|
messageId: "semanticDuplicate",
|
|
4530
4410
|
data: {
|
|
4531
|
-
kind:
|
|
4532
|
-
name: name ||
|
|
4411
|
+
kind: meta17.kind,
|
|
4412
|
+
name: name || meta17.name || "(anonymous)",
|
|
4533
4413
|
similarity: String(similarity),
|
|
4534
4414
|
otherName: bestMeta.name || "(anonymous)",
|
|
4535
4415
|
otherLocation: `${relPath}:${bestMeta.startLine}`
|
|
@@ -4540,7 +4420,7 @@ var no_semantic_duplicates_default = createRule({
|
|
|
4540
4420
|
log(` No similar chunks found above threshold`);
|
|
4541
4421
|
}
|
|
4542
4422
|
} else {
|
|
4543
|
-
log(` Node line ${nodeLine} not in chunk range ${
|
|
4423
|
+
log(` Node line ${nodeLine} not in chunk range ${meta17.startLine}-${meta17.endLine}`);
|
|
4544
4424
|
}
|
|
4545
4425
|
}
|
|
4546
4426
|
}
|
|
@@ -5786,7 +5666,7 @@ function simpleGlobMatch(pattern, path) {
|
|
|
5786
5666
|
const regex = new RegExp(`^${regexStr}$`);
|
|
5787
5667
|
return regex.test(normalizedPath);
|
|
5788
5668
|
}
|
|
5789
|
-
var
|
|
5669
|
+
var meta14 = defineRuleMeta({
|
|
5790
5670
|
id: "require-test-coverage",
|
|
5791
5671
|
version: "1.0.0",
|
|
5792
5672
|
name: "Require Test Coverage",
|
|
@@ -6499,7 +6379,7 @@ function checkForJSX(ast, visited = /* @__PURE__ */ new WeakSet()) {
|
|
|
6499
6379
|
}
|
|
6500
6380
|
|
|
6501
6381
|
// src/rules/prefer-tailwind.ts
|
|
6502
|
-
var
|
|
6382
|
+
var meta15 = defineRuleMeta({
|
|
6503
6383
|
id: "prefer-tailwind",
|
|
6504
6384
|
version: "1.0.0",
|
|
6505
6385
|
name: "Prefer Tailwind",
|
|
@@ -6926,21 +6806,20 @@ var ruleRegistry = [
|
|
|
6926
6806
|
meta4,
|
|
6927
6807
|
meta5,
|
|
6928
6808
|
meta6,
|
|
6929
|
-
meta7,
|
|
6930
6809
|
// New UI rules
|
|
6810
|
+
meta7,
|
|
6931
6811
|
meta8,
|
|
6932
6812
|
meta9,
|
|
6933
6813
|
meta10,
|
|
6934
|
-
meta11,
|
|
6935
6814
|
// New security rules
|
|
6815
|
+
meta11,
|
|
6936
6816
|
meta12,
|
|
6937
|
-
meta13,
|
|
6938
6817
|
// Semantic duplicate detection
|
|
6939
|
-
|
|
6818
|
+
meta13,
|
|
6940
6819
|
// Test coverage enforcement
|
|
6941
|
-
|
|
6820
|
+
meta14,
|
|
6942
6821
|
// Style preferences
|
|
6943
|
-
|
|
6822
|
+
meta15
|
|
6944
6823
|
];
|
|
6945
6824
|
function getRuleMetadata(id) {
|
|
6946
6825
|
return ruleRegistry.find((rule) => rule.id === id);
|
|
@@ -6959,7 +6838,6 @@ function getAllRuleIds() {
|
|
|
6959
6838
|
// src/index.ts
|
|
6960
6839
|
import { ResolverFactory as ResolverFactory3 } from "oxc-resolver";
|
|
6961
6840
|
var rules = {
|
|
6962
|
-
"no-arbitrary-tailwind": no_arbitrary_tailwind_default,
|
|
6963
6841
|
"consistent-dark-mode": consistent_dark_mode_default,
|
|
6964
6842
|
"no-direct-store-import": no_direct_store_import_default,
|
|
6965
6843
|
"prefer-zustand-state-management": prefer_zustand_state_management_default,
|
|
@@ -6977,12 +6855,12 @@ var rules = {
|
|
|
6977
6855
|
"prefer-tailwind": prefer_tailwind_default
|
|
6978
6856
|
};
|
|
6979
6857
|
var version = "0.1.0";
|
|
6980
|
-
var
|
|
6858
|
+
var meta16 = {
|
|
6981
6859
|
name: "uilint",
|
|
6982
6860
|
version
|
|
6983
6861
|
};
|
|
6984
6862
|
var plugin = {
|
|
6985
|
-
meta:
|
|
6863
|
+
meta: meta16,
|
|
6986
6864
|
rules
|
|
6987
6865
|
};
|
|
6988
6866
|
var jsxLanguageOptions = {
|
|
@@ -7000,7 +6878,6 @@ var recommendedConfig = {
|
|
|
7000
6878
|
},
|
|
7001
6879
|
languageOptions: jsxLanguageOptions,
|
|
7002
6880
|
rules: {
|
|
7003
|
-
"uilint/no-arbitrary-tailwind": "error",
|
|
7004
6881
|
"uilint/consistent-dark-mode": ["error", ...[
|
|
7005
6882
|
{
|
|
7006
6883
|
"warnOnMissingDarkMode": true
|
|
@@ -7129,7 +7006,6 @@ var strictConfig = {
|
|
|
7129
7006
|
},
|
|
7130
7007
|
languageOptions: jsxLanguageOptions,
|
|
7131
7008
|
rules: {
|
|
7132
|
-
"uilint/no-arbitrary-tailwind": "error",
|
|
7133
7009
|
"uilint/consistent-dark-mode": ["error", ...[
|
|
7134
7010
|
{
|
|
7135
7011
|
"warnOnMissingDarkMode": true
|
|
@@ -7274,7 +7150,7 @@ var configs = {
|
|
|
7274
7150
|
strict: strictConfig
|
|
7275
7151
|
};
|
|
7276
7152
|
var uilintEslint = {
|
|
7277
|
-
meta:
|
|
7153
|
+
meta: meta16,
|
|
7278
7154
|
plugin,
|
|
7279
7155
|
rules,
|
|
7280
7156
|
configs
|
|
@@ -7312,7 +7188,7 @@ export {
|
|
|
7312
7188
|
isEventHandlerAttribute,
|
|
7313
7189
|
loadCache,
|
|
7314
7190
|
loadStyleguide,
|
|
7315
|
-
|
|
7191
|
+
meta16 as meta,
|
|
7316
7192
|
plugin,
|
|
7317
7193
|
ruleRegistry,
|
|
7318
7194
|
rules,
|