eslint-plugin-conventions 4.0.7 → 4.2.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.
- package/CHANGELOG.md +149 -0
- package/LICENSE +23 -0
- package/README.md +51 -21
- package/package.json +20 -3
- package/src/index.d.ts +49 -0
- package/src/index.js +15 -1
- package/src/index.js.map +1 -1
- package/src/lib/eslint-plugin-conventions.js.map +1 -1
- package/src/oxlint.d.ts +20 -0
- package/src/oxlint.js +22 -0
- package/src/oxlint.js.map +1 -0
- package/src/rules/conventions/analytics-event-naming.d.ts +41 -0
- package/src/rules/conventions/analytics-event-naming.js +104 -0
- package/src/rules/conventions/analytics-event-naming.js.map +1 -0
- package/src/rules/conventions/consistent-existence-index-check.js +5 -1
- package/src/rules/conventions/consistent-existence-index-check.js.map +1 -1
- package/src/rules/conventions/expiring-todo-comments.d.ts +41 -0
- package/src/rules/conventions/expiring-todo-comments.js +174 -165
- package/src/rules/conventions/expiring-todo-comments.js.map +1 -1
- package/src/rules/conventions/filename-case.js +13 -4
- package/src/rules/conventions/filename-case.js.map +1 -1
- package/src/rules/conventions/no-commented-code.js +3 -2
- package/src/rules/conventions/no-commented-code.js.map +1 -1
- package/src/rules/conventions/no-console-spaces.js +5 -0
- package/src/rules/conventions/no-console-spaces.js.map +1 -1
- package/src/rules/conventions/no-json-schema-tags.js +2 -1
- package/src/rules/conventions/no-json-schema-tags.js.map +1 -1
- package/src/rules/conventions/no-magic-numbers.d.ts +41 -0
- package/src/rules/conventions/no-magic-numbers.js +205 -0
- package/src/rules/conventions/no-magic-numbers.js.map +1 -0
- package/src/rules/conventions/no-raw-cross-property-href.d.ts +24 -0
- package/src/rules/conventions/no-raw-cross-property-href.js +86 -0
- package/src/rules/conventions/no-raw-cross-property-href.js.map +1 -0
- package/src/rules/conventions/prefer-code-point.js +4 -1
- package/src/rules/conventions/prefer-code-point.js.map +1 -1
- package/src/rules/conventions/prefer-dependency-version-strategy.d.ts +5 -5
- package/src/rules/conventions/prefer-dependency-version-strategy.js +1 -0
- package/src/rules/conventions/prefer-dependency-version-strategy.js.map +1 -1
- package/src/rules/conventions/prefer-dom-node-text-content.js +7 -7
- package/src/rules/conventions/prefer-dom-node-text-content.js.map +1 -1
- package/src/rules/conventions/require-data-testid.d.ts +56 -0
- package/src/rules/conventions/require-data-testid.js +209 -0
- package/src/rules/conventions/require-data-testid.js.map +1 -0
- package/src/rules/conventions/utm-taxonomy.d.ts +25 -0
- package/src/rules/conventions/utm-taxonomy.js +117 -0
- package/src/rules/conventions/utm-taxonomy.js.map +1 -0
- package/src/rules/deprecation/no-deprecated-api.js +6 -1
- package/src/rules/deprecation/no-deprecated-api.js.map +1 -1
|
@@ -0,0 +1,104 @@
|
|
|
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.analyticsEventNaming = void 0;
|
|
9
|
+
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
10
|
+
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
11
|
+
// ANALYTICS_PHILOSOPHY.md principle 4 → fixed verb list. Edit there and
|
|
12
|
+
// here together.
|
|
13
|
+
const ACTION_VERBS = [
|
|
14
|
+
'click',
|
|
15
|
+
'submit',
|
|
16
|
+
'view',
|
|
17
|
+
'add',
|
|
18
|
+
'remove',
|
|
19
|
+
'start',
|
|
20
|
+
'end',
|
|
21
|
+
'generate',
|
|
22
|
+
'send',
|
|
23
|
+
'cancel',
|
|
24
|
+
'fail',
|
|
25
|
+
'create',
|
|
26
|
+
'delete',
|
|
27
|
+
'update',
|
|
28
|
+
'invite',
|
|
29
|
+
].join('|');
|
|
30
|
+
const EVENT_NAME_RE = new RegExp(`^[a-z][a-z0-9_]*:[a-z][a-z0-9_]*_(${ACTION_VERBS})$|^\\$[a-z_]+$`);
|
|
31
|
+
exports.analyticsEventNaming = (0, eslint_devkit_1.createRule)({
|
|
32
|
+
name: 'analytics-event-naming',
|
|
33
|
+
meta: {
|
|
34
|
+
type: 'problem',
|
|
35
|
+
docs: {
|
|
36
|
+
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/analytics-event-naming.md',
|
|
37
|
+
description: 'Analytics event names (track/capture) must follow ANALYTICS_PHILOSOPHY.md principle 4: lowercase snake_case, category:object_action, fixed verb list',
|
|
38
|
+
},
|
|
39
|
+
fixable: undefined,
|
|
40
|
+
hasSuggestions: false,
|
|
41
|
+
messages: {
|
|
42
|
+
invalidEventName: (0, eslint_devkit_2.formatLLMMessage)({
|
|
43
|
+
icon: eslint_devkit_2.MessageIcons.WARNING,
|
|
44
|
+
issueName: 'Invalid analytics event name',
|
|
45
|
+
description: 'Event "{{name}}" does not match category:object_action grammar (lowercase snake_case, action from fixed verb list).',
|
|
46
|
+
severity: 'HIGH',
|
|
47
|
+
fix: 'Rename to match `<category>:<object>_<verb>` where verb ∈ {click, submit, view, add, remove, start, end, generate, send, cancel, fail, create, delete, update, invite}. Vendor reserved events ($pageview, $set, …) are exempt.',
|
|
48
|
+
documentationLink: 'https://github.com/ofri-peretz/eslint/blob/main/ANALYTICS_PHILOSOPHY.md',
|
|
49
|
+
}),
|
|
50
|
+
interpolatedEventName: (0, eslint_devkit_2.formatLLMMessage)({
|
|
51
|
+
icon: eslint_devkit_2.MessageIcons.WARNING,
|
|
52
|
+
issueName: 'Interpolated analytics event name',
|
|
53
|
+
description: 'Event names must be static string literals. Template literals create an unbounded catalog (ANALYTICS_PHILOSOPHY.md principle 3).',
|
|
54
|
+
severity: 'HIGH',
|
|
55
|
+
fix: 'Move the dynamic part into an event property: track(\'category:object_view\', { slug }).',
|
|
56
|
+
documentationLink: 'https://github.com/ofri-peretz/eslint/blob/main/ANALYTICS_PHILOSOPHY.md',
|
|
57
|
+
}),
|
|
58
|
+
},
|
|
59
|
+
schema: [],
|
|
60
|
+
},
|
|
61
|
+
defaultOptions: [],
|
|
62
|
+
create(context) {
|
|
63
|
+
function isCaptureLike(node) {
|
|
64
|
+
// <obj>.capture(...) — PostHog
|
|
65
|
+
// <obj>.track(...) — Segment / Mixpanel / Amplitude
|
|
66
|
+
if (node.callee.type === 'MemberExpression' &&
|
|
67
|
+
node.callee.property.type === 'Identifier' &&
|
|
68
|
+
(node.callee.property.name === 'capture' ||
|
|
69
|
+
node.callee.property.name === 'track')) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
// bare track(...) — our primitive
|
|
73
|
+
if (node.callee.type === 'Identifier' &&
|
|
74
|
+
node.callee.name === 'track') {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
CallExpression(node) {
|
|
81
|
+
if (!isCaptureLike(node) || node.arguments.length === 0)
|
|
82
|
+
return;
|
|
83
|
+
const first = node.arguments[0];
|
|
84
|
+
if (first.type === 'Literal' && typeof first.value === 'string') {
|
|
85
|
+
if (!EVENT_NAME_RE.test(first.value)) {
|
|
86
|
+
context.report({
|
|
87
|
+
node: first,
|
|
88
|
+
messageId: 'invalidEventName',
|
|
89
|
+
data: { name: first.value },
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (first.type === 'TemplateLiteral' && first.expressions.length > 0) {
|
|
95
|
+
context.report({
|
|
96
|
+
node: first,
|
|
97
|
+
messageId: 'interpolatedEventName',
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
//# sourceMappingURL=analytics-event-naming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics-event-naming.js","sourceRoot":"","sources":["../../../../src/rules/conventions/analytics-event-naming.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,6 +13,7 @@ exports.consistentExistenceIndexCheck = (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/consistent-existence-index-check.md',
|
|
16
17
|
description: 'Enforce consistent style for checking object property existence',
|
|
17
18
|
},
|
|
18
19
|
fixable: 'code',
|
|
@@ -94,7 +95,10 @@ exports.consistentExistenceIndexCheck = (0, eslint_devkit_1.createRule)({
|
|
|
94
95
|
return {
|
|
95
96
|
// Check for hasOwnProperty calls
|
|
96
97
|
CallExpression(node) {
|
|
97
|
-
// Direct hasOwnProperty calls: obj.hasOwnProperty(prop)
|
|
98
|
+
// Direct hasOwnProperty calls: obj.hasOwnProperty(prop). Reindented
|
|
99
|
+
// to match the sibling `if` blocks below — the original 6-space
|
|
100
|
+
// indent here suggested this branch was at a different scope level
|
|
101
|
+
// (CodeQL: `js/misleading-indentation-after-control-statement`).
|
|
98
102
|
if (node.callee.type === 'MemberExpression' &&
|
|
99
103
|
node.callee.property.type === 'Identifier' &&
|
|
100
104
|
node.callee.property.name === 'hasOwnProperty' &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consistent-existence-index-check.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"consistent-existence-index-check.js","sourceRoot":"","sources":["../../../../src/rules/conventions/consistent-existence-index-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,47 @@ export interface Options {
|
|
|
18
18
|
allowWarningComments?: boolean;
|
|
19
19
|
}
|
|
20
20
|
type RuleOptions = [Options?];
|
|
21
|
+
export interface PackageJson {
|
|
22
|
+
version?: string;
|
|
23
|
+
engines?: {
|
|
24
|
+
node?: string;
|
|
25
|
+
};
|
|
26
|
+
dependencies?: Record<string, string>;
|
|
27
|
+
devDependencies?: Record<string, string>;
|
|
28
|
+
peerDependencies?: Record<string, string>;
|
|
29
|
+
}
|
|
30
|
+
/** A condition parsed out of a `TODO [condition]` bracket. */
|
|
31
|
+
export interface ParsedTodoCondition {
|
|
32
|
+
type: string;
|
|
33
|
+
value: string;
|
|
34
|
+
operator?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Normalize a version specifier (`^1.2.3`, `24.x`, `18`) into numeric
|
|
38
|
+
* major/minor/patch parts. Wildcard or non-numeric segments become 0 —
|
|
39
|
+
* without this, `package.json#engines.node: "24.x"` would compare as
|
|
40
|
+
* equal to everything, making every `>=` engine TODO falsely match.
|
|
41
|
+
*/
|
|
42
|
+
export declare function parseVersionParts(version: string): {
|
|
43
|
+
major: number;
|
|
44
|
+
minor: number;
|
|
45
|
+
patch: number;
|
|
46
|
+
};
|
|
47
|
+
export declare function compareVersions(version1: string, version2: string): number;
|
|
48
|
+
export declare function checkDateCondition(dateStr: string): boolean;
|
|
49
|
+
export declare function checkPackageVersionCondition(pkg: PackageJson | null, operator: string, targetVersion: string): boolean;
|
|
50
|
+
export declare function checkEngineVersionCondition(pkg: PackageJson | null, engine: string, operator: string, targetVersion: string): boolean;
|
|
51
|
+
export declare function checkDependencyCondition(pkg: PackageJson | null, packageName: string, present: boolean): boolean;
|
|
52
|
+
export declare function parseTodoCondition(commentValue: string, term: string): {
|
|
53
|
+
conditions: string[];
|
|
54
|
+
rest: string;
|
|
55
|
+
} | null;
|
|
56
|
+
export declare function validateCondition(condition: string): ParsedTodoCondition | null;
|
|
57
|
+
/**
|
|
58
|
+
* Evaluate an already-parsed condition. `getPkg` is called lazily so that
|
|
59
|
+
* date-only conditions never touch the filesystem.
|
|
60
|
+
*/
|
|
61
|
+
export declare function checkParsedCondition(getPkg: () => PackageJson | null, parsed: ParsedTodoCondition | null): boolean;
|
|
21
62
|
export declare const expiringTodoComments: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener> & {
|
|
22
63
|
name: string;
|
|
23
64
|
};
|
|
@@ -6,15 +6,188 @@
|
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.expiringTodoComments = void 0;
|
|
9
|
+
exports.parseVersionParts = parseVersionParts;
|
|
10
|
+
exports.compareVersions = compareVersions;
|
|
11
|
+
exports.checkDateCondition = checkDateCondition;
|
|
12
|
+
exports.checkPackageVersionCondition = checkPackageVersionCondition;
|
|
13
|
+
exports.checkEngineVersionCondition = checkEngineVersionCondition;
|
|
14
|
+
exports.checkDependencyCondition = checkDependencyCondition;
|
|
15
|
+
exports.parseTodoCondition = parseTodoCondition;
|
|
16
|
+
exports.validateCondition = validateCondition;
|
|
17
|
+
exports.checkParsedCondition = checkParsedCondition;
|
|
9
18
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
10
19
|
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
11
20
|
const eslint_devkit_3 = require("@interlace/eslint-devkit");
|
|
12
21
|
const eslint_devkit_4 = require("@interlace/eslint-devkit");
|
|
22
|
+
/**
|
|
23
|
+
* Normalize a version specifier (`^1.2.3`, `24.x`, `18`) into numeric
|
|
24
|
+
* major/minor/patch parts. Wildcard or non-numeric segments become 0 —
|
|
25
|
+
* without this, `package.json#engines.node: "24.x"` would compare as
|
|
26
|
+
* equal to everything, making every `>=` engine TODO falsely match.
|
|
27
|
+
*/
|
|
28
|
+
function parseVersionParts(version) {
|
|
29
|
+
const cleaned = version.replace(/^[\^~>=<]+/, '').trim();
|
|
30
|
+
const parts = cleaned
|
|
31
|
+
.split('.')
|
|
32
|
+
.map((p) => (/^\d+$/.test(p) ? parseInt(p, 10) : 0));
|
|
33
|
+
while (parts.length < 3)
|
|
34
|
+
parts.push(0);
|
|
35
|
+
return { major: parts[0], minor: parts[1], patch: parts[2] };
|
|
36
|
+
}
|
|
37
|
+
function compareVersions(version1, version2) {
|
|
38
|
+
const v1 = parseVersionParts(version1);
|
|
39
|
+
const v2 = parseVersionParts(version2);
|
|
40
|
+
if (v1.major !== v2.major)
|
|
41
|
+
return v1.major - v2.major;
|
|
42
|
+
if (v1.minor !== v2.minor)
|
|
43
|
+
return v1.minor - v2.minor;
|
|
44
|
+
return v1.patch - v2.patch;
|
|
45
|
+
}
|
|
46
|
+
function checkDateCondition(dateStr) {
|
|
47
|
+
// Invalid date strings produce an Invalid Date; comparisons against it
|
|
48
|
+
// are always false, so malformed input safely reads as "not expired".
|
|
49
|
+
const conditionDate = new Date(dateStr + 'T00:00:00Z'); // UTC
|
|
50
|
+
const now = new Date();
|
|
51
|
+
return now >= conditionDate;
|
|
52
|
+
}
|
|
53
|
+
function checkPackageVersionCondition(pkg, operator, targetVersion) {
|
|
54
|
+
if (!pkg?.version)
|
|
55
|
+
return false;
|
|
56
|
+
const comparison = compareVersions(pkg.version, targetVersion);
|
|
57
|
+
switch (operator) {
|
|
58
|
+
case '>':
|
|
59
|
+
return comparison > 0;
|
|
60
|
+
case '>=':
|
|
61
|
+
return comparison >= 0;
|
|
62
|
+
case '<':
|
|
63
|
+
return comparison < 0;
|
|
64
|
+
case '<=':
|
|
65
|
+
return comparison <= 0;
|
|
66
|
+
case '=':
|
|
67
|
+
case '==':
|
|
68
|
+
return comparison === 0;
|
|
69
|
+
default:
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function checkEngineVersionCondition(pkg, engine, operator, targetVersion) {
|
|
74
|
+
if (engine !== 'node')
|
|
75
|
+
return false;
|
|
76
|
+
const nodeVersion = pkg?.engines?.node;
|
|
77
|
+
if (!nodeVersion)
|
|
78
|
+
return false;
|
|
79
|
+
// Simple version comparison for engines
|
|
80
|
+
const currentVersion = nodeVersion.replace(/^[\^~>=<]+/, '');
|
|
81
|
+
const comparison = compareVersions(currentVersion, targetVersion);
|
|
82
|
+
switch (operator) {
|
|
83
|
+
case '>':
|
|
84
|
+
return comparison > 0;
|
|
85
|
+
case '>=':
|
|
86
|
+
return comparison >= 0;
|
|
87
|
+
case '<':
|
|
88
|
+
return comparison < 0;
|
|
89
|
+
case '<=':
|
|
90
|
+
return comparison <= 0;
|
|
91
|
+
default:
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function checkDependencyCondition(pkg, packageName, present) {
|
|
96
|
+
if (!pkg)
|
|
97
|
+
return false;
|
|
98
|
+
const allDeps = {
|
|
99
|
+
...pkg.dependencies,
|
|
100
|
+
...pkg.devDependencies,
|
|
101
|
+
...pkg.peerDependencies,
|
|
102
|
+
};
|
|
103
|
+
const hasPackage = packageName in allDeps;
|
|
104
|
+
return present ? hasPackage : hasPackage;
|
|
105
|
+
}
|
|
106
|
+
function parseTodoCondition(commentValue, term) {
|
|
107
|
+
// Match patterns like: TODO [condition]: message
|
|
108
|
+
// or TODO (@author) [condition]: message
|
|
109
|
+
// Also handle block comments with * prefix: * TODO [condition]: message
|
|
110
|
+
const todoRegex = new RegExp(`\\*?\\s*${term}\\s*(?:\\([^)]+\\))?\\s*\\[([^\\]]+)\\]\\s*:\\s*(.+)$`, 'im');
|
|
111
|
+
const match = commentValue.match(todoRegex);
|
|
112
|
+
if (!match)
|
|
113
|
+
return null;
|
|
114
|
+
const conditionStr = match[1];
|
|
115
|
+
const rest = match[2];
|
|
116
|
+
// Split multiple conditions (shouldn't happen, but handle gracefully)
|
|
117
|
+
const conditions = conditionStr.split(/\s*,\s*/);
|
|
118
|
+
return { conditions, rest };
|
|
119
|
+
}
|
|
120
|
+
function validateCondition(condition) {
|
|
121
|
+
// Date condition: YYYY-MM-DD
|
|
122
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(condition)) {
|
|
123
|
+
return { type: 'date', value: condition };
|
|
124
|
+
}
|
|
125
|
+
// Package version condition: >=1.0.0, >2.0.0, etc.
|
|
126
|
+
const packageVersionMatch = condition.match(/^([><]=?|=|==)\s*([\d.]+)$/);
|
|
127
|
+
if (packageVersionMatch) {
|
|
128
|
+
return {
|
|
129
|
+
type: 'package-version',
|
|
130
|
+
operator: packageVersionMatch[1],
|
|
131
|
+
value: packageVersionMatch[2],
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
// Engine version condition: engine:node@>=8, engine:node@>20.0.0
|
|
135
|
+
const engineVersionMatch = condition.match(/^engine:(\w+)@([><]=?)\s*([\d.]+)$/);
|
|
136
|
+
if (engineVersionMatch) {
|
|
137
|
+
const engine = engineVersionMatch[1];
|
|
138
|
+
// Validate engine name
|
|
139
|
+
if (!['node', 'npm', 'yarn', 'pnpm'].includes(engine)) {
|
|
140
|
+
return null; // Invalid engine, let it be caught as invalid condition
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
type: 'engine-version',
|
|
144
|
+
value: `${engine}@${engineVersionMatch[3]}`,
|
|
145
|
+
operator: engineVersionMatch[2],
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
// Dependency condition: +package-name or -package-name
|
|
149
|
+
const depMatch = condition.match(/^([+-])(.+)$/);
|
|
150
|
+
if (depMatch) {
|
|
151
|
+
return {
|
|
152
|
+
type: 'dependency',
|
|
153
|
+
value: depMatch[2],
|
|
154
|
+
operator: depMatch[1],
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Evaluate an already-parsed condition. `getPkg` is called lazily so that
|
|
161
|
+
* date-only conditions never touch the filesystem.
|
|
162
|
+
*/
|
|
163
|
+
function checkParsedCondition(getPkg, parsed) {
|
|
164
|
+
if (!parsed)
|
|
165
|
+
return false;
|
|
166
|
+
switch (parsed.type) {
|
|
167
|
+
case 'date':
|
|
168
|
+
return checkDateCondition(parsed.value);
|
|
169
|
+
case 'package-version':
|
|
170
|
+
return parsed.operator
|
|
171
|
+
? checkPackageVersionCondition(getPkg(), parsed.operator, parsed.value)
|
|
172
|
+
: false;
|
|
173
|
+
case 'engine-version': {
|
|
174
|
+
const [engine, version] = parsed.value.split('@');
|
|
175
|
+
return parsed.operator
|
|
176
|
+
? checkEngineVersionCondition(getPkg(), engine, parsed.operator, version)
|
|
177
|
+
: false;
|
|
178
|
+
}
|
|
179
|
+
case 'dependency':
|
|
180
|
+
return checkDependencyCondition(getPkg(), parsed.value, parsed.operator === '+');
|
|
181
|
+
default:
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
13
185
|
exports.expiringTodoComments = (0, eslint_devkit_1.createRule)({
|
|
14
186
|
name: 'expiring-todo-comments',
|
|
15
187
|
meta: {
|
|
16
188
|
type: 'problem',
|
|
17
189
|
docs: {
|
|
190
|
+
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-conventions/docs/rules/expiring-todo-comments.md',
|
|
18
191
|
description: 'Add expiration conditions to TODO comments to prevent forgotten tasks',
|
|
19
192
|
},
|
|
20
193
|
hasSuggestions: false,
|
|
@@ -78,170 +251,6 @@ exports.expiringTodoComments = (0, eslint_devkit_1.createRule)({
|
|
|
78
251
|
packageJson = (0, eslint_devkit_3.readJsonFileSync)(packageJsonPath);
|
|
79
252
|
return packageJson;
|
|
80
253
|
}
|
|
81
|
-
function parseSemver(version) {
|
|
82
|
-
const match = version.match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
83
|
-
if (!match)
|
|
84
|
-
return null;
|
|
85
|
-
return {
|
|
86
|
-
major: parseInt(match[1], 10),
|
|
87
|
-
minor: parseInt(match[2], 10),
|
|
88
|
-
patch: parseInt(match[3], 10),
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
function compareVersions(version1, version2) {
|
|
92
|
-
const v1 = parseSemver(version1);
|
|
93
|
-
const v2 = parseSemver(version2);
|
|
94
|
-
if (!v1 || !v2)
|
|
95
|
-
return 0;
|
|
96
|
-
if (v1.major !== v2.major)
|
|
97
|
-
return v1.major - v2.major;
|
|
98
|
-
if (v1.minor !== v2.minor)
|
|
99
|
-
return v1.minor - v2.minor;
|
|
100
|
-
return v1.patch - v2.patch;
|
|
101
|
-
}
|
|
102
|
-
function checkDateCondition(dateStr) {
|
|
103
|
-
try {
|
|
104
|
-
const conditionDate = new Date(dateStr + 'T00:00:00Z'); // UTC
|
|
105
|
-
const now = new Date();
|
|
106
|
-
return now >= conditionDate;
|
|
107
|
-
}
|
|
108
|
-
catch {
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
function checkPackageVersionCondition(operator, targetVersion) {
|
|
113
|
-
const pkg = loadPackageJson();
|
|
114
|
-
if (!pkg?.version)
|
|
115
|
-
return false;
|
|
116
|
-
const currentVersion = pkg.version;
|
|
117
|
-
const comparison = compareVersions(currentVersion, targetVersion);
|
|
118
|
-
switch (operator) {
|
|
119
|
-
case '>':
|
|
120
|
-
return comparison > 0;
|
|
121
|
-
case '>=':
|
|
122
|
-
return comparison >= 0;
|
|
123
|
-
case '<':
|
|
124
|
-
return comparison < 0;
|
|
125
|
-
case '<=':
|
|
126
|
-
return comparison <= 0;
|
|
127
|
-
case '=':
|
|
128
|
-
case '==':
|
|
129
|
-
return comparison === 0;
|
|
130
|
-
default:
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
function checkEngineVersionCondition(engine, operator, targetVersion) {
|
|
135
|
-
if (engine !== 'node')
|
|
136
|
-
return false;
|
|
137
|
-
const pkg = loadPackageJson();
|
|
138
|
-
const nodeVersion = pkg?.engines?.node;
|
|
139
|
-
if (!nodeVersion)
|
|
140
|
-
return false;
|
|
141
|
-
// Simple version comparison for engines
|
|
142
|
-
const currentVersion = nodeVersion.replace(/^[\^~>=<]+/, '');
|
|
143
|
-
const comparison = compareVersions(currentVersion, targetVersion);
|
|
144
|
-
switch (operator) {
|
|
145
|
-
case '>':
|
|
146
|
-
return comparison > 0;
|
|
147
|
-
case '>=':
|
|
148
|
-
return comparison >= 0;
|
|
149
|
-
case '<':
|
|
150
|
-
return comparison < 0;
|
|
151
|
-
case '<=':
|
|
152
|
-
return comparison <= 0;
|
|
153
|
-
default:
|
|
154
|
-
return false;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
function checkDependencyCondition(packageName, present) {
|
|
158
|
-
const pkg = loadPackageJson();
|
|
159
|
-
if (!pkg)
|
|
160
|
-
return false;
|
|
161
|
-
const allDeps = {
|
|
162
|
-
...pkg.dependencies,
|
|
163
|
-
...pkg.devDependencies,
|
|
164
|
-
...pkg.peerDependencies,
|
|
165
|
-
};
|
|
166
|
-
const hasPackage = packageName in allDeps;
|
|
167
|
-
return present ? hasPackage : hasPackage;
|
|
168
|
-
}
|
|
169
|
-
function parseTodoCondition(commentValue, term) {
|
|
170
|
-
// Match patterns like: TODO [condition]: message
|
|
171
|
-
// or TODO (@author) [condition]: message
|
|
172
|
-
// Also handle block comments with * prefix: * TODO [condition]: message
|
|
173
|
-
const todoRegex = new RegExp(`\\*?\\s*${term}\\s*(?:\\([^)]+\\))?\\s*\\[([^\\]]+)\\]\\s*:\\s*(.+)$`, 'im');
|
|
174
|
-
const match = commentValue.match(todoRegex);
|
|
175
|
-
if (!match)
|
|
176
|
-
return null;
|
|
177
|
-
const conditionStr = match[1];
|
|
178
|
-
const rest = match[2];
|
|
179
|
-
// Split multiple conditions (shouldn't happen, but handle gracefully)
|
|
180
|
-
const conditions = conditionStr.split(/\s*,\s*/);
|
|
181
|
-
return { conditions, rest };
|
|
182
|
-
}
|
|
183
|
-
function validateCondition(condition) {
|
|
184
|
-
// Date condition: YYYY-MM-DD
|
|
185
|
-
if (/^\d{4}-\d{2}-\d{2}$/.test(condition)) {
|
|
186
|
-
return { type: 'date', value: condition };
|
|
187
|
-
}
|
|
188
|
-
// Package version condition: >=1.0.0, >2.0.0, etc.
|
|
189
|
-
const packageVersionMatch = condition.match(/^([><]=?|=|==)\s*([\d.]+)$/);
|
|
190
|
-
if (packageVersionMatch) {
|
|
191
|
-
return {
|
|
192
|
-
type: 'package-version',
|
|
193
|
-
operator: packageVersionMatch[1],
|
|
194
|
-
value: packageVersionMatch[2],
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
// Engine version condition: engine:node@>=8, engine:node@>20.0.0
|
|
198
|
-
const engineVersionMatch = condition.match(/^engine:(\w+)@([><]=?)\s*([\d.]+)$/);
|
|
199
|
-
if (engineVersionMatch) {
|
|
200
|
-
const engine = engineVersionMatch[1];
|
|
201
|
-
// Validate engine name
|
|
202
|
-
if (!['node', 'npm', 'yarn', 'pnpm'].includes(engine)) {
|
|
203
|
-
return null; // Invalid engine, let it be caught as invalid condition
|
|
204
|
-
}
|
|
205
|
-
return {
|
|
206
|
-
type: 'engine-version',
|
|
207
|
-
value: `${engine}@${engineVersionMatch[3]}`,
|
|
208
|
-
operator: engineVersionMatch[2],
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
// Dependency condition: +package-name or -package-name
|
|
212
|
-
const depMatch = condition.match(/^([+-])(.+)$/);
|
|
213
|
-
if (depMatch) {
|
|
214
|
-
return {
|
|
215
|
-
type: 'dependency',
|
|
216
|
-
value: depMatch[2],
|
|
217
|
-
operator: depMatch[1],
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
return null;
|
|
221
|
-
}
|
|
222
|
-
function checkCondition(condition) {
|
|
223
|
-
const parsed = validateCondition(condition);
|
|
224
|
-
if (!parsed)
|
|
225
|
-
return false;
|
|
226
|
-
switch (parsed.type) {
|
|
227
|
-
case 'date':
|
|
228
|
-
return checkDateCondition(parsed.value);
|
|
229
|
-
case 'package-version':
|
|
230
|
-
return parsed.operator
|
|
231
|
-
? checkPackageVersionCondition(parsed.operator, parsed.value)
|
|
232
|
-
: false;
|
|
233
|
-
case 'engine-version': {
|
|
234
|
-
const [engine, version] = parsed.value.split('@');
|
|
235
|
-
return parsed.operator
|
|
236
|
-
? checkEngineVersionCondition(engine, parsed.operator, version)
|
|
237
|
-
: false;
|
|
238
|
-
}
|
|
239
|
-
case 'dependency':
|
|
240
|
-
return checkDependencyCondition(parsed.value, parsed.operator === '+');
|
|
241
|
-
default:
|
|
242
|
-
return false;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
254
|
function checkComment(comment) {
|
|
246
255
|
const commentValue = comment.value;
|
|
247
256
|
for (const term of terms) {
|
|
@@ -276,7 +285,7 @@ exports.expiringTodoComments = (0, eslint_devkit_1.createRule)({
|
|
|
276
285
|
continue;
|
|
277
286
|
}
|
|
278
287
|
// Check if condition has expired
|
|
279
|
-
if (
|
|
288
|
+
if (checkParsedCondition(loadPackageJson, parsedCondition)) {
|
|
280
289
|
context.report({
|
|
281
290
|
loc: comment.loc,
|
|
282
291
|
messageId: 'expiringTodoComment',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expiring-todo-comments.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"expiring-todo-comments.js","sourceRoot":"","sources":["../../../../src/rules/conventions/expiring-todo-comments.ts"],"names":[],"mappings":"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"}
|