eslint-plugin-conventions 4.0.7 → 4.1.0

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.
Files changed (47) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/LICENSE +23 -0
  3. package/README.md +51 -21
  4. package/package.json +20 -3
  5. package/src/index.d.ts +49 -0
  6. package/src/index.js +15 -1
  7. package/src/index.js.map +1 -1
  8. package/src/lib/eslint-plugin-conventions.js.map +1 -1
  9. package/src/oxlint.d.ts +20 -0
  10. package/src/oxlint.js +22 -0
  11. package/src/oxlint.js.map +1 -0
  12. package/src/rules/conventions/analytics-event-naming.d.ts +41 -0
  13. package/src/rules/conventions/analytics-event-naming.js +104 -0
  14. package/src/rules/conventions/analytics-event-naming.js.map +1 -0
  15. package/src/rules/conventions/consistent-existence-index-check.js +5 -1
  16. package/src/rules/conventions/consistent-existence-index-check.js.map +1 -1
  17. package/src/rules/conventions/expiring-todo-comments.js +18 -2
  18. package/src/rules/conventions/expiring-todo-comments.js.map +1 -1
  19. package/src/rules/conventions/filename-case.js +9 -1
  20. package/src/rules/conventions/filename-case.js.map +1 -1
  21. package/src/rules/conventions/no-commented-code.js +3 -2
  22. package/src/rules/conventions/no-commented-code.js.map +1 -1
  23. package/src/rules/conventions/no-console-spaces.js +5 -0
  24. package/src/rules/conventions/no-console-spaces.js.map +1 -1
  25. package/src/rules/conventions/no-json-schema-tags.js +2 -1
  26. package/src/rules/conventions/no-json-schema-tags.js.map +1 -1
  27. package/src/rules/conventions/no-magic-numbers.d.ts +41 -0
  28. package/src/rules/conventions/no-magic-numbers.js +205 -0
  29. package/src/rules/conventions/no-magic-numbers.js.map +1 -0
  30. package/src/rules/conventions/no-raw-cross-property-href.d.ts +24 -0
  31. package/src/rules/conventions/no-raw-cross-property-href.js +86 -0
  32. package/src/rules/conventions/no-raw-cross-property-href.js.map +1 -0
  33. package/src/rules/conventions/prefer-code-point.js +4 -1
  34. package/src/rules/conventions/prefer-code-point.js.map +1 -1
  35. package/src/rules/conventions/prefer-dependency-version-strategy.d.ts +5 -5
  36. package/src/rules/conventions/prefer-dependency-version-strategy.js +1 -0
  37. package/src/rules/conventions/prefer-dependency-version-strategy.js.map +1 -1
  38. package/src/rules/conventions/prefer-dom-node-text-content.js +3 -0
  39. package/src/rules/conventions/prefer-dom-node-text-content.js.map +1 -1
  40. package/src/rules/conventions/require-data-testid.d.ts +56 -0
  41. package/src/rules/conventions/require-data-testid.js +209 -0
  42. package/src/rules/conventions/require-data-testid.js.map +1 -0
  43. package/src/rules/conventions/utm-taxonomy.d.ts +25 -0
  44. package/src/rules/conventions/utm-taxonomy.js +113 -0
  45. package/src/rules/conventions/utm-taxonomy.js.map +1 -0
  46. package/src/rules/deprecation/no-deprecated-api.js +4 -0
  47. package/src/rules/deprecation/no-deprecated-api.js.map +1 -1
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2025 Ofri Peretz
4
+ * Licensed under the MIT License. Use of this source code is governed by the
5
+ * MIT license that can be found in the LICENSE file.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.noMagicNumbers = void 0;
9
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
11
+ /** Numbers that are universally idiomatic in JS/TS and need no naming. */
12
+ const DEFAULT_IGNORE = new Set([-1, 0, 1, 2]);
13
+ /** Build a SCREAMING_SNAKE_CASE const name from a numeric value. */
14
+ function constNameFor(value) {
15
+ // e.g. 5000 → MAGIC_5000 · -3 → MAGIC_NEG_3 · 1.5 → MAGIC_1_5
16
+ const prefix = value < 0 ? 'MAGIC_NEG_' : 'MAGIC_';
17
+ const digits = String(Math.abs(value)).replace('.', '_');
18
+ return `${prefix}${digits}`;
19
+ }
20
+ /**
21
+ * Walk up the AST to find the nearest statement ancestor that can be used
22
+ * as the insertion point for a const declaration.
23
+ */
24
+ function nearestStatement(node) {
25
+ const STATEMENT_TYPES = new Set([
26
+ 'ExpressionStatement', 'VariableDeclaration', 'ReturnStatement',
27
+ 'IfStatement', 'WhileStatement', 'ForStatement', 'ForInStatement',
28
+ 'ForOfStatement', 'ThrowStatement', 'SwitchStatement',
29
+ ]);
30
+ let current = node.parent;
31
+ while (current) {
32
+ if (STATEMENT_TYPES.has(current.type))
33
+ return current;
34
+ current = current.parent;
35
+ }
36
+ return null;
37
+ }
38
+ exports.noMagicNumbers = (0, eslint_devkit_1.createRule)({
39
+ name: 'no-magic-numbers',
40
+ meta: {
41
+ type: 'suggestion',
42
+ docs: {
43
+ url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/no-magic-numbers.md',
44
+ description: 'Disallow magic numbers (numeric literals without a named constant)',
45
+ },
46
+ hasSuggestions: true,
47
+ messages: {
48
+ noMagicNumber: (0, eslint_devkit_2.formatLLMMessage)({
49
+ icon: eslint_devkit_2.MessageIcons.INFO,
50
+ issueName: 'Magic Number',
51
+ description: 'The number {{value}} is a magic literal. Extract it to a named constant to make the intent clear.',
52
+ severity: 'LOW',
53
+ fix: 'const TIMEOUT_MS = {{value}}; // use the named constant everywhere',
54
+ documentationLink: 'https://refactoring.guru/replace-magic-literal',
55
+ }),
56
+ extractConst: 'Extract {{value}} to a named constant ({{constName}})',
57
+ },
58
+ schema: [
59
+ {
60
+ type: 'object',
61
+ properties: {
62
+ ignore: {
63
+ type: 'array',
64
+ items: { type: 'number' },
65
+ description: 'Additional numbers to allow',
66
+ },
67
+ ignoreArrayIndexes: { type: 'boolean', default: true },
68
+ ignoreDefaultValues: { type: 'boolean', default: true },
69
+ ignoreEnums: { type: 'boolean', default: true },
70
+ ignoreBitwiseExpressions: { type: 'boolean', default: false },
71
+ },
72
+ additionalProperties: false,
73
+ },
74
+ ],
75
+ },
76
+ defaultOptions: [
77
+ {
78
+ ignore: [],
79
+ ignoreArrayIndexes: true,
80
+ ignoreDefaultValues: true,
81
+ ignoreEnums: true,
82
+ ignoreBitwiseExpressions: false,
83
+ },
84
+ ],
85
+ create(context) {
86
+ const [options = {}] = context.options;
87
+ const { ignore = [], ignoreArrayIndexes = true, ignoreDefaultValues = true, ignoreEnums = true, ignoreBitwiseExpressions = false, } = options;
88
+ const ignoredValues = new Set([...DEFAULT_IGNORE, ...ignore]);
89
+ function isIgnoredNumber(value) {
90
+ return ignoredValues.has(value);
91
+ }
92
+ function isArrayIndex(node) {
93
+ if (!ignoreArrayIndexes)
94
+ return false;
95
+ const parent = node.parent;
96
+ return (parent?.type === 'MemberExpression' &&
97
+ parent.computed &&
98
+ parent.property === node);
99
+ }
100
+ function isDefaultValue(node) {
101
+ if (!ignoreDefaultValues)
102
+ return false;
103
+ const parent = node.parent;
104
+ return (parent?.type === 'AssignmentPattern' &&
105
+ parent.right === node);
106
+ }
107
+ function isEnumMember(node) {
108
+ if (!ignoreEnums)
109
+ return false;
110
+ const parent = node.parent;
111
+ return parent?.type === 'TSEnumMember';
112
+ }
113
+ function isBitwiseContext(node) {
114
+ if (!ignoreBitwiseExpressions)
115
+ return false;
116
+ const parent = node.parent;
117
+ const BITWISE_OPS = new Set(['&', '|', '^', '<<', '>>', '>>>']);
118
+ return (parent?.type === 'BinaryExpression' &&
119
+ BITWISE_OPS.has(parent.operator));
120
+ }
121
+ function isVariableDeclarator(node) {
122
+ // const FOO = 42 — the literal is the named constant itself
123
+ const parent = node.parent;
124
+ return parent?.type === 'VariableDeclarator';
125
+ }
126
+ function isExportedConst(node) {
127
+ // export const FOO = 42
128
+ let current = node;
129
+ while (current) {
130
+ if (current.type === 'ExportNamedDeclaration')
131
+ return true;
132
+ if (current.type === 'VariableDeclaration' ||
133
+ current.type === 'VariableDeclarator') {
134
+ current = current.parent;
135
+ continue;
136
+ }
137
+ break;
138
+ }
139
+ return false;
140
+ }
141
+ function isPropertyKey(node) {
142
+ // { 42: 'value' } — numeric key in object literal
143
+ const parent = node.parent;
144
+ return (parent?.type === 'Property' &&
145
+ parent.key === node);
146
+ }
147
+ return {
148
+ Literal(node) {
149
+ if (typeof node.value !== 'number')
150
+ return;
151
+ const value = node.value;
152
+ // Skip universally ignored values
153
+ if (isIgnoredNumber(value))
154
+ return;
155
+ // Skip NaN / Infinity (not numeric literals per se)
156
+ if (!isFinite(value))
157
+ return;
158
+ // Context-based skips
159
+ if (isVariableDeclarator(node))
160
+ return; // const X = 42
161
+ if (isExportedConst(node))
162
+ return;
163
+ if (isArrayIndex(node))
164
+ return;
165
+ if (isDefaultValue(node))
166
+ return;
167
+ if (isEnumMember(node))
168
+ return;
169
+ if (isBitwiseContext(node))
170
+ return;
171
+ if (isPropertyKey(node))
172
+ return;
173
+ const constName = constNameFor(value);
174
+ const sourceCode = context.sourceCode;
175
+ context.report({
176
+ node,
177
+ messageId: 'noMagicNumber',
178
+ data: { value: String(value) },
179
+ suggest: [
180
+ {
181
+ messageId: 'extractConst',
182
+ data: { value: String(value), constName },
183
+ fix(fixer) {
184
+ const stmt = nearestStatement(node);
185
+ if (!stmt)
186
+ return null;
187
+ // Determine indentation from the statement's first token.
188
+ const firstToken = sourceCode.getFirstToken(stmt);
189
+ if (!firstToken)
190
+ return null;
191
+ const col = firstToken.loc.start.column;
192
+ const indent = ' '.repeat(col);
193
+ return [
194
+ fixer.insertTextBefore(stmt, `const ${constName} = ${value};\n${indent}`),
195
+ fixer.replaceText(node, constName),
196
+ ];
197
+ },
198
+ },
199
+ ],
200
+ });
201
+ },
202
+ };
203
+ },
204
+ });
205
+ //# sourceMappingURL=no-magic-numbers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-magic-numbers.js","sourceRoot":"","sources":["../../../../src/rules/conventions/no-magic-numbers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Copyright (c) 2025 Ofri Peretz
3
+ * Licensed under the MIT License. Use of this source code is governed by the
4
+ * MIT license that can be found in the LICENSE file.
5
+ */
6
+ /**
7
+ * ESLint Rule: no-raw-cross-property-href
8
+ *
9
+ * Flags hand-written `<a href="https://*.interlace.tools/…">` and
10
+ * `<a href="https://ofriperetz.dev/…">` JSX literals. UTM_PHILOSOPHY.md
11
+ * principle 9: the only blessed way to construct a cross-property URL is the
12
+ * `buildUtmHref()` helper, which stamps the source/medium/campaign/content
13
+ * and (for cross-eTLD+1 outbound) appends `ph_distinct_id` for identity
14
+ * stitching.
15
+ *
16
+ * The rule fires on JSX `href` attributes whose value is a string Literal
17
+ * (not an expression). Wrapping the URL in `buildUtmHref(...)` produces a
18
+ * JSXExpressionContainer instead of a Literal, which is the intended escape
19
+ * hatch — no separate detection needed.
20
+ */
21
+ import type { TSESLint } from '@interlace/eslint-devkit';
22
+ export declare const noRawCrossPropertyHref: TSESLint.RuleModule<"rawCrossPropertyHref", [], unknown, TSESLint.RuleListener> & {
23
+ name: string;
24
+ };
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2025 Ofri Peretz
4
+ * Licensed under the MIT License. Use of this source code is governed by the
5
+ * MIT license that can be found in the LICENSE file.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.noRawCrossPropertyHref = void 0;
9
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
11
+ // Fixed list of cross-property hosts. Mirrors UTM_PHILOSOPHY.md's
12
+ // cross-property travel matrix and ANALYTICS_PHILOSOPHY.md principle 1's
13
+ // list of measured surfaces. Edit there and here together.
14
+ const CROSS_PROPERTY_HOSTS = new Set([
15
+ 'ofriperetz.dev',
16
+ 'interlace.tools',
17
+ 'eslint.interlace.tools',
18
+ 'serverless.interlace.tools',
19
+ 'ds.interlace.tools',
20
+ 'storybook.interlace.tools',
21
+ ]);
22
+ exports.noRawCrossPropertyHref = (0, eslint_devkit_1.createRule)({
23
+ name: 'no-raw-cross-property-href',
24
+ meta: {
25
+ type: 'problem',
26
+ docs: {
27
+ url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/no-raw-cross-property-href.md',
28
+ description: 'Forbid hand-written cross-property hrefs; use buildUtmHref() from lib/utm.ts',
29
+ },
30
+ fixable: undefined,
31
+ hasSuggestions: false,
32
+ messages: {
33
+ rawCrossPropertyHref: (0, eslint_devkit_2.formatLLMMessage)({
34
+ icon: eslint_devkit_2.MessageIcons.WARNING,
35
+ issueName: 'Raw cross-property href',
36
+ description: 'href "{{href}}" points to a cross-property surface ({{host}}). Use buildUtmHref() from lib/utm.ts so the link carries UTM and ph_distinct_id.',
37
+ severity: 'HIGH',
38
+ fix: 'Replace with buildUtmHref(\'{{href}}\', { source, medium, campaign, content }).',
39
+ documentationLink: 'https://github.com/ofri-peretz/eslint/blob/main/UTM_PHILOSOPHY.md',
40
+ }),
41
+ },
42
+ schema: [],
43
+ },
44
+ defaultOptions: [],
45
+ create(context) {
46
+ function parseHost(value) {
47
+ // Only absolute URLs with a hostname.
48
+ if (!/^https?:\/\//i.test(value))
49
+ return null;
50
+ try {
51
+ return new URL(value).hostname.toLowerCase();
52
+ }
53
+ catch {
54
+ return null;
55
+ }
56
+ }
57
+ function isCrossPropertyHref(href) {
58
+ const host = parseHost(href);
59
+ if (!host)
60
+ return null;
61
+ if (!CROSS_PROPERTY_HOSTS.has(host))
62
+ return null;
63
+ return { host };
64
+ }
65
+ return {
66
+ JSXAttribute(node) {
67
+ if (node.name.type !== 'JSXIdentifier' ||
68
+ node.name.name !== 'href' ||
69
+ !node.value ||
70
+ node.value.type !== 'Literal' ||
71
+ typeof node.value.value !== 'string') {
72
+ return;
73
+ }
74
+ const result = isCrossPropertyHref(node.value.value);
75
+ if (!result)
76
+ return;
77
+ context.report({
78
+ node: node.value,
79
+ messageId: 'rawCrossPropertyHref',
80
+ data: { href: node.value.value, host: result.host },
81
+ });
82
+ },
83
+ };
84
+ },
85
+ });
86
+ //# sourceMappingURL=no-raw-cross-property-href.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-raw-cross-property-href.js","sourceRoot":"","sources":["../../../../src/rules/conventions/no-raw-cross-property-href.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAkBH,4DAAsD;AACtD,4DAA0E;AAK1E,kEAAkE;AAClE,yEAAyE;AACzE,2DAA2D;AAC3D,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,gBAAgB;IAChB,iBAAiB;IACjB,wBAAwB;IACxB,4BAA4B;IAC5B,oBAAoB;IACpB,2BAA2B;CAC5B,CAAC,CAAC;AAEU,QAAA,sBAAsB,GAAG,IAAA,0BAAU,EAA0B;IACxE,IAAI,EAAE,4BAA4B;IAClC,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,GAAG,EAAE,6HAA6H;YAClI,WAAW,EACT,8EAA8E;SACjF;QACD,OAAO,EAAE,SAAS;QAClB,cAAc,EAAE,KAAK;QACrB,QAAQ,EAAE;YACR,oBAAoB,EAAE,IAAA,gCAAgB,EAAC;gBACrC,IAAI,EAAE,4BAAY,CAAC,OAAO;gBAC1B,SAAS,EAAE,yBAAyB;gBACpC,WAAW,EACT,+IAA+I;gBACjJ,QAAQ,EAAE,MAAM;gBAChB,GAAG,EAAE,iFAAiF;gBACtF,iBAAiB,EACf,mEAAmE;aACtE,CAAC;SACH;QACD,MAAM,EAAE,EAAE;KACX;IACD,cAAc,EAAE,EAAE;IAElB,MAAM,CAAC,OAAsD;QAC3D,SAAS,SAAS,CAAC,KAAa;YAC9B,sCAAsC;YACtC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC9C,IAAI,CAAC;gBACH,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;YAC/C,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,SAAS,mBAAmB,CAAC,IAAY;YAGvC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,CAAC,IAAI;gBAAE,OAAO,IAAI,CAAC;YACvB,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;YACjD,OAAO,EAAE,IAAI,EAAE,CAAC;QAClB,CAAC;QAED,OAAO;YACL,YAAY,CAAC,IAA2B;gBACtC,IACE,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe;oBAClC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM;oBACzB,CAAC,IAAI,CAAC,KAAK;oBACX,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;oBAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,EACpC,CAAC;oBACD,OAAO;gBACT,CAAC;gBACD,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACrD,IAAI,CAAC,MAAM;oBAAE,OAAO;gBACpB,OAAO,CAAC,MAAM,CAAC;oBACb,IAAI,EAAE,IAAI,CAAC,KAAK;oBAChB,SAAS,EAAE,sBAAsB;oBACjC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE;iBACpD,CAAC,CAAC;YACL,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -13,6 +13,7 @@ exports.preferCodePoint = (0, eslint_devkit_1.createRule)({
13
13
  meta: {
14
14
  type: 'suggestion',
15
15
  docs: {
16
+ url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/prefer-code-point.md',
16
17
  description: 'Prefer codePointAt over charCodeAt for proper Unicode character handling',
17
18
  },
18
19
  messages: {
@@ -35,12 +36,13 @@ exports.preferCodePoint = (0, eslint_devkit_1.createRule)({
35
36
  },
36
37
  defaultOptions: [],
37
38
  create(context) {
38
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
39
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, consistent-function-scoping
39
40
  function isInAllowedContext(node) {
40
41
  // For simplicity, we'll skip the allow option for now
41
42
  // This would require more complex logic to check comments/code context
42
43
  return false;
43
44
  }
45
+ // oxlint-disable-next-line consistent-function-scoping
44
46
  function shouldIgnoreCall(node) {
45
47
  // The unicorn rule flags ALL charCodeAt calls, but allows some contexts
46
48
  if (node.callee.type === 'MemberExpression') {
@@ -57,6 +59,7 @@ exports.preferCodePoint = (0, eslint_devkit_1.createRule)({
57
59
  }
58
60
  return false;
59
61
  }
62
+ // oxlint-disable-next-line consistent-function-scoping
60
63
  function isCharCodeAtCall(node) {
61
64
  // Check if this is a call to charCodeAt method
62
65
  if (node.callee.type === 'MemberExpression') {
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-code-point.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-conventions/src/rules/conventions/prefer-code-point.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAOH,4DAAsD;AACtD,4DAA0E;AAM7D,QAAA,eAAe,GAAG,IAAA,0BAAU,EAA0B;IACjE,IAAI,EAAE,mBAAmB;IACzB,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EACT,0EAA0E;SAC7E;QACD,QAAQ,EAAE;YACR,eAAe,EAAE,IAAA,gCAAgB,EAAC;gBAChC,IAAI,EAAE,4BAAY,CAAC,OAAO;gBAC1B,SAAS,EAAE,oBAAoB;gBAC/B,WAAW,EAAE,0DAA0D;gBACvE,QAAQ,EAAE,QAAQ;gBAClB,GAAG,EAAE,yCAAyC;gBAC9C,iBAAiB,EACf,iGAAiG;aACpG,CAAC;SACH;QACD,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,EAAE;gBACd,oBAAoB,EAAE,KAAK;aAC5B;SACF;KACF;IACD,cAAc,EAAE,EAAE;IAElB,MAAM,CAAC,OAAsD;QAC3D,6DAA6D;QAC7D,SAAS,kBAAkB,CAAC,IAA6B;YACvD,sDAAsD;YACtD,uEAAuE;YACvE,OAAO,KAAK,CAAC;QACf,CAAC;QAED,SAAS,gBAAgB,CAAC,IAA6B;YACrD,wEAAwE;YAExE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBAC5C,0BAA0B;gBAC1B,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACzB,OAAO,IAAI,CAAC;gBACd,CAAC;gBAED,gFAAgF;gBAChF,4EAA4E;gBAC5E,IACE,IAAI,CAAC,MAAM,CAAC,QAAQ;oBACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,EAC1C,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;QAED,SAAS,gBAAgB,CAAC,IAA6B;YACrD,+CAA+C;YAC/C,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBAC5C,yCAAyC;gBACzC,IACE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;oBAC1C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,EAC1C,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;gBAED,8CAA8C;gBAC9C,IACE,IAAI,CAAC,MAAM,CAAC,QAAQ;oBACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS;oBACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,KAAK,YAAY,EAC3C,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO;YACL,cAAc,CAAC,IAA6B;gBAC1C,IACE,gBAAgB,CAAC,IAAI,CAAC;oBACtB,CAAC,kBAAkB,CAAC,IAAI,CAAC;oBACzB,CAAC,gBAAgB,CAAC,IAAI,CAAC,EACvB,CAAC;oBACD,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI;wBACJ,SAAS,EAAE,iBAAiB;wBAC5B,IAAI,EAAE;4BACJ,OAAO,EAAE,cAAc;4BACvB,GAAG,EAAE,eAAe;yBACrB;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
1
+ {"version":3,"file":"prefer-code-point.js","sourceRoot":"","sources":["../../../../src/rules/conventions/prefer-code-point.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAOH,4DAAsD;AACtD,4DAA0E;AAM7D,QAAA,eAAe,GAAG,IAAA,0BAAU,EAA0B;IACjE,IAAI,EAAE,mBAAmB;IACzB,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,GAAG,EAAE,oHAAoH;YACzH,WAAW,EACT,0EAA0E;SAC7E;QACD,QAAQ,EAAE;YACR,eAAe,EAAE,IAAA,gCAAgB,EAAC;gBAChC,IAAI,EAAE,4BAAY,CAAC,OAAO;gBAC1B,SAAS,EAAE,oBAAoB;gBAC/B,WAAW,EAAE,0DAA0D;gBACvE,QAAQ,EAAE,QAAQ;gBAClB,GAAG,EAAE,yCAAyC;gBAC9C,iBAAiB,EACf,iGAAiG;aACpG,CAAC;SACH;QACD,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,EAAE;gBACd,oBAAoB,EAAE,KAAK;aAC5B;SACF;KACF;IACD,cAAc,EAAE,EAAE;IAElB,MAAM,CAAC,OAAsD;QAC3D,0FAA0F;QAC1F,SAAS,kBAAkB,CAAC,IAA6B;YACvD,sDAAsD;YACtD,uEAAuE;YACvE,OAAO,KAAK,CAAC;QACf,CAAC;QAED,uDAAuD;QACvD,SAAS,gBAAgB,CAAC,IAA6B;YACrD,wEAAwE;YAExE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBAC5C,0BAA0B;gBAC1B,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACzB,OAAO,IAAI,CAAC;gBACd,CAAC;gBAED,gFAAgF;gBAChF,4EAA4E;gBAC5E,IACE,IAAI,CAAC,MAAM,CAAC,QAAQ;oBACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,EAC1C,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;QAED,uDAAuD;QACvD,SAAS,gBAAgB,CAAC,IAA6B;YACrD,+CAA+C;YAC/C,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBAC5C,yCAAyC;gBACzC,IACE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;oBAC1C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,EAC1C,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;gBAED,8CAA8C;gBAC9C,IACE,IAAI,CAAC,MAAM,CAAC,QAAQ;oBACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS;oBACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,KAAK,YAAY,EAC3C,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO;YACL,cAAc,CAAC,IAA6B;gBAC1C,IACE,gBAAgB,CAAC,IAAI,CAAC;oBACtB,CAAC,kBAAkB,CAAC,IAAI,CAAC;oBACzB,CAAC,gBAAgB,CAAC,IAAI,CAAC,EACvB,CAAC;oBACD,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI;wBACJ,SAAS,EAAE,iBAAiB;wBAC5B,IAAI,EAAE;4BACJ,OAAO,EAAE,cAAc;4BACvB,GAAG,EAAE,eAAe;yBACrB;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -6,11 +6,11 @@
6
6
  /**
7
7
  * prefer-dependency-version-strategy
8
8
  *
9
- * Enforces a consistent version strategy (caret, tilde, exact, etc.) for package.json dependencies.
10
- * Works alongside @nx/dependency-checks to ensure both version alignment and strategy consistency.
11
- *
12
- * This rule is designed to complement @nx/dependency-checks, which validates that dependencies
13
- * match the lockfile. This rule ensures the version specifier format is consistent.
9
+ * Enforces a consistent version-specifier strategy (caret, tilde, exact, etc.)
10
+ * for package.json dependencies. Pairs with a lockfile-alignment check
11
+ * (e.g. `npm ci`, or this monorepo's `scripts/check-version-alignment.ts`)
12
+ * so both format consistency and lockfile parity are enforced; this rule
13
+ * handles the "format" half at edit/PR time inside ESLint.
14
14
  */
15
15
  import type { TSESLint } from '@interlace/eslint-devkit';
16
16
  type VersionStrategy = 'caret' | 'tilde' | 'exact' | 'range' | 'any';
@@ -13,6 +13,7 @@ exports.preferDependencyVersionStrategy = (0, eslint_devkit_2.createRule)({
13
13
  meta: {
14
14
  type: 'suggestion',
15
15
  docs: {
16
+ url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/prefer-dependency-version-strategy.md',
16
17
  description: 'Enforce consistent version strategy (caret, tilde, exact, etc.) for package.json dependencies',
17
18
  },
18
19
  fixable: 'code',
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-dependency-version-strategy.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-conventions/src/rules/conventions/prefer-dependency-version-strategy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prefer-dependency-version-strategy.js","sourceRoot":"","sources":["../../../../src/rules/conventions/prefer-dependency-version-strategy.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@ exports.preferDomNodeTextContent = (0, eslint_devkit_1.createRule)({
13
13
  meta: {
14
14
  type: 'suggestion',
15
15
  docs: {
16
+ url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/prefer-dom-node-text-content.md',
16
17
  description: 'Prefer textContent over innerText for better performance and reliability',
17
18
  },
18
19
  hasSuggestions: true,
@@ -36,6 +37,7 @@ exports.preferDomNodeTextContent = (0, eslint_devkit_1.createRule)({
36
37
  },
37
38
  defaultOptions: [],
38
39
  create(context) {
40
+ // oxlint-disable-next-line consistent-function-scoping
39
41
  function isInAllowedContext() {
40
42
  // For simplicity, we'll skip the allow option for now
41
43
  return false;
@@ -93,6 +95,7 @@ exports.preferDomNodeTextContent = (0, eslint_devkit_1.createRule)({
93
95
  }
94
96
  return false;
95
97
  }
98
+ // oxlint-disable-next-line consistent-function-scoping
96
99
  function isInnerTextAccess(node) {
97
100
  // Check if this is accessing .innerText property
98
101
  if (node.property.type === 'Identifier' &&
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-dom-node-text-content.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-conventions/src/rules/conventions/prefer-dom-node-text-content.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prefer-dom-node-text-content.js","sourceRoot":"","sources":["../../../../src/rules/conventions/prefer-dom-node-text-content.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAOH,4DAAsD;AACtD,4DAA0E;AAM7D,QAAA,wBAAwB,GAAG,IAAA,0BAAU,EAA0B;IAC1E,IAAI,EAAE,8BAA8B;IACpC,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,GAAG,EAAE,+HAA+H;YACpI,WAAW,EACT,0EAA0E;SAC7E;QACD,cAAc,EAAE,IAAI;QACpB,QAAQ,EAAE;YACR,wBAAwB,EAAE,IAAA,gCAAgB,EAAC;gBACzC,IAAI,EAAE,4BAAY,CAAC,WAAW;gBAC9B,SAAS,EAAE,iBAAiB;gBAC5B,WAAW,EAAE,sCAAsC;gBACnD,QAAQ,EAAE,QAAQ;gBAClB,GAAG,EAAE,oCAAoC;gBACzC,iBAAiB,EACf,4GAA4G;aAC/G,CAAC;SACH;QACD,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,EAAE;gBACd,oBAAoB,EAAE,KAAK;aAC5B;SACF;KACF;IACD,cAAc,EAAE,EAAE;IAElB,MAAM,CAAC,OAAsD;QAC3D,uDAAuD;QACvD,SAAS,kBAAkB;YACzB,sDAAsD;YACtD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,SAAS,kBAAkB,CAAC,IAA+B;YACzD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;YAExB,kEAAkE;YAClE,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;gBACtB,oCAAoC;gBACpC,IAAI,IAAI,CAAC,KAAK,CAAC,4CAA4C,CAAC,EAAE,CAAC;oBAC7D,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,8CAA8C;gBAC9C,IAAI,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,EAAE,CAAC;oBACtC,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YAED,+EAA+E;YAC/E,IACE,GAAG,CAAC,IAAI,KAAK,gBAAgB;gBAC7B,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB,EACtC,CAAC;gBACD,MAAM,UAAU,GAAI,GAAG,CAAC,MAAM,CAAC,QAAgC,EAAE,IAAI,CAAC;gBACtE,IACE,UAAU;oBACV;wBACE,eAAe;wBACf,kBAAkB;wBAClB,gBAAgB;wBAChB,wBAAwB;wBACxB,sBAAsB;wBACtB,eAAe;qBAChB,CAAC,QAAQ,CAAC,UAAU,CAAC,EACtB,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YAED,iDAAiD;YACjD,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBACpC,MAAM,QAAQ,GAAI,GAAG,CAAC,QAAgC,EAAE,IAAI,CAAC;gBAC7D,IACE,QAAQ;oBACR;wBACE,SAAS;wBACT,UAAU;wBACV,YAAY;wBACZ,YAAY;wBACZ,SAAS;qBACV,CAAC,QAAQ,CAAC,QAAQ,CAAC,EACpB,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YAED,mCAAmC;YACnC,IACE,GAAG,CAAC,IAAI,KAAK,kBAAkB;gBAC/B,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,gBAAgB;gBACpC,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;gBAClC,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS,EAC/B,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;QAED,uDAAuD;QACvD,SAAS,iBAAiB,CAAC,IAA+B;YACxD,iDAAiD;YACjD,IACE,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;gBACnC,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,WAAW,EAClC,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,gEAAgE;YAChE,IACE,IAAI,CAAC,QAAQ;gBACb,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS;gBAChC,IAAI,CAAC,QAAQ,CAAC,KAAK,KAAK,WAAW,EACnC,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO;YACL,gBAAgB,CAAC,IAA+B;gBAC9C,IACE,iBAAiB,CAAC,IAAI,CAAC;oBACvB,kBAAkB,CAAC,IAAI,CAAC;oBACxB,CAAC,kBAAkB,EAAE,EACrB,CAAC;oBACD,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI;wBACJ,SAAS,EAAE,0BAA0B;wBACrC,IAAI,EAAE;4BACJ,OAAO,EAAE,WAAW;4BACpB,GAAG,EAAE,aAAa;yBACnB;wBACD,OAAO,EAAE;4BACP;gCACE,SAAS,EAAE,0BAA0B;gCACrC,IAAI,EAAE;oCACJ,WAAW,EAAE,aAAa;oCAC1B,UAAU,EAAE,0BAA0B;iCACvC;gCACD,GAAG,CAAC,KAAyB;oCAC3B,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;wCACxC,OAAO,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;oCACzD,CAAC;yCAAM,IACL,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS;wCAChC,IAAI,CAAC,QAAQ,CAAC,KAAK,KAAK,WAAW,EACnC,CAAC;wCACD,OAAO,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;oCAC3D,CAAC;oCACD,OAAO,IAAI,CAAC;gCACd,CAAC;6BACF;yBACF;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Copyright (c) 2025 Ofri Peretz
3
+ * Licensed under the MIT License. Use of this source code is governed by the
4
+ * MIT license that can be found in the LICENSE file.
5
+ */
6
+ /**
7
+ * ESLint Rule: require-data-testid
8
+ *
9
+ * Enforces a stable `data-testid` attribute on elements that are testing
10
+ * targets. Pairs with `apps/docs/A11Y.md` (Layer 3 of the a11y self-test
11
+ * model): brittle class-name selectors break on every styling refactor;
12
+ * `data-testid` gives every component a stable identity invisible at
13
+ * runtime and untouchable by Tailwind churn.
14
+ *
15
+ * By default flags:
16
+ * - native interactive elements: <button>, <input>, <select>,
17
+ * <textarea>, <a> with onClick or href
18
+ * - custom React components (PascalCase identifier)
19
+ *
20
+ * Options:
21
+ * - `requireOn`: extra element/component names that must have the attribute
22
+ * - `ignore`: names to skip even when default-flagged
23
+ * - `componentPattern`: regex string for "this is a custom component"
24
+ * detection (default: ^[A-Z])
25
+ */
26
+ import type { TSESLint } from '@interlace/eslint-devkit';
27
+ type MessageIds = 'missingDataTestId' | 'dynamicDataTestId';
28
+ export interface Options {
29
+ /** Additional element / component names to require `data-testid` on. */
30
+ requireOn?: string[];
31
+ /** Names to skip (even when otherwise default-flagged). */
32
+ ignore?: string[];
33
+ /**
34
+ * Regex string. If a JSX element name matches, it's treated as a "custom
35
+ * component" and required to carry `data-testid`. Default: `^[A-Z]`.
36
+ */
37
+ componentPattern?: string;
38
+ /**
39
+ * If true, `data-testid` values must be string-literal expressions or
40
+ * template literals containing only string + identifier expressions
41
+ * (so they're stable across renders). Default: true.
42
+ */
43
+ enforceStableValues?: boolean;
44
+ /**
45
+ * If true, only flag custom components (matching `componentPattern`)
46
+ * when they accept an event handler prop (onClick / onChange / etc.).
47
+ * Native interactive elements (`button`, `a`, `input`, …) are always
48
+ * flagged regardless. Default: true.
49
+ */
50
+ componentRequiresHandler?: boolean;
51
+ }
52
+ type RuleOptions = [Options?];
53
+ export declare const requireDataTestId: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener> & {
54
+ name: string;
55
+ };
56
+ export {};