@redocly/recheck 0.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.
- package/README.md +544 -0
- package/dist/assertions/bullet-style.d.ts +3 -0
- package/dist/assertions/bullet-style.d.ts.map +1 -0
- package/dist/assertions/bullet-style.js +60 -0
- package/dist/assertions/bullet-style.js.map +1 -0
- package/dist/assertions/index.d.ts +21 -0
- package/dist/assertions/index.d.ts.map +1 -0
- package/dist/assertions/index.js +30 -0
- package/dist/assertions/index.js.map +1 -0
- package/dist/assertions/max-image-size.d.ts +3 -0
- package/dist/assertions/max-image-size.d.ts.map +1 -0
- package/dist/assertions/max-image-size.js +73 -0
- package/dist/assertions/max-image-size.js.map +1 -0
- package/dist/assertions/max-line-length.d.ts +3 -0
- package/dist/assertions/max-line-length.d.ts.map +1 -0
- package/dist/assertions/max-line-length.js +68 -0
- package/dist/assertions/max-line-length.js.map +1 -0
- package/dist/assertions/no-broken-fragment-links.d.ts +3 -0
- package/dist/assertions/no-broken-fragment-links.d.ts.map +1 -0
- package/dist/assertions/no-broken-fragment-links.js +79 -0
- package/dist/assertions/no-broken-fragment-links.js.map +1 -0
- package/dist/assertions/no-duplicate-headings.d.ts +3 -0
- package/dist/assertions/no-duplicate-headings.d.ts.map +1 -0
- package/dist/assertions/no-duplicate-headings.js +66 -0
- package/dist/assertions/no-duplicate-headings.js.map +1 -0
- package/dist/assertions/no-hard-tabs.d.ts +3 -0
- package/dist/assertions/no-hard-tabs.d.ts.map +1 -0
- package/dist/assertions/no-hard-tabs.js +63 -0
- package/dist/assertions/no-hard-tabs.js.map +1 -0
- package/dist/assertions/no-trailing-spaces.d.ts +3 -0
- package/dist/assertions/no-trailing-spaces.d.ts.map +1 -0
- package/dist/assertions/no-trailing-spaces.js +72 -0
- package/dist/assertions/no-trailing-spaces.js.map +1 -0
- package/dist/assertions/pattern.d.ts +3 -0
- package/dist/assertions/pattern.d.ts.map +1 -0
- package/dist/assertions/pattern.js +39 -0
- package/dist/assertions/pattern.js.map +1 -0
- package/dist/assertions/semantic-line-breaks.d.ts +3 -0
- package/dist/assertions/semantic-line-breaks.d.ts.map +1 -0
- package/dist/assertions/semantic-line-breaks.js +152 -0
- package/dist/assertions/semantic-line-breaks.js.map +1 -0
- package/dist/assertions/swap.d.ts +3 -0
- package/dist/assertions/swap.d.ts.map +1 -0
- package/dist/assertions/swap.js +39 -0
- package/dist/assertions/swap.js.map +1 -0
- package/dist/assertions/utils.d.ts +8 -0
- package/dist/assertions/utils.d.ts.map +1 -0
- package/dist/assertions/utils.js +57 -0
- package/dist/assertions/utils.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +125 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/run.d.ts +20 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +115 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/validate.d.ts +8 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +43 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/config/load.d.ts +20 -0
- package/dist/config/load.d.ts.map +1 -0
- package/dist/config/load.js +85 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/schema.d.ts +109 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +103 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/validate.d.ts +10 -0
- package/dist/config/validate.d.ts.map +1 -0
- package/dist/config/validate.js +129 -0
- package/dist/config/validate.js.map +1 -0
- package/dist/core/auto-fix.d.ts +16 -0
- package/dist/core/auto-fix.d.ts.map +1 -0
- package/dist/core/auto-fix.js +82 -0
- package/dist/core/auto-fix.js.map +1 -0
- package/dist/core/files.d.ts +6 -0
- package/dist/core/files.d.ts.map +1 -0
- package/dist/core/files.js +75 -0
- package/dist/core/files.js.map +1 -0
- package/dist/core/rule-filters.d.ts +28 -0
- package/dist/core/rule-filters.d.ts.map +1 -0
- package/dist/core/rule-filters.js +54 -0
- package/dist/core/rule-filters.js.map +1 -0
- package/dist/core/runner.d.ts +4 -0
- package/dist/core/runner.d.ts.map +1 -0
- package/dist/core/runner.js +135 -0
- package/dist/core/runner.js.map +1 -0
- package/dist/core/scope-parser.d.ts +26 -0
- package/dist/core/scope-parser.d.ts.map +1 -0
- package/dist/core/scope-parser.js +110 -0
- package/dist/core/scope-parser.js.map +1 -0
- package/dist/core/timing.d.ts +24 -0
- package/dist/core/timing.d.ts.map +1 -0
- package/dist/core/timing.js +39 -0
- package/dist/core/timing.js.map +1 -0
- package/dist/files.d.ts +2 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +39 -0
- package/dist/files.js.map +1 -0
- package/dist/load-config.d.ts +25 -0
- package/dist/load-config.d.ts.map +1 -0
- package/dist/load-config.js +104 -0
- package/dist/load-config.js.map +1 -0
- package/dist/load.d.ts +25 -0
- package/dist/load.d.ts.map +1 -0
- package/dist/load.js +112 -0
- package/dist/load.js.map +1 -0
- package/dist/reporter/fixes.d.ts +3 -0
- package/dist/reporter/fixes.d.ts.map +1 -0
- package/dist/reporter/fixes.js +20 -0
- package/dist/reporter/fixes.js.map +1 -0
- package/dist/reporter/formats/github-actions.d.ts +6 -0
- package/dist/reporter/formats/github-actions.d.ts.map +1 -0
- package/dist/reporter/formats/github-actions.js +20 -0
- package/dist/reporter/formats/github-actions.js.map +1 -0
- package/dist/reporter/formats/json.d.ts +6 -0
- package/dist/reporter/formats/json.d.ts.map +1 -0
- package/dist/reporter/formats/json.js +24 -0
- package/dist/reporter/formats/json.js.map +1 -0
- package/dist/reporter/formats/sarif.d.ts +10 -0
- package/dist/reporter/formats/sarif.d.ts.map +1 -0
- package/dist/reporter/formats/sarif.js +66 -0
- package/dist/reporter/formats/sarif.js.map +1 -0
- package/dist/reporter/formats/table.d.ts +6 -0
- package/dist/reporter/formats/table.d.ts.map +1 -0
- package/dist/reporter/formats/table.js +38 -0
- package/dist/reporter/formats/table.js.map +1 -0
- package/dist/reporter/index.d.ts +10 -0
- package/dist/reporter/index.d.ts.map +1 -0
- package/dist/reporter/index.js +42 -0
- package/dist/reporter/index.js.map +1 -0
- package/dist/reporter/prioritize-problems.d.ts +7 -0
- package/dist/reporter/prioritize-problems.d.ts.map +1 -0
- package/dist/reporter/prioritize-problems.js +29 -0
- package/dist/reporter/prioritize-problems.js.map +1 -0
- package/dist/reporter/statistics.d.ts +17 -0
- package/dist/reporter/statistics.d.ts.map +1 -0
- package/dist/reporter/statistics.js +52 -0
- package/dist/reporter/statistics.js.map +1 -0
- package/dist/reporter/summary.d.ts +10 -0
- package/dist/reporter/summary.d.ts.map +1 -0
- package/dist/reporter/summary.js +48 -0
- package/dist/reporter/summary.js.map +1 -0
- package/dist/scope.d.ts +26 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +110 -0
- package/dist/scope.js.map +1 -0
- package/dist/types/assertions.d.ts +56 -0
- package/dist/types/assertions.d.ts.map +1 -0
- package/dist/types/assertions.js +2 -0
- package/dist/types/assertions.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/problems.d.ts +21 -0
- package/dist/types/problems.d.ts.map +1 -0
- package/dist/types/problems.js +2 -0
- package/dist/types/problems.js.map +1 -0
- package/dist/types/reporting.d.ts +23 -0
- package/dist/types/reporting.d.ts.map +1 -0
- package/dist/types/reporting.js +2 -0
- package/dist/types/reporting.js.map +1 -0
- package/dist/types/rules.d.ts +43 -0
- package/dist/types/rules.d.ts.map +1 -0
- package/dist/types/rules.js +2 -0
- package/dist/types/rules.js.map +1 -0
- package/dist/types/validation.d.ts +6 -0
- package/dist/types/validation.d.ts.map +1 -0
- package/dist/types/validation.js +2 -0
- package/dist/types/validation.js.map +1 -0
- package/dist/types.d.ts +109 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +31 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +154 -0
- package/dist/validate.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
async function execute(rule, file, { content }) {
|
|
2
|
+
const problems = [];
|
|
3
|
+
const options = rule.assertions['semantic-line-breaks'];
|
|
4
|
+
const lines = content.split('\n');
|
|
5
|
+
let inCodeBlock = false;
|
|
6
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
7
|
+
const lineText = lines[lineIndex];
|
|
8
|
+
const lineNumber = lineIndex + 1;
|
|
9
|
+
if (lineText.startsWith('```')) {
|
|
10
|
+
inCodeBlock = !inCodeBlock;
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
if (options.ignoreCodeBlocks && inCodeBlock)
|
|
14
|
+
continue;
|
|
15
|
+
if (options.ignoreTables && lineText.includes('|'))
|
|
16
|
+
continue;
|
|
17
|
+
if (lineText.trim() === '' ||
|
|
18
|
+
lineText.startsWith('#') ||
|
|
19
|
+
lineText.startsWith('-') ||
|
|
20
|
+
lineText.startsWith('*') ||
|
|
21
|
+
/^\s*\d+\.\s/.test(lineText) ||
|
|
22
|
+
/^\s*[a-zA-Z]\.\s/.test(lineText) ||
|
|
23
|
+
/^\s*[-*]\s+[a-zA-Z]\.\s/.test(lineText)) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (options.mode === 'sentence') {
|
|
27
|
+
const sentenceCount = countActualSentences(lineText);
|
|
28
|
+
if (sentenceCount > 1) {
|
|
29
|
+
problems.push({
|
|
30
|
+
file,
|
|
31
|
+
line: lineNumber,
|
|
32
|
+
column: 1,
|
|
33
|
+
text: lineText,
|
|
34
|
+
match: lineText,
|
|
35
|
+
ruleName: rule.name,
|
|
36
|
+
severity: rule.severity,
|
|
37
|
+
message: formatMessage(rule.message, options.mode),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return problems;
|
|
43
|
+
}
|
|
44
|
+
async function fix(rule, file, { content }) {
|
|
45
|
+
const fixes = [];
|
|
46
|
+
const lines = content.split('\n');
|
|
47
|
+
const newLines = [...lines];
|
|
48
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
49
|
+
const lineText = lines[lineIndex];
|
|
50
|
+
const lineNumber = lineIndex + 1;
|
|
51
|
+
if (lineText.trim() === '' || lineText.startsWith('#'))
|
|
52
|
+
continue;
|
|
53
|
+
const sentenceCount = countActualSentences(lineText);
|
|
54
|
+
if (sentenceCount <= 1)
|
|
55
|
+
continue;
|
|
56
|
+
const splitResult = splitAtSentenceBoundaries(lineText, rule);
|
|
57
|
+
if (splitResult.length <= 1)
|
|
58
|
+
continue;
|
|
59
|
+
const indentation = calculateContinuationIndent(lineText);
|
|
60
|
+
const [firstLine, ...continuationLines] = splitResult;
|
|
61
|
+
const newLinesForThisLine = [
|
|
62
|
+
firstLine,
|
|
63
|
+
...continuationLines.map((line) => indentation + line.trim()),
|
|
64
|
+
];
|
|
65
|
+
const newText = newLinesForThisLine.join('\n');
|
|
66
|
+
fixes.push({
|
|
67
|
+
file,
|
|
68
|
+
line: lineNumber,
|
|
69
|
+
column: 1,
|
|
70
|
+
oldText: lineText,
|
|
71
|
+
newText,
|
|
72
|
+
ruleName: rule.name,
|
|
73
|
+
description: 'Split multiple sentences into separate lines with semantic line breaks',
|
|
74
|
+
});
|
|
75
|
+
newLines.splice(lineIndex, 1, ...newLinesForThisLine);
|
|
76
|
+
lineIndex += newLinesForThisLine.length - 1;
|
|
77
|
+
}
|
|
78
|
+
return fixes;
|
|
79
|
+
}
|
|
80
|
+
function countActualSentences(text) {
|
|
81
|
+
// Remove common non-sentence elements
|
|
82
|
+
let cleanText = text
|
|
83
|
+
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') // Links
|
|
84
|
+
.replace(/`([^`]+)`/g, '$1') // Code spans
|
|
85
|
+
.replace(/\b\w+\.(md|html|css|js|ts|json|yaml|yml|txt|pdf|png|jpg|svg|xml)\b/gi, 'FILE') // File extensions
|
|
86
|
+
.replace(/https?:\/\/[^\s]+/gi, 'URL') // URLs
|
|
87
|
+
.replace(/\b(e\.g\.|i\.e\.|etc\.|vs\.|Mr\.|Mrs\.|Dr\.|Prof\.)\s/gi, 'ABBREV ') // Abbreviations
|
|
88
|
+
.replace(/\b\d+\.\d+(\.\d+)*\b/g, 'VERSION') // Version numbers
|
|
89
|
+
.replace(/\b\d+\.\d+\b/g, 'NUMBER'); // Decimal numbers
|
|
90
|
+
const sentenceEnds = cleanText.match(/[.!?]+(\s+[A-Z\[`"']|$)/g);
|
|
91
|
+
return sentenceEnds ? sentenceEnds.length : 0;
|
|
92
|
+
}
|
|
93
|
+
function splitAtSentenceBoundaries(text, _rule) {
|
|
94
|
+
const sentencePattern = /([.!?])\s+([A-Z\[`"'])/g;
|
|
95
|
+
const parts = [];
|
|
96
|
+
let lastIndex = 0;
|
|
97
|
+
let match;
|
|
98
|
+
while ((match = sentencePattern.exec(text)) !== null) {
|
|
99
|
+
const endOfSentence = match.index + 1;
|
|
100
|
+
// Skip if this looks like a list marker (e.g., "1. Item")
|
|
101
|
+
const beforePunctuation = text.substring(0, match.index);
|
|
102
|
+
if (/^\s*(?:\d+|[a-zA-Z])$/.test(beforePunctuation.trim())) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
// Skip if this is an abbreviation (e.g., i.e., etc., vs., titles)
|
|
106
|
+
// Look at the few characters before the period to check for abbreviations
|
|
107
|
+
const textBeforePeriod = text.substring(Math.max(0, match.index - 10), match.index + 1);
|
|
108
|
+
const abbrevMatch = textBeforePeriod.match(/\b(e\.g|i\.e|etc|vs|mr|mrs|dr|prof|ltd|inc|corp)\.$/i);
|
|
109
|
+
if (abbrevMatch) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const sentence = text.substring(lastIndex, endOfSentence);
|
|
113
|
+
if (sentence.trim()) {
|
|
114
|
+
parts.push(sentence);
|
|
115
|
+
}
|
|
116
|
+
lastIndex = match.index + 2;
|
|
117
|
+
}
|
|
118
|
+
const remaining = text.substring(lastIndex);
|
|
119
|
+
if (remaining.trim()) {
|
|
120
|
+
parts.push(remaining);
|
|
121
|
+
}
|
|
122
|
+
return parts.length > 1 ? parts : [text];
|
|
123
|
+
}
|
|
124
|
+
function calculateContinuationIndent(line) {
|
|
125
|
+
const leadingWhitespace = line.match(/^(\s*)/)?.[1] || '';
|
|
126
|
+
// Check for list markers and return appropriate indentation
|
|
127
|
+
const listMarkers = [
|
|
128
|
+
/^(\s*[-*]\s)/, // Bullet points
|
|
129
|
+
/^(\s*\d+\.\s)/, // Numbered lists
|
|
130
|
+
/^(\s*[a-zA-Z]\.\s)/, // Letter lists
|
|
131
|
+
];
|
|
132
|
+
for (const pattern of listMarkers) {
|
|
133
|
+
const match = line.match(pattern);
|
|
134
|
+
if (match) {
|
|
135
|
+
return ' '.repeat(match[1].length);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return leadingWhitespace;
|
|
139
|
+
}
|
|
140
|
+
function formatMessage(template, ...args) {
|
|
141
|
+
let result = template;
|
|
142
|
+
for (let i = 0; i < args.length; i++) {
|
|
143
|
+
result = result.replace('%s', args[i]);
|
|
144
|
+
}
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
export const semanticLineBreaks = {
|
|
148
|
+
id: 'semantic-line-breaks',
|
|
149
|
+
execute,
|
|
150
|
+
fix,
|
|
151
|
+
};
|
|
152
|
+
//# sourceMappingURL=semantic-line-breaks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic-line-breaks.js","sourceRoot":"","sources":["../../src/assertions/semantic-line-breaks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swap.d.ts","sourceRoot":"","sources":["../../src/assertions/swap.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAW,MAAM,YAAY,CAAC;AA4C1D,eAAO,MAAM,IAAI,EAAE,cAGlB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
async function execute(rule, file, { content }) {
|
|
2
|
+
const problems = [];
|
|
3
|
+
const assertion = rule.assertions.swap;
|
|
4
|
+
if (content === undefined) {
|
|
5
|
+
// Gracefully handle empty or unreadable files
|
|
6
|
+
return problems;
|
|
7
|
+
}
|
|
8
|
+
const pairs = assertion.pairs || {};
|
|
9
|
+
for (const [from, to] of Object.entries(pairs)) {
|
|
10
|
+
const escaped = assertion.keysAreRegex
|
|
11
|
+
? from
|
|
12
|
+
: String(from).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
13
|
+
const pattern = assertion.wordBoundary ? `\\b${escaped}\\b` : escaped;
|
|
14
|
+
const flags = assertion.ignoreCase ? 'gi' : 'g';
|
|
15
|
+
const regex = new RegExp(pattern, flags);
|
|
16
|
+
let match;
|
|
17
|
+
while ((match = regex.exec(content)) !== null) {
|
|
18
|
+
const before = content.slice(0, match.index);
|
|
19
|
+
const lineNumber = before.split('\n').length;
|
|
20
|
+
const column = match.index - before.lastIndexOf('\n');
|
|
21
|
+
problems.push({
|
|
22
|
+
file,
|
|
23
|
+
line: lineNumber,
|
|
24
|
+
column,
|
|
25
|
+
text: content.split('\n')[lineNumber - 1] || '',
|
|
26
|
+
match: match[0],
|
|
27
|
+
ruleName: rule.name,
|
|
28
|
+
severity: rule.severity,
|
|
29
|
+
message: rule.message.replace('%s', String(to)).replace('%s', String(from)),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return problems;
|
|
34
|
+
}
|
|
35
|
+
export const swap = {
|
|
36
|
+
id: 'swap',
|
|
37
|
+
execute,
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=swap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swap.js","sourceRoot":"","sources":["../../src/assertions/swap.ts"],"names":[],"mappings":"AAGA,KAAK,UAAU,OAAO,CACpB,IAAoB,EACpB,IAAY,EACZ,EAAE,OAAO,EAAW;IAEpB,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,IAAqB,CAAC;IAExD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,8CAA8C;QAC9C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,SAAS,CAAC,YAAY;YACpC,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,OAAO,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC;QACtE,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACzC,IAAI,KAA6B,CAAC;QAClC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YAC7C,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;YAC7C,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACtD,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI;gBACJ,IAAI,EAAE,UAAU;gBAChB,MAAM;gBACN,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,IAAI,EAAE;gBAC/C,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;gBACf,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;aAC5E,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,MAAM,IAAI,GAAmB;IAClC,EAAE,EAAE,MAAM;IACV,OAAO;CACR,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { NormalizedRule } from '../types/index.js';
|
|
2
|
+
export declare function shouldProcessFile(file: string, rule: NormalizedRule): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Check if a line should be excluded based on line exceptions.
|
|
5
|
+
* Returns true if the line should be skipped.
|
|
6
|
+
*/
|
|
7
|
+
export declare function shouldSkipLine(lineContent: string, rule: NormalizedRule): boolean;
|
|
8
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/assertions/utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAsBxD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CA+B7E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAOjF"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import picomatch from 'picomatch';
|
|
3
|
+
/**
|
|
4
|
+
* Check if a file matches a pattern using multiple strategies
|
|
5
|
+
*/
|
|
6
|
+
function matchesFilePattern(pattern, basename, normalizedPath) {
|
|
7
|
+
// Try basename match first (for simple patterns like "*.md")
|
|
8
|
+
if (picomatch.isMatch(basename, pattern))
|
|
9
|
+
return true;
|
|
10
|
+
// Try full relative path match
|
|
11
|
+
if (picomatch.isMatch(normalizedPath, pattern))
|
|
12
|
+
return true;
|
|
13
|
+
// Try matching path segments for patterns like "docs/**" or "**/config/*.md"
|
|
14
|
+
const pathParts = normalizedPath.split('/');
|
|
15
|
+
for (let i = 0; i < pathParts.length; i++) {
|
|
16
|
+
const suffix = pathParts.slice(i).join('/');
|
|
17
|
+
if (picomatch.isMatch(suffix, pattern))
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
export function shouldProcessFile(file, rule) {
|
|
23
|
+
const basename = path.basename(file);
|
|
24
|
+
const relativePath = path.relative(process.cwd(), file);
|
|
25
|
+
const normalizedPath = relativePath.replace(/\\/g, '/');
|
|
26
|
+
// Check excludes with full path support
|
|
27
|
+
if (rule.excludes &&
|
|
28
|
+
rule.excludes.some((pattern) => matchesFilePattern(pattern, basename, normalizedPath))) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
// Check appliesTo with full path support
|
|
32
|
+
if (rule.appliesTo &&
|
|
33
|
+
!rule.appliesTo.some((pattern) => matchesFilePattern(pattern, basename, normalizedPath))) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
// Check file exceptions
|
|
37
|
+
if (rule.exceptions?.files) {
|
|
38
|
+
for (const pattern of rule.exceptions.files) {
|
|
39
|
+
if (matchesFilePattern(pattern, basename, normalizedPath)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Check if a line should be excluded based on line exceptions.
|
|
48
|
+
* Returns true if the line should be skipped.
|
|
49
|
+
*/
|
|
50
|
+
export function shouldSkipLine(lineContent, rule) {
|
|
51
|
+
if (!rule.exceptions?.lines) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
// Check if any exception pattern matches the line content (fragment matching)
|
|
55
|
+
return rule.exceptions.lines.some((exceptionPattern) => lineContent.includes(exceptionPattern));
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/assertions/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,SAAS,MAAM,WAAW,CAAC;AAIlC;;GAEG;AACH,SAAS,kBAAkB,CAAC,OAAe,EAAE,QAAgB,EAAE,cAAsB;IACnF,6DAA6D;IAC7D,IAAI,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtD,+BAA+B;IAC/B,IAAI,SAAS,CAAC,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAE5D,6EAA6E;IAC7E,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5C,IAAI,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;IACtD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,IAAoB;IAClE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;IACxD,MAAM,cAAc,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAExD,wCAAwC;IACxC,IACE,IAAI,CAAC,QAAQ;QACb,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC,EACtF,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,yCAAyC;IACzC,IACE,IAAI,CAAC,SAAS;QACd,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC,EACxF,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,wBAAwB;IACxB,IAAI,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC;QAC3B,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YAC5C,IAAI,kBAAkB,CAAC,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC,EAAE,CAAC;gBAC1D,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,IAAoB;IACtE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,8EAA8E;IAC9E,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,gBAAgB,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAClG,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import yargs from 'yargs';
|
|
3
|
+
import { hideBin } from 'yargs/helpers';
|
|
4
|
+
import { red } from 'colorette';
|
|
5
|
+
import { validateCommand } from './commands/validate.js';
|
|
6
|
+
import { runCommand } from './commands/run.js';
|
|
7
|
+
function createYargsInterface() {
|
|
8
|
+
return yargs(hideBin(process.argv))
|
|
9
|
+
.scriptName('recheck')
|
|
10
|
+
.usage('$0 <command> [options]')
|
|
11
|
+
.command('validate', 'Validate recheck configuration file', (yargs) => {
|
|
12
|
+
return yargs.option('config', {
|
|
13
|
+
type: 'string',
|
|
14
|
+
describe: 'Path to configuration file',
|
|
15
|
+
alias: 'c',
|
|
16
|
+
});
|
|
17
|
+
}, async (argv) => {
|
|
18
|
+
const exitCode = await validateCommand(argv);
|
|
19
|
+
process.exit(exitCode);
|
|
20
|
+
})
|
|
21
|
+
.command('run [path]', 'Run recheck on files', (yargs) => {
|
|
22
|
+
return yargs
|
|
23
|
+
.positional('path', {
|
|
24
|
+
type: 'string',
|
|
25
|
+
default: '.',
|
|
26
|
+
describe: 'Path to scan (default: current directory)',
|
|
27
|
+
})
|
|
28
|
+
.option('config', {
|
|
29
|
+
type: 'string',
|
|
30
|
+
describe: 'Path to configuration file',
|
|
31
|
+
alias: 'c',
|
|
32
|
+
})
|
|
33
|
+
.option('output', {
|
|
34
|
+
type: 'string',
|
|
35
|
+
choices: ['table', 'json', 'sarif', 'github-actions'],
|
|
36
|
+
default: 'table',
|
|
37
|
+
describe: 'Output format',
|
|
38
|
+
})
|
|
39
|
+
.option('output-path', {
|
|
40
|
+
type: 'string',
|
|
41
|
+
describe: 'Write output to this file (works with all output formats)',
|
|
42
|
+
})
|
|
43
|
+
.option('severity', {
|
|
44
|
+
type: 'string',
|
|
45
|
+
choices: ['off', 'info', 'warn', 'warning', 'error'],
|
|
46
|
+
describe: 'Minimum severity to report',
|
|
47
|
+
})
|
|
48
|
+
.option('tags', {
|
|
49
|
+
type: 'array',
|
|
50
|
+
describe: 'Filter by tags',
|
|
51
|
+
})
|
|
52
|
+
.option('stats', {
|
|
53
|
+
type: 'boolean',
|
|
54
|
+
describe: 'Show summary statistics',
|
|
55
|
+
alias: 's',
|
|
56
|
+
})
|
|
57
|
+
.option('fix', {
|
|
58
|
+
type: 'boolean',
|
|
59
|
+
describe: 'Auto-fix issues (only safe rules)',
|
|
60
|
+
alias: 'f',
|
|
61
|
+
})
|
|
62
|
+
.option('annotations-limit', {
|
|
63
|
+
type: 'number',
|
|
64
|
+
describe: 'Limit number of CI annotations (errors prioritized). Does not affect CLI output',
|
|
65
|
+
default: 20,
|
|
66
|
+
})
|
|
67
|
+
.option('summary', {
|
|
68
|
+
type: 'string',
|
|
69
|
+
choices: ['json', 'text'],
|
|
70
|
+
describe: 'Emit a run summary in the chosen format to stdout or to the file given by --summary-path',
|
|
71
|
+
})
|
|
72
|
+
.option('summary-path', {
|
|
73
|
+
type: 'string',
|
|
74
|
+
describe: 'Write the summary to this file (used with --summary)',
|
|
75
|
+
})
|
|
76
|
+
.option('changed-only', {
|
|
77
|
+
type: 'boolean',
|
|
78
|
+
describe: 'Limit scanning to files listed via --changed-list or piped on stdin',
|
|
79
|
+
default: false,
|
|
80
|
+
})
|
|
81
|
+
.option('changed-list', {
|
|
82
|
+
type: 'string',
|
|
83
|
+
describe: 'Path to a newline-separated file list of changed files (used with --changed-only)',
|
|
84
|
+
})
|
|
85
|
+
.option('verbose', {
|
|
86
|
+
type: 'boolean',
|
|
87
|
+
describe: 'Show verbose output',
|
|
88
|
+
default: false,
|
|
89
|
+
});
|
|
90
|
+
}, async (argv) => {
|
|
91
|
+
const exitCode = await runCommand(argv.path || '.', {
|
|
92
|
+
config: argv.config,
|
|
93
|
+
output: argv.output,
|
|
94
|
+
outputPath: argv['output-path'],
|
|
95
|
+
severity: argv.severity,
|
|
96
|
+
tags: argv.tags,
|
|
97
|
+
stats: argv.stats,
|
|
98
|
+
fix: argv.fix,
|
|
99
|
+
annotationsLimit: argv['annotations-limit'],
|
|
100
|
+
summary: argv.summary,
|
|
101
|
+
summaryPath: argv['summary-path'],
|
|
102
|
+
changedOnly: argv['changed-only'],
|
|
103
|
+
changedListPath: argv['changed-list'],
|
|
104
|
+
verbose: argv.verbose,
|
|
105
|
+
});
|
|
106
|
+
process.exit(exitCode);
|
|
107
|
+
})
|
|
108
|
+
.demandCommand(1, 'You must specify a command')
|
|
109
|
+
.help()
|
|
110
|
+
.alias('help', 'h')
|
|
111
|
+
.version()
|
|
112
|
+
.alias('version', 'v');
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Run the CLI with the provided arguments
|
|
116
|
+
*/
|
|
117
|
+
async function runCLI() {
|
|
118
|
+
const cli = createYargsInterface();
|
|
119
|
+
await cli.parseAsync();
|
|
120
|
+
}
|
|
121
|
+
runCLI().catch((error) => {
|
|
122
|
+
console.error(red(`š„ Fatal error: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
123
|
+
process.exit(1);
|
|
124
|
+
});
|
|
125
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAEhC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,SAAS,oBAAoB;IAC3B,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;SAChC,UAAU,CAAC,SAAS,CAAC;SACrB,KAAK,CAAC,wBAAwB,CAAC;SAC/B,OAAO,CACN,UAAU,EACV,qCAAqC,EACrC,CAAC,KAAK,EAAE,EAAE;QACR,OAAO,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE;YAC5B,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,4BAA4B;YACtC,KAAK,EAAE,GAAG;SACX,CAAC,CAAC;IACL,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC,CACF;SACA,OAAO,CACN,YAAY,EACZ,sBAAsB,EACtB,CAAC,KAAK,EAAE,EAAE;QACR,OAAO,KAAK;aACT,UAAU,CAAC,MAAM,EAAE;YAClB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,GAAG;YACZ,QAAQ,EAAE,2CAA2C;SACtD,CAAC;aACD,MAAM,CAAC,QAAQ,EAAE;YAChB,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,4BAA4B;YACtC,KAAK,EAAE,GAAG;SACX,CAAC;aACD,MAAM,CAAC,QAAQ,EAAE;YAChB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,CAAC;YACrD,OAAO,EAAE,OAAO;YAChB,QAAQ,EAAE,eAAe;SAC1B,CAAC;aACD,MAAM,CAAC,aAAa,EAAE;YACrB,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,2DAA2D;SACtE,CAAC;aACD,MAAM,CAAC,UAAU,EAAE;YAClB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC;YACpD,QAAQ,EAAE,4BAA4B;SACvC,CAAC;aACD,MAAM,CAAC,MAAM,EAAE;YACd,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,gBAAgB;SAC3B,CAAC;aACD,MAAM,CAAC,OAAO,EAAE;YACf,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,yBAAyB;YACnC,KAAK,EAAE,GAAG;SACX,CAAC;aACD,MAAM,CAAC,KAAK,EAAE;YACb,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,mCAAmC;YAC7C,KAAK,EAAE,GAAG;SACX,CAAC;aACD,MAAM,CAAC,mBAAmB,EAAE;YAC3B,IAAI,EAAE,QAAQ;YACd,QAAQ,EACN,iFAAiF;YACnF,OAAO,EAAE,EAAE;SACZ,CAAC;aACD,MAAM,CAAC,SAAS,EAAE;YACjB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;YACzB,QAAQ,EACN,0FAA0F;SAC7F,CAAC;aACD,MAAM,CAAC,cAAc,EAAE;YACtB,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,sDAAsD;SACjE,CAAC;aACD,MAAM,CAAC,cAAc,EAAE;YACtB,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,qEAAqE;YAC/E,OAAO,EAAE,KAAK;SACf,CAAC;aACD,MAAM,CAAC,cAAc,EAAE;YACtB,IAAI,EAAE,QAAQ;YACd,QAAQ,EACN,mFAAmF;SACtF,CAAC;aACD,MAAM,CAAC,SAAS,EAAE;YACjB,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,qBAAqB;YAC/B,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;IACP,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,EAAE;YAClD,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,MAAuD;YACpE,UAAU,EAAE,IAAI,CAAC,aAAa,CAAuB;YACrD,QAAQ,EAAE,IAAI,CAAC,QAAqE;YACpF,IAAI,EAAE,IAAI,CAAC,IAA4B;YACvC,KAAK,EAAE,IAAI,CAAC,KAA4B;YACxC,GAAG,EAAE,IAAI,CAAC,GAA0B;YACpC,gBAAgB,EAAE,IAAI,CAAC,mBAAmB,CAAuB;YACjE,OAAO,EAAE,IAAI,CAAC,OAAsC;YACpD,WAAW,EAAE,IAAI,CAAC,cAAc,CAAuB;YACvD,WAAW,EAAE,IAAI,CAAC,cAAc,CAAwB;YACxD,eAAe,EAAE,IAAI,CAAC,cAAc,CAAuB;YAC3D,OAAO,EAAE,IAAI,CAAC,OAA8B;SAC7C,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC,CACF;SACA,aAAa,CAAC,CAAC,EAAE,4BAA4B,CAAC;SAC9C,IAAI,EAAE;SACN,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC;SAClB,OAAO,EAAE;SACT,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,MAAM;IACnB,MAAM,GAAG,GAAG,oBAAoB,EAAE,CAAC;IACnC,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACvB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAClG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface RunOptions {
|
|
2
|
+
config?: string;
|
|
3
|
+
output?: 'table' | 'json' | 'sarif' | 'github-actions';
|
|
4
|
+
severity?: 'off' | 'info' | 'warn' | 'warning' | 'error';
|
|
5
|
+
tags?: (string | number)[];
|
|
6
|
+
stats?: boolean;
|
|
7
|
+
fix?: boolean;
|
|
8
|
+
annotationsLimit?: number;
|
|
9
|
+
summary?: 'json' | 'text';
|
|
10
|
+
summaryPath?: string;
|
|
11
|
+
changedOnly?: boolean;
|
|
12
|
+
changedListPath?: string;
|
|
13
|
+
outputPath?: string;
|
|
14
|
+
verbose?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Run recheck on files
|
|
18
|
+
*/
|
|
19
|
+
export declare function runCommand(path: string | undefined, options: RunOptions): Promise<number>;
|
|
20
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,gBAAgB,CAAC;IACvD,QAAQ,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACzD,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,YAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA0GzF"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import * as pathModule from 'path';
|
|
2
|
+
import { red, green, yellow, cyan } from 'colorette';
|
|
3
|
+
import { findAndLoadConfig } from '../config/load.js';
|
|
4
|
+
import { applyFilters } from '../core/rule-filters.js';
|
|
5
|
+
import { runRecheck } from '../core/runner.js';
|
|
6
|
+
import { generateReport, generateEmptyReport } from '../reporter/index.js';
|
|
7
|
+
import { buildSummary, printSummary } from '../reporter/summary.js';
|
|
8
|
+
import { discoverMarkdownFiles, loadChangedFiles } from '../core/files.js';
|
|
9
|
+
import { Timer } from '../core/timing.js';
|
|
10
|
+
/**
|
|
11
|
+
* Run recheck on files
|
|
12
|
+
*/
|
|
13
|
+
export async function runCommand(path = '.', options) {
|
|
14
|
+
console.log(cyan(`š Running recheck on: ${path}`));
|
|
15
|
+
const result = await findAndLoadConfig(options.config);
|
|
16
|
+
if (!result.success) {
|
|
17
|
+
console.log(red(`ā Configuration validation failed! Please fix the configuration first.`));
|
|
18
|
+
console.log(red('\nErrors:'));
|
|
19
|
+
for (const error of result.errors) {
|
|
20
|
+
if (error.path) {
|
|
21
|
+
console.log(red(` ⢠${error.path}: ${error.message}`));
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
console.log(red(` ⢠${error.message}`));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return 1;
|
|
28
|
+
}
|
|
29
|
+
console.log(green(`ā
Configuration loaded successfully!`));
|
|
30
|
+
console.log(` Config file: ${result.configPath}`);
|
|
31
|
+
console.log(` Loaded ${result.rules.length} rule(s)`);
|
|
32
|
+
const { filtered: rulesToRun, disabledCount } = applyFilters(result.rules, {
|
|
33
|
+
severity: options.severity,
|
|
34
|
+
tags: options.tags,
|
|
35
|
+
});
|
|
36
|
+
if (disabledCount > 0) {
|
|
37
|
+
console.log(` Disabled ${disabledCount} rule(s) (severity: off)`);
|
|
38
|
+
}
|
|
39
|
+
console.log(cyan(`\nš§ Running ${rulesToRun.length} rule(s)...`));
|
|
40
|
+
const timer = new Timer();
|
|
41
|
+
try {
|
|
42
|
+
let files = await discoverMarkdownFiles(path);
|
|
43
|
+
if (files.length === 0) {
|
|
44
|
+
console.log(yellow(`ā ļø No markdown files found in: ${path}`));
|
|
45
|
+
await emitEmptyReport(options);
|
|
46
|
+
console.log(` Completed in ${timer.elapsedString()}`);
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
console.log(` Found ${files.length} markdown file(s)`);
|
|
50
|
+
// If changed-only, filter to files provided via --changed-list or stdin
|
|
51
|
+
if (options.changedOnly) {
|
|
52
|
+
const changedCandidates = await loadChangedFiles(options.changedListPath);
|
|
53
|
+
if (!changedCandidates || changedCandidates.length === 0) {
|
|
54
|
+
console.log(yellow(' Warning: --changed-only set, but no changed files were provided. Nothing to scan.'));
|
|
55
|
+
await emitEmptyReport(options);
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
58
|
+
const changedSet = new Set(changedCandidates.map((p) => (pathModule.isAbsolute(p) ? p : pathModule.resolve(p))));
|
|
59
|
+
const filtered = files.filter((f) => changedSet.has(pathModule.resolve(f)));
|
|
60
|
+
console.log(` Filtering to ${filtered.length} changed file(s)`);
|
|
61
|
+
if (filtered.length === 0) {
|
|
62
|
+
console.log(yellow(' Warning: No changed markdown files matched.'));
|
|
63
|
+
await emitEmptyReport(options);
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
files = filtered;
|
|
67
|
+
}
|
|
68
|
+
const allProblems = await runRecheck(files, rulesToRun, options);
|
|
69
|
+
await generateReport(allProblems, files.length, {
|
|
70
|
+
format: options.output || 'table',
|
|
71
|
+
showStats: options.stats,
|
|
72
|
+
annotationsLimit: options.annotationsLimit,
|
|
73
|
+
outputPath: options.outputPath,
|
|
74
|
+
});
|
|
75
|
+
if (options.summary) {
|
|
76
|
+
const summary = buildSummary(allProblems, files.length);
|
|
77
|
+
await printSummary(summary, options.summary, options.summaryPath);
|
|
78
|
+
}
|
|
79
|
+
const errorProblems = allProblems.filter((p) => p.severity === 'error');
|
|
80
|
+
if (errorProblems.length > 0) {
|
|
81
|
+
console.log(red(`\nā Found ${errorProblems.length} error(s). Exiting with code 1.`));
|
|
82
|
+
console.log(` Completed in ${timer.elapsedString()}`);
|
|
83
|
+
return 1;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
console.log(green(`\nā
No errors found!`));
|
|
87
|
+
if (allProblems.length > 0) {
|
|
88
|
+
console.log(` Found ${allProblems.length} warning(s) and info message(s).`);
|
|
89
|
+
}
|
|
90
|
+
console.log(` Completed in ${timer.elapsedString()}`);
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
console.error(red(`š„ Error running recheck: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
96
|
+
console.log(` Failed after ${timer.elapsedString()}`);
|
|
97
|
+
return 1;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Emit empty report for cases where no files are found
|
|
102
|
+
*/
|
|
103
|
+
async function emitEmptyReport(options) {
|
|
104
|
+
await generateEmptyReport({
|
|
105
|
+
format: options.output || 'table',
|
|
106
|
+
showStats: options.stats,
|
|
107
|
+
annotationsLimit: options.annotationsLimit,
|
|
108
|
+
outputPath: options.outputPath,
|
|
109
|
+
});
|
|
110
|
+
if (options.summary) {
|
|
111
|
+
const emptySummary = buildSummary([], 0);
|
|
112
|
+
await printSummary(emptySummary, options.summary, options.summaryPath);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CA2C/E"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { red, green, cyan } from 'colorette';
|
|
2
|
+
import { findAndLoadConfig } from '../config/load.js';
|
|
3
|
+
/**
|
|
4
|
+
* Validate recheck configuration file
|
|
5
|
+
*/
|
|
6
|
+
export async function validateCommand(options) {
|
|
7
|
+
console.log(cyan('š Validating recheck configuration...'));
|
|
8
|
+
try {
|
|
9
|
+
const result = await findAndLoadConfig(options.config);
|
|
10
|
+
if (result.success) {
|
|
11
|
+
console.log(green(`ā
Configuration is valid!`));
|
|
12
|
+
if (result.configPath) {
|
|
13
|
+
console.log(` Config file: ${result.configPath}`);
|
|
14
|
+
}
|
|
15
|
+
console.log(` Found ${result.rules.length} rule(s):`);
|
|
16
|
+
for (const rule of result.rules) {
|
|
17
|
+
console.log(` - ${rule.name} (severity: ${rule.severity})`);
|
|
18
|
+
}
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
console.log(red(`ā Configuration validation failed!`));
|
|
23
|
+
if (result.configPath) {
|
|
24
|
+
console.log(` Config file: ${result.configPath}`);
|
|
25
|
+
}
|
|
26
|
+
console.log(red('\nErrors:'));
|
|
27
|
+
for (const error of result.errors) {
|
|
28
|
+
if (error.path) {
|
|
29
|
+
console.log(red(` ⢠${error.path}: ${error.message}`));
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
console.log(red(` ⢠${error.message}`));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return 1;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
console.error(red(`š„ Unexpected error: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
40
|
+
return 1;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAMtD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAwB;IAC5D,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC,CAAC;IAE5D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEvD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;YAEhD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBACtB,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;YACtD,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,MAAM,WAAW,CAAC,CAAC;YACxD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBAChC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,IAAI,eAAe,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;YAChE,CAAC;YAED,OAAO,CAAC,CAAC;QACX,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC,CAAC;YAEvD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBACtB,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;YACtD,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;YAC9B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;oBACf,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBAC3D,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;YAED,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,GAAG,CAAC,wBAAwB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CACxF,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC"}
|