@sarj/eslint-plugin 16.14.4 → 16.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1356 -1109
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +1267 -1020
- package/dist/rule-examples.cjs +33 -0
- package/dist/rule-examples.js +33 -0
- package/package.json +1 -1
package/dist/rule-examples.cjs
CHANGED
|
@@ -48,6 +48,7 @@ async function verifyRuleExamples(rule, setup = {}) {
|
|
|
48
48
|
try {
|
|
49
49
|
for (const file of example.files) {
|
|
50
50
|
const path = fixturePath(root, file.path);
|
|
51
|
+
validateFixtureSyntax(example.id, file, path);
|
|
51
52
|
await (0, import_promises.mkdir)((0, import_node_path.dirname)(path), { recursive: true });
|
|
52
53
|
await (0, import_promises.writeFile)(path, file.source);
|
|
53
54
|
}
|
|
@@ -92,6 +93,14 @@ function fixturePath(root, path) {
|
|
|
92
93
|
if (!resolved.startsWith(root + import_node_path.sep)) throw new Error(`unsafe example path: ${path}`);
|
|
93
94
|
return resolved;
|
|
94
95
|
}
|
|
96
|
+
function validateFixtureSyntax(exampleId, file, path) {
|
|
97
|
+
if (!/\.[cm]?[jt]sx?$/u.test(file.path)) return;
|
|
98
|
+
try {
|
|
99
|
+
parser.parse(file.source, { filePath: path });
|
|
100
|
+
} catch (error) {
|
|
101
|
+
throw new Error(`${exampleId}: invalid fixture ${file.path}`, { cause: error });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
95
104
|
async function verifyExample(linter, config, example, root, ruleId) {
|
|
96
105
|
const focus = example.files.find((file) => file.path === example.focusPath);
|
|
97
106
|
if (focus === void 0) throw new Error(`${example.id}: focus file is missing`);
|
|
@@ -100,6 +109,19 @@ async function verifyExample(linter, config, example, root, ruleId) {
|
|
|
100
109
|
if (messages.some((message) => message.fatal || message.ruleId !== ruleId)) {
|
|
101
110
|
throw new Error(`${example.id}: invalid fixture: ${messages.map((message) => message.message).join("; ")}`);
|
|
102
111
|
}
|
|
112
|
+
const lines = linter.getSourceCode().lines;
|
|
113
|
+
if (messages.some((message) => !physicalDiagnosticLocation(message, lines))) {
|
|
114
|
+
throw new Error(`${example.id}: invalid diagnostic location`);
|
|
115
|
+
}
|
|
116
|
+
const locations = messages.map((message) => JSON.stringify([
|
|
117
|
+
message.ruleId,
|
|
118
|
+
message.messageId ?? message.message,
|
|
119
|
+
message.line,
|
|
120
|
+
message.column,
|
|
121
|
+
message.endLine,
|
|
122
|
+
message.endColumn
|
|
123
|
+
]));
|
|
124
|
+
if (new Set(locations).size !== locations.length) throw new Error(`${example.id}: duplicate diagnostic`);
|
|
103
125
|
if (messages.length !== example.expectedCount) {
|
|
104
126
|
throw new Error(`${example.id}: expected ${example.expectedCount} findings, received ${messages.length}`);
|
|
105
127
|
}
|
|
@@ -116,6 +138,17 @@ async function verifyExample(linter, config, example, root, ruleId) {
|
|
|
116
138
|
}
|
|
117
139
|
}
|
|
118
140
|
}
|
|
141
|
+
function physicalDiagnosticLocation(message, lines) {
|
|
142
|
+
if (!physicalPosition(lines, message.line, message.column)) return false;
|
|
143
|
+
if (message.endLine === void 0 && message.endColumn === void 0) return true;
|
|
144
|
+
if (!physicalPosition(lines, message.endLine, message.endColumn)) return false;
|
|
145
|
+
return message.endLine !== void 0 && message.endColumn !== void 0 && (message.endLine > message.line || message.endLine === message.line && message.endColumn >= message.column);
|
|
146
|
+
}
|
|
147
|
+
function physicalPosition(lines, line, column) {
|
|
148
|
+
if (line === void 0 || column === void 0 || !Number.isInteger(line) || !Number.isInteger(column)) return false;
|
|
149
|
+
const text = lines[line - 1];
|
|
150
|
+
return text !== void 0 && column >= 1 && column <= text.length + 1;
|
|
151
|
+
}
|
|
119
152
|
// Annotate the CommonJS export names for ESM import in node:
|
|
120
153
|
0 && (module.exports = {
|
|
121
154
|
verifyRuleExamples
|
package/dist/rule-examples.js
CHANGED
|
@@ -14,6 +14,7 @@ async function verifyRuleExamples(rule, setup = {}) {
|
|
|
14
14
|
try {
|
|
15
15
|
for (const file of example.files) {
|
|
16
16
|
const path = fixturePath(root, file.path);
|
|
17
|
+
validateFixtureSyntax(example.id, file, path);
|
|
17
18
|
await mkdir(dirname(path), { recursive: true });
|
|
18
19
|
await writeFile(path, file.source);
|
|
19
20
|
}
|
|
@@ -58,6 +59,14 @@ function fixturePath(root, path) {
|
|
|
58
59
|
if (!resolved.startsWith(root + sep)) throw new Error(`unsafe example path: ${path}`);
|
|
59
60
|
return resolved;
|
|
60
61
|
}
|
|
62
|
+
function validateFixtureSyntax(exampleId, file, path) {
|
|
63
|
+
if (!/\.[cm]?[jt]sx?$/u.test(file.path)) return;
|
|
64
|
+
try {
|
|
65
|
+
parser.parse(file.source, { filePath: path });
|
|
66
|
+
} catch (error) {
|
|
67
|
+
throw new Error(`${exampleId}: invalid fixture ${file.path}`, { cause: error });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
61
70
|
async function verifyExample(linter, config, example, root, ruleId) {
|
|
62
71
|
const focus = example.files.find((file) => file.path === example.focusPath);
|
|
63
72
|
if (focus === void 0) throw new Error(`${example.id}: focus file is missing`);
|
|
@@ -66,6 +75,19 @@ async function verifyExample(linter, config, example, root, ruleId) {
|
|
|
66
75
|
if (messages.some((message) => message.fatal || message.ruleId !== ruleId)) {
|
|
67
76
|
throw new Error(`${example.id}: invalid fixture: ${messages.map((message) => message.message).join("; ")}`);
|
|
68
77
|
}
|
|
78
|
+
const lines = linter.getSourceCode().lines;
|
|
79
|
+
if (messages.some((message) => !physicalDiagnosticLocation(message, lines))) {
|
|
80
|
+
throw new Error(`${example.id}: invalid diagnostic location`);
|
|
81
|
+
}
|
|
82
|
+
const locations = messages.map((message) => JSON.stringify([
|
|
83
|
+
message.ruleId,
|
|
84
|
+
message.messageId ?? message.message,
|
|
85
|
+
message.line,
|
|
86
|
+
message.column,
|
|
87
|
+
message.endLine,
|
|
88
|
+
message.endColumn
|
|
89
|
+
]));
|
|
90
|
+
if (new Set(locations).size !== locations.length) throw new Error(`${example.id}: duplicate diagnostic`);
|
|
69
91
|
if (messages.length !== example.expectedCount) {
|
|
70
92
|
throw new Error(`${example.id}: expected ${example.expectedCount} findings, received ${messages.length}`);
|
|
71
93
|
}
|
|
@@ -82,6 +104,17 @@ async function verifyExample(linter, config, example, root, ruleId) {
|
|
|
82
104
|
}
|
|
83
105
|
}
|
|
84
106
|
}
|
|
107
|
+
function physicalDiagnosticLocation(message, lines) {
|
|
108
|
+
if (!physicalPosition(lines, message.line, message.column)) return false;
|
|
109
|
+
if (message.endLine === void 0 && message.endColumn === void 0) return true;
|
|
110
|
+
if (!physicalPosition(lines, message.endLine, message.endColumn)) return false;
|
|
111
|
+
return message.endLine !== void 0 && message.endColumn !== void 0 && (message.endLine > message.line || message.endLine === message.line && message.endColumn >= message.column);
|
|
112
|
+
}
|
|
113
|
+
function physicalPosition(lines, line, column) {
|
|
114
|
+
if (line === void 0 || column === void 0 || !Number.isInteger(line) || !Number.isInteger(column)) return false;
|
|
115
|
+
const text = lines[line - 1];
|
|
116
|
+
return text !== void 0 && column >= 1 && column <= text.length + 1;
|
|
117
|
+
}
|
|
85
118
|
export {
|
|
86
119
|
verifyRuleExamples
|
|
87
120
|
};
|