markuplint 5.0.0-rc.1 → 5.0.0-rc.2
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 +24 -0
- package/lib/api/ml-engine.js +1 -1
- package/lib/api/types.d.ts +0 -4
- package/lib/cli/command.js +40 -9
- package/lib/cli/output.d.ts +19 -0
- package/lib/cli/output.js +63 -0
- package/lib/suppressions/downgrade-severity.d.ts +51 -0
- package/lib/suppressions/downgrade-severity.js +102 -0
- package/lib/suppressions/index.d.ts +3 -0
- package/lib/suppressions/index.js +2 -0
- package/lib/suppressions/suppressions-file.js +1 -1
- package/lib/testing-tool/index.js +4 -4
- package/lib/types.d.ts +2 -20
- package/package.json +23 -14
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,30 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [5.0.0-rc.2](https://github.com/markuplint/markuplint/compare/v5.0.0-rc.1...v5.0.0-rc.2) (2026-04-15)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **markuplint:** add default export condition and re-export isFatalError ([55a990a](https://github.com/markuplint/markuplint/commit/55a990affeec62c23a96cf15b42327fcb867e809))
|
|
11
|
+
- **markuplint:** add missing status property to github-reporter test data ([bb7ba62](https://github.com/markuplint/markuplint/commit/bb7ba62e9350c173987f76de2741aaeb3ba0997b))
|
|
12
|
+
|
|
13
|
+
- build!: remove ESLint and replace with oxlint ([1e0a337](https://github.com/markuplint/markuplint/commit/1e0a337707f76b903b16beeeb8c4d4fc0d8fc9e4))
|
|
14
|
+
- feat(markuplint)!: remove deprecated autoLoad option and MLResultInfo_v1 interface ([4eb1d05](https://github.com/markuplint/markuplint/commit/4eb1d05eb2829019cd4073afa153a512b1c4c8fa))
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
- **config-presets:** add document uniqueness rules to html-standard preset ([6ed848b](https://github.com/markuplint/markuplint/commit/6ed848bd800416d1220b9de95ece7a3d752d881f))
|
|
19
|
+
- **markuplint:** add CLI summary output ([4743ba0](https://github.com/markuplint/markuplint/commit/4743ba0be7311288ea2b28fb9345567cf97c1a23))
|
|
20
|
+
- **markuplint:** add suppressions subpath export and editor severity downgrade ([362adef](https://github.com/markuplint/markuplint/commit/362adef1a040c66fec36c01bd8d8fcbe9a66c453))
|
|
21
|
+
- **vscode:** add suppressed message prefix and blame parser tests ([cd80a80](https://github.com/markuplint/markuplint/commit/cd80a802c3bad29a8a1d510d2160a21a6f0a2682))
|
|
22
|
+
|
|
23
|
+
### BREAKING CHANGES
|
|
24
|
+
|
|
25
|
+
- ESLint is no longer used. Use oxlint instead.
|
|
26
|
+
- The autoLoad option has been removed from APIOptions.
|
|
27
|
+
Rules are now always auto-loaded unconditionally.
|
|
28
|
+
The MLResultInfo_v1 interface has also been removed.
|
|
29
|
+
|
|
6
30
|
# [5.0.0-rc.1](https://github.com/markuplint/markuplint/compare/v5.0.0-rc.0...v5.0.0-rc.1) (2026-03-27)
|
|
7
31
|
|
|
8
32
|
### Bug Fixes
|
package/lib/api/ml-engine.js
CHANGED
|
@@ -341,7 +341,7 @@ export class MLEngine extends Emitter {
|
|
|
341
341
|
return pretenders;
|
|
342
342
|
}
|
|
343
343
|
async #resolveRules(plugins, ruleset) {
|
|
344
|
-
const rules = await resolveRules(plugins, ruleset, this.#options?.importPresetRules ?? true
|
|
344
|
+
const rules = await resolveRules(plugins, ruleset, this.#options?.importPresetRules ?? true);
|
|
345
345
|
if (this.#options?.rules) {
|
|
346
346
|
rules.push(...this.#options.rules);
|
|
347
347
|
}
|
package/lib/api/types.d.ts
CHANGED
|
@@ -18,10 +18,6 @@ export type APIOptions = {
|
|
|
18
18
|
readonly rules?: readonly Readonly<AnyMLRule>[];
|
|
19
19
|
readonly importPresetRules?: boolean;
|
|
20
20
|
readonly severity?: SeverityOptions;
|
|
21
|
-
/**
|
|
22
|
-
* @deprecated
|
|
23
|
-
*/
|
|
24
|
-
readonly autoLoad?: boolean;
|
|
25
21
|
};
|
|
26
22
|
/**
|
|
27
23
|
* Event map for the {@link MLEngine}, defining all emitted events and their payload types.
|
package/lib/cli/command.js
CHANGED
|
@@ -7,7 +7,7 @@ import { MLEngine } from '../api/index.js';
|
|
|
7
7
|
import { log } from '../debug.js';
|
|
8
8
|
import { applySuppressions, generateSuppressions, mergeSuppressions, pruneSuppressions, readSuppressionsFile, resolveSuppressionsPath, writeSuppressionsFile, } from '../suppressions/index.js';
|
|
9
9
|
import { outputDryRunDiff } from './dry-run-output.js';
|
|
10
|
-
import { output } from './output.js';
|
|
10
|
+
import { output, outputSummary } from './output.js';
|
|
11
11
|
/**
|
|
12
12
|
* Executes the markuplint linting command against the given files.
|
|
13
13
|
*
|
|
@@ -114,6 +114,11 @@ export async function command(files, options, apiOptions) {
|
|
|
114
114
|
if (!result) {
|
|
115
115
|
continue;
|
|
116
116
|
}
|
|
117
|
+
processedFiles.push(result.filePath);
|
|
118
|
+
filesContent.set(result.filePath, {
|
|
119
|
+
sourceCode: result.sourceCode,
|
|
120
|
+
fixedCode: result.fixedCode,
|
|
121
|
+
});
|
|
117
122
|
// Store engine for scope computation in suppressions
|
|
118
123
|
engines.set(result.filePath, engine);
|
|
119
124
|
// Progressive出力が有効でJSON形式でない場合
|
|
@@ -127,14 +132,6 @@ export async function command(files, options, apiOptions) {
|
|
|
127
132
|
status: 'processed',
|
|
128
133
|
}, options);
|
|
129
134
|
}
|
|
130
|
-
else {
|
|
131
|
-
// 従来の動作:メモリに蓄積
|
|
132
|
-
processedFiles.push(result.filePath);
|
|
133
|
-
filesContent.set(result.filePath, {
|
|
134
|
-
sourceCode: result.sourceCode,
|
|
135
|
-
fixedCode: result.fixedCode,
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
135
|
// Add violations to collector
|
|
139
136
|
collector.pushWithFile(result.filePath, ...result.violations);
|
|
140
137
|
const errorCount = result.violations.filter(v => v.severity === 'error').length;
|
|
@@ -287,6 +284,40 @@ export async function command(files, options, apiOptions) {
|
|
|
287
284
|
}
|
|
288
285
|
}
|
|
289
286
|
}
|
|
287
|
+
let errorCount = 0;
|
|
288
|
+
let warningCount = 0;
|
|
289
|
+
let noticeCount = 0;
|
|
290
|
+
let failedFileCount = 0;
|
|
291
|
+
for (const filePath of processedFiles) {
|
|
292
|
+
const violations = outputViolationsByFile.get(filePath) || [];
|
|
293
|
+
if (violations.length > 0) {
|
|
294
|
+
failedFileCount++;
|
|
295
|
+
}
|
|
296
|
+
for (const violation of violations) {
|
|
297
|
+
switch (violation.severity) {
|
|
298
|
+
case 'error': {
|
|
299
|
+
errorCount++;
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
case 'warning': {
|
|
303
|
+
warningCount++;
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
case 'info': {
|
|
307
|
+
noticeCount++;
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
outputSummary({
|
|
314
|
+
checkedFileCount: processedFiles.length,
|
|
315
|
+
failedFileCount,
|
|
316
|
+
skippedFileCount: skippedFiles.length,
|
|
317
|
+
errorCount,
|
|
318
|
+
warningCount,
|
|
319
|
+
noticeCount,
|
|
320
|
+
}, options);
|
|
290
321
|
// Check if max-warnings limit is exceeded (ESLint compatible)
|
|
291
322
|
if (!hasError && options.maxWarnings >= 0 && totalWarningCount > options.maxWarnings) {
|
|
292
323
|
hasError = true;
|
package/lib/cli/output.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { CLIOptions } from './bootstrap.js';
|
|
2
2
|
import type { MLResultInfo } from '../types.js';
|
|
3
|
+
export interface SummaryInfo {
|
|
4
|
+
readonly checkedFileCount: number;
|
|
5
|
+
readonly failedFileCount: number;
|
|
6
|
+
readonly skippedFileCount: number;
|
|
7
|
+
readonly errorCount: number;
|
|
8
|
+
readonly warningCount: number;
|
|
9
|
+
readonly noticeCount: number;
|
|
10
|
+
}
|
|
3
11
|
/**
|
|
4
12
|
* Writes lint results to stdout or stderr using the reporter selected by `--format`.
|
|
5
13
|
*
|
|
@@ -12,3 +20,14 @@ import type { MLResultInfo } from '../types.js';
|
|
|
12
20
|
* @param options - CLI options that control the output format and color.
|
|
13
21
|
*/
|
|
14
22
|
export declare function output(results: MLResultInfo, options: CLIOptions): void;
|
|
23
|
+
/**
|
|
24
|
+
* Writes an aggregated lint summary after all file outputs have been emitted.
|
|
25
|
+
*
|
|
26
|
+
* Summary output is enabled for the standard and simple formats only.
|
|
27
|
+
* JSON and GitHub formats are left unchanged because they are intended for
|
|
28
|
+
* machine-readable output.
|
|
29
|
+
*
|
|
30
|
+
* @param summary - Aggregated counts across all linted files.
|
|
31
|
+
* @param options - CLI options that control the output format and color.
|
|
32
|
+
*/
|
|
33
|
+
export declare function outputSummary(summary: SummaryInfo, options: CLIOptions): void;
|
package/lib/cli/output.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { font, xterm } from '@markuplint/cli-utils';
|
|
1
2
|
import stripAnsi from 'strip-ansi';
|
|
2
3
|
import { simpleReporter, standardReporter, githubReporter } from '../reporter/index.js';
|
|
4
|
+
const loggerError = font.red;
|
|
5
|
+
const loggerWarning = xterm(208);
|
|
3
6
|
/**
|
|
4
7
|
* Writes lint results to stdout or stderr using the reporter selected by `--format`.
|
|
5
8
|
*
|
|
@@ -43,3 +46,63 @@ export function output(results, options) {
|
|
|
43
46
|
}
|
|
44
47
|
process.stdout.write(msg);
|
|
45
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Writes an aggregated lint summary after all file outputs have been emitted.
|
|
51
|
+
*
|
|
52
|
+
* Summary output is enabled for the standard and simple formats only.
|
|
53
|
+
* JSON and GitHub formats are left unchanged because they are intended for
|
|
54
|
+
* machine-readable output.
|
|
55
|
+
*
|
|
56
|
+
* @param summary - Aggregated counts across all linted files.
|
|
57
|
+
* @param options - CLI options that control the output format and color.
|
|
58
|
+
*/
|
|
59
|
+
export function outputSummary(summary, options) {
|
|
60
|
+
const format = options.format?.toLowerCase() ?? 'standard';
|
|
61
|
+
if (format === 'json' || format === 'github') {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (summary.checkedFileCount === 0 && summary.skippedFileCount === 0) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const problemCount = summary.errorCount + summary.warningCount + summary.noticeCount;
|
|
68
|
+
if (options.problemOnly && problemCount === 0) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const out = createSummaryLines(summary);
|
|
72
|
+
if (out.length === 0) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
let msg = `\n${out.join('\n')}\n`;
|
|
76
|
+
msg = options.color ? msg : stripAnsi(msg);
|
|
77
|
+
if (problemCount > 0) {
|
|
78
|
+
process.stderr.write(msg);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
process.stdout.write(msg);
|
|
82
|
+
}
|
|
83
|
+
function createSummaryLines(summary) {
|
|
84
|
+
const out = [];
|
|
85
|
+
const problemCount = summary.errorCount + summary.warningCount + summary.noticeCount;
|
|
86
|
+
const passedFileCount = summary.checkedFileCount - summary.failedFileCount;
|
|
87
|
+
if (problemCount === 0) {
|
|
88
|
+
out.push(`${font.green('✔')} ${pluralize(summary.checkedFileCount, 'file')} checked, 0 problems`);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
const problemDetail = [
|
|
92
|
+
`${summary.errorCount} error${summary.errorCount === 1 ? '' : 's'}`,
|
|
93
|
+
`${summary.warningCount} warning${summary.warningCount === 1 ? '' : 's'}`,
|
|
94
|
+
summary.noticeCount > 0 ? `${summary.noticeCount} notice${summary.noticeCount === 1 ? '' : 's'}` : null,
|
|
95
|
+
]
|
|
96
|
+
.filter(Boolean)
|
|
97
|
+
.join(', ');
|
|
98
|
+
const logger = summary.errorCount > 0 ? loggerError : loggerWarning;
|
|
99
|
+
out.push(`${logger('✖')} ${problemCount} problem${problemCount === 1 ? '' : 's'} (${problemDetail}) in ${pluralize(summary.checkedFileCount, 'file')}`, `${pluralize(summary.checkedFileCount, 'file')} checked: ${passedFileCount} passed, ${summary.failedFileCount} failed`);
|
|
100
|
+
}
|
|
101
|
+
if (summary.skippedFileCount > 0) {
|
|
102
|
+
out.push(`${font.yellow('⚠')} ${pluralize(summary.skippedFileCount, 'file')} skipped because --max-count was reached`);
|
|
103
|
+
}
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
function pluralize(count, noun) {
|
|
107
|
+
return `${count} ${noun}${count === 1 ? '' : 's'}`;
|
|
108
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Violation } from '@markuplint/ml-config';
|
|
2
|
+
import type { PositionedNode } from './compute-scope.js';
|
|
3
|
+
import type { SuppressionsData } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* @experimental
|
|
6
|
+
* A violation with its severity potentially downgraded by bulk suppression.
|
|
7
|
+
*/
|
|
8
|
+
export type DowngradedViolation = Violation & {
|
|
9
|
+
/**
|
|
10
|
+
* When set, indicates the original severity before suppression downgrade.
|
|
11
|
+
* Absent when the violation was not affected by suppression.
|
|
12
|
+
*/
|
|
13
|
+
readonly originalSeverity?: Violation['severity'];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* @experimental
|
|
17
|
+
* Result of analyzing violations against suppression data for severity downgrade.
|
|
18
|
+
* Used by editor integrations to show suppressed violations as `info` instead of hiding them.
|
|
19
|
+
*/
|
|
20
|
+
export type DowngradeResult = {
|
|
21
|
+
/** All violation indices that should be downgraded to info. */
|
|
22
|
+
readonly withinThreshold: ReadonlySet<number>;
|
|
23
|
+
/**
|
|
24
|
+
* Violation indices where count exceeds the suppressed threshold.
|
|
25
|
+
* These need further analysis (e.g., git blame) to distinguish old vs new.
|
|
26
|
+
*/
|
|
27
|
+
readonly exceedingThreshold: ReadonlyMap<string, readonly number[]>;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* @experimental
|
|
31
|
+
* Analyzes violations against suppression data and returns which should be downgraded.
|
|
32
|
+
*
|
|
33
|
+
* - Within threshold: all violations for that rule → should be downgraded to info
|
|
34
|
+
* - Exceeding threshold: returns violation indices grouped by ruleId for further analysis
|
|
35
|
+
*
|
|
36
|
+
* @param absoluteFilePath - The file being linted
|
|
37
|
+
* @param violations - The violations to analyze
|
|
38
|
+
* @param suppressions - The suppression data
|
|
39
|
+
* @param suppressionsFilePath - Absolute path to the suppressions file
|
|
40
|
+
* @param nodeList - Optional node list for scope-aware filtering
|
|
41
|
+
*/
|
|
42
|
+
export declare function analyzeForDowngrade(absoluteFilePath: string, violations: readonly Violation[], suppressions: SuppressionsData, suppressionsFilePath: string, _nodeList?: readonly PositionedNode[]): DowngradeResult;
|
|
43
|
+
/**
|
|
44
|
+
* @experimental
|
|
45
|
+
* Applies severity downgrade to violations based on downgrade indices.
|
|
46
|
+
*
|
|
47
|
+
* @param violations - Original violations
|
|
48
|
+
* @param downgradeIndices - Set of violation indices to downgrade to info
|
|
49
|
+
* @returns Violations with severity potentially modified
|
|
50
|
+
*/
|
|
51
|
+
export declare function applyDowngrade(violations: readonly Violation[], downgradeIndices: ReadonlySet<number>): readonly DowngradedViolation[];
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { toRelativePath } from './suppressions-file.js';
|
|
2
|
+
/**
|
|
3
|
+
* @experimental
|
|
4
|
+
* Analyzes violations against suppression data and returns which should be downgraded.
|
|
5
|
+
*
|
|
6
|
+
* - Within threshold: all violations for that rule → should be downgraded to info
|
|
7
|
+
* - Exceeding threshold: returns violation indices grouped by ruleId for further analysis
|
|
8
|
+
*
|
|
9
|
+
* @param absoluteFilePath - The file being linted
|
|
10
|
+
* @param violations - The violations to analyze
|
|
11
|
+
* @param suppressions - The suppression data
|
|
12
|
+
* @param suppressionsFilePath - Absolute path to the suppressions file
|
|
13
|
+
* @param nodeList - Optional node list for scope-aware filtering
|
|
14
|
+
*/
|
|
15
|
+
export function analyzeForDowngrade(absoluteFilePath, violations,
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
17
|
+
suppressions, suppressionsFilePath,
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
19
|
+
_nodeList) {
|
|
20
|
+
const relPath = toRelativePath(absoluteFilePath, suppressionsFilePath);
|
|
21
|
+
const fileSuppressions = suppressions[relPath];
|
|
22
|
+
if (!fileSuppressions) {
|
|
23
|
+
return { withinThreshold: new Set(), exceedingThreshold: new Map() };
|
|
24
|
+
}
|
|
25
|
+
const withinThreshold = new Set();
|
|
26
|
+
const exceedingThreshold = new Map();
|
|
27
|
+
// Group error violations by ruleId
|
|
28
|
+
const violationsByRule = new Map();
|
|
29
|
+
for (const [i, v] of violations.entries()) {
|
|
30
|
+
if (v.severity !== 'error') {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const group = violationsByRule.get(v.ruleId) ?? [];
|
|
34
|
+
group.push({ index: i, violation: v });
|
|
35
|
+
violationsByRule.set(v.ruleId, group);
|
|
36
|
+
}
|
|
37
|
+
for (const [ruleId, entry] of Object.entries(fileSuppressions)) {
|
|
38
|
+
const group = violationsByRule.get(ruleId);
|
|
39
|
+
if (!group) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const scopedGroup = filterByScope(group, entry, _nodeList);
|
|
43
|
+
const scopedCount = scopedGroup.length;
|
|
44
|
+
if (scopedCount === 0) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (scopedCount <= entry.count) {
|
|
48
|
+
for (const item of scopedGroup) {
|
|
49
|
+
withinThreshold.add(item.index);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
exceedingThreshold.set(ruleId, scopedGroup.map(item => item.index));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return { withinThreshold, exceedingThreshold };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* @experimental
|
|
60
|
+
* Applies severity downgrade to violations based on downgrade indices.
|
|
61
|
+
*
|
|
62
|
+
* @param violations - Original violations
|
|
63
|
+
* @param downgradeIndices - Set of violation indices to downgrade to info
|
|
64
|
+
* @returns Violations with severity potentially modified
|
|
65
|
+
*/
|
|
66
|
+
export function applyDowngrade(violations,
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
68
|
+
downgradeIndices) {
|
|
69
|
+
const result = [];
|
|
70
|
+
for (const [i, violation] of violations.entries()) {
|
|
71
|
+
if (downgradeIndices.has(i)) {
|
|
72
|
+
result.push({
|
|
73
|
+
...violation,
|
|
74
|
+
severity: 'info',
|
|
75
|
+
originalSeverity: violation.severity,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
result.push(violation);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Filters a group of violations by scope selector if present.
|
|
86
|
+
*/
|
|
87
|
+
function filterByScope(
|
|
88
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
89
|
+
group, entry,
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
91
|
+
_nodeList) {
|
|
92
|
+
if (!entry.scope || !_nodeList) {
|
|
93
|
+
return group;
|
|
94
|
+
}
|
|
95
|
+
// Scope-aware filtering in editor context:
|
|
96
|
+
// When scope is present but we lack full scope matching infrastructure,
|
|
97
|
+
// fall back to file-level filtering (treats all violations as in-scope).
|
|
98
|
+
// This is the safe direction — more violations may be downgraded than intended,
|
|
99
|
+
// but no new violations are hidden.
|
|
100
|
+
// TODO(#3536): Export isViolationInScope from apply-suppressions.ts and reuse here.
|
|
101
|
+
return group;
|
|
102
|
+
}
|
|
@@ -18,3 +18,6 @@ export { generateSuppressions } from './generate-suppressions.js';
|
|
|
18
18
|
export { mergeSuppressions } from './merge-suppressions.js';
|
|
19
19
|
export { pruneSuppressions } from './prune-suppressions.js';
|
|
20
20
|
export { readSuppressionsFile, writeSuppressionsFile, resolveSuppressionsPath, toRelativePath, toAbsolutePath, } from './suppressions-file.js';
|
|
21
|
+
export type { DowngradedViolation, DowngradeResult } from './downgrade-severity.js';
|
|
22
|
+
export { analyzeForDowngrade, applyDowngrade } from './downgrade-severity.js';
|
|
23
|
+
export { isFatalError } from '@markuplint/shared';
|
|
@@ -14,3 +14,5 @@ export { generateSuppressions } from './generate-suppressions.js';
|
|
|
14
14
|
export { mergeSuppressions } from './merge-suppressions.js';
|
|
15
15
|
export { pruneSuppressions } from './prune-suppressions.js';
|
|
16
16
|
export { readSuppressionsFile, writeSuppressionsFile, resolveSuppressionsPath, toRelativePath, toAbsolutePath, } from './suppressions-file.js';
|
|
17
|
+
export { analyzeForDowngrade, applyDowngrade } from './downgrade-severity.js';
|
|
18
|
+
export { isFatalError } from '@markuplint/shared';
|
|
@@ -33,7 +33,7 @@ export async function readSuppressionsFile(filePath) {
|
|
|
33
33
|
return {};
|
|
34
34
|
}
|
|
35
35
|
if (error instanceof SyntaxError) {
|
|
36
|
-
//
|
|
36
|
+
// eslint-disable-next-line unicorn/prefer-type-error -- Not a type error; this is a JSON parse failure
|
|
37
37
|
throw new Error(`Failed to parse suppressions file "${filePath}": ${error.message}`, { cause: error });
|
|
38
38
|
}
|
|
39
39
|
if (isFatalError(error)) {
|
|
@@ -19,7 +19,6 @@ export async function mlTest(sourceCode, config, rules, locale = 'en', fix = fal
|
|
|
19
19
|
locale: locale ?? global.locale,
|
|
20
20
|
fix,
|
|
21
21
|
ignoreExt: true,
|
|
22
|
-
autoLoad: true,
|
|
23
22
|
importPresetRules: !rules,
|
|
24
23
|
});
|
|
25
24
|
const result = results[0];
|
|
@@ -42,8 +41,10 @@ export async function mlTest(sourceCode, config, rules, locale = 'en', fix = fal
|
|
|
42
41
|
* @returns An object containing violations (without ruleId) and the fixed code
|
|
43
42
|
*/
|
|
44
43
|
export async function mlRuleTest(rule, sourceCode,
|
|
45
|
-
|
|
46
|
-
config = { rule: true },
|
|
44
|
+
/* eslint-disable unicorn/no-object-as-default-parameter */
|
|
45
|
+
config = { rule: true },
|
|
46
|
+
/* eslint-enable unicorn/no-object-as-default-parameter */
|
|
47
|
+
fix = false, locale = 'en') {
|
|
47
48
|
if (config.rule === undefined && (config.nodeRule || config.childNodeRule)) {
|
|
48
49
|
config.rule = true;
|
|
49
50
|
}
|
|
@@ -110,7 +111,6 @@ export async function mlTestFile(target, config, rules, locale, fix = false) {
|
|
|
110
111
|
fix,
|
|
111
112
|
ignoreExt: true,
|
|
112
113
|
noSearchConfig: !!config,
|
|
113
|
-
autoLoad: true,
|
|
114
114
|
importPresetRules: !rules,
|
|
115
115
|
});
|
|
116
116
|
const result = results[0];
|
package/lib/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { Violation } from '@markuplint/ml-config';
|
|
2
|
+
import type { FixSummary } from '@markuplint/ml-core';
|
|
3
3
|
/**
|
|
4
4
|
* The result of linting a single file, including violations, source code, and fix results.
|
|
5
5
|
*/
|
|
@@ -12,22 +12,4 @@ export interface MLResultInfo {
|
|
|
12
12
|
/** Fix process summary. Present when fix mode was enabled and fixes were found. */
|
|
13
13
|
readonly fixSummary?: FixSummary;
|
|
14
14
|
}
|
|
15
|
-
/**
|
|
16
|
-
* @deprecated
|
|
17
|
-
*/
|
|
18
|
-
export interface MLResultInfo_v1 {
|
|
19
|
-
results: Violation[];
|
|
20
|
-
filePath: string;
|
|
21
|
-
sourceCode: string;
|
|
22
|
-
fixedCode: string;
|
|
23
|
-
document: Document<RuleConfigValue, PlainData> | null;
|
|
24
|
-
parser: string;
|
|
25
|
-
locale?: string;
|
|
26
|
-
ruleset: Ruleset;
|
|
27
|
-
configSet: {
|
|
28
|
-
config: Config;
|
|
29
|
-
files: string[];
|
|
30
|
-
error: string[];
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
15
|
export { type FixSummary } from '@markuplint/ml-core';
|
package/package.json
CHANGED
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "markuplint",
|
|
3
|
-
"version": "5.0.0-rc.
|
|
3
|
+
"version": "5.0.0-rc.2",
|
|
4
4
|
"description": "An HTML linter for all markup developers",
|
|
5
5
|
"author": "Yusuke Hirao",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"engines": {
|
|
8
8
|
"node": ">=22"
|
|
9
9
|
},
|
|
10
|
-
"repository":
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/markuplint/markuplint.git",
|
|
13
|
+
"directory": "packages/markuplint"
|
|
14
|
+
},
|
|
11
15
|
"type": "module",
|
|
12
16
|
"exports": {
|
|
13
17
|
".": {
|
|
14
18
|
"import": "./lib/index.js",
|
|
15
19
|
"types": "./lib/index.d.ts"
|
|
16
20
|
},
|
|
21
|
+
"./suppressions": {
|
|
22
|
+
"import": "./lib/suppressions/index.js",
|
|
23
|
+
"types": "./lib/suppressions/index.d.ts",
|
|
24
|
+
"default": "./lib/suppressions/index.js"
|
|
25
|
+
},
|
|
17
26
|
"./package.json": "./package.json"
|
|
18
27
|
},
|
|
19
28
|
"typedoc": {
|
|
@@ -26,17 +35,17 @@
|
|
|
26
35
|
"clean": "tsc --build --clean tsconfig.build.json"
|
|
27
36
|
},
|
|
28
37
|
"dependencies": {
|
|
29
|
-
"@markuplint/cli-utils": "5.0.0-rc.
|
|
30
|
-
"@markuplint/file-resolver": "5.0.0-rc.
|
|
31
|
-
"@markuplint/html-parser": "5.0.0-rc.
|
|
32
|
-
"@markuplint/html-spec": "5.0.0-rc.
|
|
33
|
-
"@markuplint/i18n": "5.0.0-rc.
|
|
34
|
-
"@markuplint/ml-ast": "5.0.0-rc.
|
|
35
|
-
"@markuplint/ml-config": "5.0.0-rc.
|
|
36
|
-
"@markuplint/ml-core": "5.0.0-rc.
|
|
37
|
-
"@markuplint/ml-spec": "5.0.0-rc.
|
|
38
|
-
"@markuplint/rules": "5.0.0-rc.
|
|
39
|
-
"@markuplint/shared": "5.0.0-rc.
|
|
38
|
+
"@markuplint/cli-utils": "5.0.0-rc.2",
|
|
39
|
+
"@markuplint/file-resolver": "5.0.0-rc.2",
|
|
40
|
+
"@markuplint/html-parser": "5.0.0-rc.2",
|
|
41
|
+
"@markuplint/html-spec": "5.0.0-rc.2",
|
|
42
|
+
"@markuplint/i18n": "5.0.0-rc.2",
|
|
43
|
+
"@markuplint/ml-ast": "5.0.0-rc.2",
|
|
44
|
+
"@markuplint/ml-config": "5.0.0-rc.2",
|
|
45
|
+
"@markuplint/ml-core": "5.0.0-rc.2",
|
|
46
|
+
"@markuplint/ml-spec": "5.0.0-rc.2",
|
|
47
|
+
"@markuplint/rules": "5.0.0-rc.2",
|
|
48
|
+
"@markuplint/shared": "5.0.0-rc.2",
|
|
40
49
|
"@types/debug": "4.1.13",
|
|
41
50
|
"chokidar": "5.0.0",
|
|
42
51
|
"debug": "4.4.3",
|
|
@@ -46,5 +55,5 @@
|
|
|
46
55
|
"strip-ansi": "7.2.0",
|
|
47
56
|
"type-fest": "5.5.0"
|
|
48
57
|
},
|
|
49
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "e43763858d9234c417053becc73dbd088c1e7ea6"
|
|
50
59
|
}
|