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,209 @@
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.requireDataTestId = void 0;
9
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
+ /**
11
+ * Native HTML elements that always need a stable selector — they're the
12
+ * usual targets in Playwright / Cypress / Testing Library.
13
+ */
14
+ const ALWAYS_INTERACTIVE = new Set([
15
+ 'button',
16
+ 'input',
17
+ 'select',
18
+ 'textarea',
19
+ 'form',
20
+ ]);
21
+ /**
22
+ * `<a>` is interactive only when it has `href` or `onClick`. We don't want
23
+ * to flag in-content anchor jumps (e.g. <a name="...">).
24
+ */
25
+ function isInteractiveAnchor(node) {
26
+ return node.attributes.some((attr) => {
27
+ if (attr.type !== 'JSXAttribute')
28
+ return false;
29
+ const name = attr.name.type === 'JSXIdentifier' ? attr.name.name : undefined;
30
+ return name === 'href' || name === 'onClick';
31
+ });
32
+ }
33
+ function hasEventHandler(node) {
34
+ return node.attributes.some((attr) => {
35
+ if (attr.type !== 'JSXAttribute')
36
+ return false;
37
+ if (attr.name.type !== 'JSXIdentifier')
38
+ return false;
39
+ // React `on*` handler convention: onClick, onChange, onSubmit, etc.
40
+ return /^on[A-Z]/.test(attr.name.name);
41
+ });
42
+ }
43
+ function getJsxName(name) {
44
+ if (name.type === 'JSXIdentifier')
45
+ return name.name;
46
+ if (name.type === 'JSXMemberExpression') {
47
+ // Conservative: use the right-most segment. e.g. `<Card.Header />` → "Header"
48
+ return name.property.type === 'JSXIdentifier'
49
+ ? name.property.name
50
+ : undefined;
51
+ }
52
+ return undefined;
53
+ }
54
+ function hasDataTestId(node) {
55
+ for (const attr of node.attributes) {
56
+ if (attr.type !== 'JSXAttribute')
57
+ continue;
58
+ if (attr.name.type === 'JSXIdentifier' && attr.name.name === 'data-testid')
59
+ return attr;
60
+ }
61
+ return null;
62
+ }
63
+ function hasSpreadingAllProps(node) {
64
+ // If the element receives `{...props}` we trust the parent is supplying
65
+ // data-testid (or else the parent itself is responsible). Avoid double-
66
+ // flagging in pure render-forward components.
67
+ return node.attributes.some((a) => a.type === 'JSXSpreadAttribute');
68
+ }
69
+ function isStableValue(attr) {
70
+ if (!attr.value)
71
+ return false; // <... data-testid /> — boolean shorthand
72
+ if (attr.value.type === 'Literal')
73
+ return typeof attr.value.value === 'string';
74
+ if (attr.value.type === 'JSXExpressionContainer') {
75
+ const expr = attr.value.expression;
76
+ if (expr.type === 'Literal')
77
+ return typeof expr.value === 'string';
78
+ if (expr.type === 'TemplateLiteral') {
79
+ // Template literal is stable if all expressions are member/identifier
80
+ // (no function calls / random values).
81
+ return expr.expressions.every((e) => ['Identifier', 'MemberExpression', 'Literal'].includes(e.type));
82
+ }
83
+ // Identifier reference (likely a constant) — accept.
84
+ if (expr.type === 'Identifier')
85
+ return true;
86
+ return false;
87
+ }
88
+ return false;
89
+ }
90
+ exports.requireDataTestId = (0, eslint_devkit_1.createRule)({
91
+ name: 'require-data-testid',
92
+ meta: {
93
+ type: 'problem',
94
+ docs: {
95
+ url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/require-data-testid.md',
96
+ description: 'Require stable `data-testid` attributes on interactive elements and custom components for testability.',
97
+ },
98
+ fixable: undefined,
99
+ hasSuggestions: false,
100
+ messages: {
101
+ missingDataTestId: (0, eslint_devkit_1.formatLLMMessage)({
102
+ icon: eslint_devkit_1.MessageIcons.WARNING,
103
+ issueName: 'Missing data-testid',
104
+ description: 'Interactive elements and custom components must expose a stable `data-testid` for E2E testability. Class-name selectors break on every Tailwind refactor; `data-testid` survives.',
105
+ severity: 'MEDIUM',
106
+ fix: 'Add `data-testid="<lower-kebab-case-name>"` to the element.',
107
+ documentationLink: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/require-data-testid.md',
108
+ }),
109
+ dynamicDataTestId: (0, eslint_devkit_1.formatLLMMessage)({
110
+ icon: eslint_devkit_1.MessageIcons.WARNING,
111
+ issueName: 'Unstable data-testid value',
112
+ description: '`data-testid` should be a string literal or a template literal of stable identifiers — values that change between renders make tests flaky.',
113
+ severity: 'LOW',
114
+ // oxlint-disable-next-line eslint/no-template-curly-in-string
115
+ fix: 'Use a string literal or template like `pagination-page-${pageNumber}` instead of dynamic / computed values.',
116
+ documentationLink: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/require-data-testid.md',
117
+ }),
118
+ },
119
+ schema: [
120
+ {
121
+ type: 'object',
122
+ additionalProperties: false,
123
+ properties: {
124
+ requireOn: {
125
+ type: 'array',
126
+ items: { type: 'string' },
127
+ description: 'Extra element / component names to flag.',
128
+ },
129
+ ignore: {
130
+ type: 'array',
131
+ items: { type: 'string' },
132
+ description: 'Element / component names to skip.',
133
+ },
134
+ componentPattern: {
135
+ type: 'string',
136
+ description: 'Regex; matched names are treated as custom components. Empty disables component checks.',
137
+ },
138
+ componentRequiresHandler: {
139
+ type: 'boolean',
140
+ description: 'When `componentPattern` matches, only flag if the component has an `on*` event handler (default true). Set false to flag every matching component.',
141
+ },
142
+ enforceStableValues: {
143
+ type: 'boolean',
144
+ description: 'Reject computed `data-testid` values (default: true).',
145
+ },
146
+ },
147
+ },
148
+ ],
149
+ },
150
+ defaultOptions: [
151
+ {
152
+ requireOn: [],
153
+ ignore: [],
154
+ // Default: only flag PascalCase components when they handle events.
155
+ // Pure presentational wrappers (e.g. <Body />, <AnchorProvider>) are
156
+ // not testing targets and would create noise.
157
+ componentPattern: '^[A-Z]',
158
+ componentRequiresHandler: true,
159
+ enforceStableValues: true,
160
+ },
161
+ ],
162
+ create(context, [opts]) {
163
+ const options = opts ?? {};
164
+ const requireOn = new Set(options.requireOn ?? []);
165
+ const ignore = new Set(options.ignore ?? []);
166
+ const componentPatternStr = options.componentPattern ?? '^[A-Z]';
167
+ const componentPattern = componentPatternStr
168
+ ? new RegExp(componentPatternStr)
169
+ : null;
170
+ const componentRequiresHandler = options.componentRequiresHandler ?? true;
171
+ const enforceStableValues = options.enforceStableValues ?? true;
172
+ return {
173
+ JSXOpeningElement(node) {
174
+ const name = getJsxName(node.name);
175
+ if (!name)
176
+ return;
177
+ if (ignore.has(name))
178
+ return;
179
+ // Decide whether this element is in-scope.
180
+ let inScope = false;
181
+ if (ALWAYS_INTERACTIVE.has(name))
182
+ inScope = true;
183
+ else if (name === 'a' && isInteractiveAnchor(node))
184
+ inScope = true;
185
+ else if (componentPattern && componentPattern.test(name)) {
186
+ // PascalCase component. Only flag when it has an interactive
187
+ // event handler, unless `componentRequiresHandler: false` is set.
188
+ inScope = componentRequiresHandler ? hasEventHandler(node) : true;
189
+ }
190
+ else if (requireOn.has(name))
191
+ inScope = true;
192
+ if (!inScope)
193
+ return;
194
+ // Skip if a spread is forwarding all props — the parent owns testid.
195
+ if (hasSpreadingAllProps(node))
196
+ return;
197
+ const existing = hasDataTestId(node);
198
+ if (!existing) {
199
+ context.report({ node, messageId: 'missingDataTestId' });
200
+ return;
201
+ }
202
+ if (enforceStableValues && !isStableValue(existing)) {
203
+ context.report({ node: existing, messageId: 'dynamicDataTestId' });
204
+ }
205
+ },
206
+ };
207
+ },
208
+ });
209
+ //# sourceMappingURL=require-data-testid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-data-testid.js","sourceRoot":"","sources":["../../../../src/rules/conventions/require-data-testid.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
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: utm-taxonomy
8
+ *
9
+ * Validates `utm_source` and `utm_medium` values in URL string literals
10
+ * against the fixed taxonomy codified in UTM_PHILOSOPHY.md. Free-text values
11
+ * (`Blog`, `BLOG`, `blog_v2`) destroy joinability in PostHog — they don't
12
+ * compose into a single cohort, they split into N rows that nothing can
13
+ * re-merge automatically.
14
+ *
15
+ * The rule scans string Literal nodes anywhere in source for `utm_source=`
16
+ * or `utm_medium=` query params and reports any value outside the fixed
17
+ * list. The fixed list lives in this rule and in UTM_PHILOSOPHY.md (taxonomy
18
+ * table) — both must be edited together.
19
+ */
20
+ import type { TSESLint } from '@interlace/eslint-devkit';
21
+ type MessageIds = 'invalidUtmSource' | 'invalidUtmMedium';
22
+ export declare const utmTaxonomy: TSESLint.RuleModule<MessageIds, [], unknown, TSESLint.RuleListener> & {
23
+ name: string;
24
+ };
25
+ export {};
@@ -0,0 +1,113 @@
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.utmTaxonomy = void 0;
9
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
11
+ // UTM_PHILOSOPHY.md → "The taxonomy" table.
12
+ // Edit there and here together (the rule has no other source of truth).
13
+ const VALID_UTM_SOURCES = new Set([
14
+ 'ofriperetz_dev',
15
+ 'interlace',
16
+ 'eslint_docs',
17
+ 'serverless_docs',
18
+ 'ds',
19
+ 'storybook',
20
+ 'dev_to',
21
+ 'github',
22
+ 'npm',
23
+ 'x',
24
+ 'linkedin',
25
+ 'email',
26
+ ]);
27
+ const VALID_UTM_MEDIUMS = new Set([
28
+ 'blog',
29
+ 'docs',
30
+ 'landing',
31
+ 'social',
32
+ 'email',
33
+ 'referral',
34
+ 'cli',
35
+ ]);
36
+ const UTM_PARAM_RE = /[?&](utm_source|utm_medium)=([^&#]+)/g;
37
+ exports.utmTaxonomy = (0, eslint_devkit_1.createRule)({
38
+ name: 'utm-taxonomy',
39
+ meta: {
40
+ type: 'problem',
41
+ docs: {
42
+ url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/utm-taxonomy.md',
43
+ description: 'Validate utm_source and utm_medium values against the fixed taxonomy in UTM_PHILOSOPHY.md',
44
+ },
45
+ fixable: undefined,
46
+ hasSuggestions: false,
47
+ messages: {
48
+ invalidUtmSource: (0, eslint_devkit_2.formatLLMMessage)({
49
+ icon: eslint_devkit_2.MessageIcons.WARNING,
50
+ issueName: 'Invalid utm_source',
51
+ description: 'utm_source="{{value}}" is not in the fixed taxonomy. Allowed: {{allowed}}',
52
+ severity: 'HIGH',
53
+ fix: 'Use one of the allowed values, or extend the taxonomy in UTM_PHILOSOPHY.md and this rule together.',
54
+ documentationLink: 'https://github.com/ofri-peretz/eslint/blob/main/UTM_PHILOSOPHY.md',
55
+ }),
56
+ invalidUtmMedium: (0, eslint_devkit_2.formatLLMMessage)({
57
+ icon: eslint_devkit_2.MessageIcons.WARNING,
58
+ issueName: 'Invalid utm_medium',
59
+ description: 'utm_medium="{{value}}" is not in the fixed taxonomy. Allowed: {{allowed}}',
60
+ severity: 'HIGH',
61
+ fix: 'Use one of the allowed values, or extend the taxonomy in UTM_PHILOSOPHY.md and this rule together.',
62
+ documentationLink: 'https://github.com/ofri-peretz/eslint/blob/main/UTM_PHILOSOPHY.md',
63
+ }),
64
+ },
65
+ schema: [],
66
+ },
67
+ defaultOptions: [],
68
+ create(context) {
69
+ function checkString(node, value) {
70
+ UTM_PARAM_RE.lastIndex = 0;
71
+ let match;
72
+ while ((match = UTM_PARAM_RE.exec(value)) !== null) {
73
+ const [, key, raw] = match;
74
+ const decoded = decodeURIComponent(raw);
75
+ if (key === 'utm_source' && !VALID_UTM_SOURCES.has(decoded)) {
76
+ context.report({
77
+ node,
78
+ messageId: 'invalidUtmSource',
79
+ data: {
80
+ value: decoded,
81
+ allowed: [...VALID_UTM_SOURCES].join(', '),
82
+ },
83
+ });
84
+ }
85
+ else if (key === 'utm_medium' && !VALID_UTM_MEDIUMS.has(decoded)) {
86
+ context.report({
87
+ node,
88
+ messageId: 'invalidUtmMedium',
89
+ data: {
90
+ value: decoded,
91
+ allowed: [...VALID_UTM_MEDIUMS].join(', '),
92
+ },
93
+ });
94
+ }
95
+ }
96
+ }
97
+ return {
98
+ Literal(node) {
99
+ if (typeof node.value === 'string' && node.value.includes('utm_')) {
100
+ checkString(node, node.value);
101
+ }
102
+ },
103
+ TemplateLiteral(node) {
104
+ for (const quasi of node.quasis) {
105
+ if (quasi.value.cooked && quasi.value.cooked.includes('utm_')) {
106
+ checkString(quasi, quasi.value.cooked);
107
+ }
108
+ }
109
+ },
110
+ };
111
+ },
112
+ });
113
+ //# sourceMappingURL=utm-taxonomy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utm-taxonomy.js","sourceRoot":"","sources":["../../../../src/rules/conventions/utm-taxonomy.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,10 @@ exports.noDeprecatedApi = (0, eslint_devkit_2.createRule)({
13
13
  meta: {
14
14
  type: 'problem',
15
15
  docs: {
16
+ url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/no-deprecated-api.md',
16
17
  description: 'Prevent usage of deprecated APIs with migration context',
18
+ cwe: 'CWE-1078',
19
+ cvss: 7.5,
17
20
  },
18
21
  fixable: 'code',
19
22
  hasSuggestions: true,
@@ -81,6 +84,7 @@ exports.noDeprecatedApi = (0, eslint_devkit_2.createRule)({
81
84
  /**
82
85
  * Calculate days until removal
83
86
  */
87
+ // oxlint-disable-next-line consistent-function-scoping
84
88
  const calculateDaysRemaining = (removalDate) => {
85
89
  if (!removalDate)
86
90
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"no-deprecated-api.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-conventions/src/rules/deprecation/no-deprecated-api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"no-deprecated-api.js","sourceRoot":"","sources":["../../../../src/rules/deprecation/no-deprecated-api.ts"],"names":[],"mappings":"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"}