pr-checkmate 1.21.6 → 1.21.8
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/.eslintrc.js +1 -1
- package/cspell.json +5 -5
- package/dist/config/loader.js +10 -0
- package/dist/scripts/commitlint.js +5 -1
- package/dist/scripts/copy-configs.js +0 -1
- package/dist/scripts/dependency-check.js +6 -1
- package/dist/scripts/duplicate-check.js +1 -1
- package/dist/scripts/license-check.js +16 -0
- package/dist/scripts/lint.js +2 -4
- package/dist/scripts/markdown-lint.js +1 -1
- package/dist/scripts/prettier-autoformat.js +1 -1
- package/dist/scripts/security.js +1 -1
- package/dist/scripts/spellcheck.js +17 -3
- package/dist/scripts/typecheck.js +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/resolve-bin.js +46 -0
- package/eslint.config.mjs +5 -5
- package/package.json +2 -3
- package/src/config/.eslintrc.js +1 -1
- package/src/config/cspell.json +5 -5
- package/src/config/eslint.config.mjs +5 -5
- package/.eslintignore +0 -72
- package/src/config/.eslintignore +0 -72
package/.eslintrc.js
CHANGED
|
@@ -21,7 +21,7 @@ function loadUserConfig() {
|
|
|
21
21
|
if (fs.existsSync(configPath)) {
|
|
22
22
|
try {
|
|
23
23
|
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
24
|
-
console.
|
|
24
|
+
console.error(`[ESLint]: ✅ Loaded config from: ${configPath}`);
|
|
25
25
|
return config;
|
|
26
26
|
} catch (err) {
|
|
27
27
|
console.warn(`[ESLint]: ⚠️ Failed to parse ${configPath}:`, err.message);
|
package/cspell.json
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"version": "0.2",
|
|
3
3
|
"language": "en,ru,uk,he,fr,es",
|
|
4
4
|
"import": [
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
5
|
+
"@cspell/dict-ru_ru/cspell-ext.json",
|
|
6
|
+
"@cspell/dict-uk-ua/cspell-ext.json",
|
|
7
|
+
"@cspell/dict-he/cspell-ext.json",
|
|
8
|
+
"@cspell/dict-fr-fr/cspell-ext.json",
|
|
9
|
+
"@cspell/dict-es-es/cspell-ext.json"
|
|
10
10
|
],
|
|
11
11
|
"words": [
|
|
12
12
|
"ACMR",
|
package/dist/config/loader.js
CHANGED
|
@@ -59,6 +59,16 @@ function mergeWithDefaults(userConfig) {
|
|
|
59
59
|
prBody: { ...defaults.prBody, ...userConfig.prBody },
|
|
60
60
|
duplicate: { ...defaults.duplicate, ...userConfig.duplicate },
|
|
61
61
|
commitlint: { ...defaults.commitlint, ...userConfig.commitlint },
|
|
62
|
+
licenseCheck: {
|
|
63
|
+
allowPackages: [
|
|
64
|
+
...(defaults.licenseCheck?.allowPackages || []),
|
|
65
|
+
...(userConfig.licenseCheck?.allowPackages || []),
|
|
66
|
+
],
|
|
67
|
+
allowLicenses: [
|
|
68
|
+
...(defaults.licenseCheck?.allowLicenses || []),
|
|
69
|
+
...(userConfig.licenseCheck?.allowLicenses || []),
|
|
70
|
+
],
|
|
71
|
+
},
|
|
62
72
|
};
|
|
63
73
|
}
|
|
64
74
|
/**
|
|
@@ -39,6 +39,10 @@ const DEFAULT_TYPES = [
|
|
|
39
39
|
];
|
|
40
40
|
function buildTempConfig(types) {
|
|
41
41
|
const config = {
|
|
42
|
+
// Resolve the config package to its real entry point via Node module
|
|
43
|
+
// resolution. It works regardless of npm hoisting in the client project and
|
|
44
|
+
// regardless of the package's internal layout (e.g. lib/index.js vs index.js)
|
|
45
|
+
// or exports map — unlike hardcoding a subpath.
|
|
42
46
|
extends: [require.resolve('@commitlint/config-conventional')],
|
|
43
47
|
rules: {
|
|
44
48
|
'type-enum': [2, 'always', types],
|
|
@@ -74,7 +78,7 @@ async function runCommitlint() {
|
|
|
74
78
|
return;
|
|
75
79
|
}
|
|
76
80
|
utils_1.logger.info('[runCommitlint]: 📝 Running commitlint...');
|
|
77
|
-
const commitlintBin =
|
|
81
|
+
const commitlintBin = (0, utils_1.resolvePackageBin)('@commitlint/cli', 'cli.js');
|
|
78
82
|
const hasLocal = (0, config_1.hasLocalConfig)(LOCAL_CONFIG_FILES);
|
|
79
83
|
let tempConfigFile = null;
|
|
80
84
|
const { from, to } = await getCommitRange();
|
|
@@ -11,7 +11,6 @@ const configFiles = [
|
|
|
11
11
|
{ source: 'src/config/eslint.config.mjs', dest: 'eslint.config.mjs' },
|
|
12
12
|
{ source: 'src/config/.eslintrc.js', dest: '.eslintrc.js' },
|
|
13
13
|
{ source: 'src/config/.prettierrc', dest: '.prettierrc' },
|
|
14
|
-
{ source: 'src/config/.eslintignore', dest: '.eslintignore' },
|
|
15
14
|
{ source: 'src/config/cspell.json', dest: 'cspell.json' },
|
|
16
15
|
{ source: 'tsconfig.json', dest: 'tsconfig.json' },
|
|
17
16
|
{ source: 'src/config/pr-checkmate-workflow.yml', dest: 'dist/config/pr-checkmate-workflow.yml' },
|
|
@@ -30,9 +30,14 @@ async function runDependencyCheck() {
|
|
|
30
30
|
throw err;
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
+
// Tools loaded by depcheck (e.g. eslint configs) may print to stdout ahead of
|
|
34
|
+
// the JSON, so slice from the first "{" to the last "}" before parsing.
|
|
35
|
+
const start = stdout.indexOf('{');
|
|
36
|
+
const end = stdout.lastIndexOf('}');
|
|
37
|
+
const json = start !== -1 && end !== -1 ? stdout.slice(start, end + 1) : stdout;
|
|
33
38
|
let result;
|
|
34
39
|
try {
|
|
35
|
-
result = JSON.parse(
|
|
40
|
+
result = JSON.parse(json);
|
|
36
41
|
}
|
|
37
42
|
catch {
|
|
38
43
|
utils_1.logger.error('[runDependencyCheck]: ❌ Failed to parse depcheck output');
|
|
@@ -32,7 +32,7 @@ async function runDuplicateCheck() {
|
|
|
32
32
|
// Fall back to src/ or project root when not in delta mode
|
|
33
33
|
const srcPath = node_path_1.default.join(projectRoot, 'src');
|
|
34
34
|
const targetPaths = changedFiles ?? (node_fs_1.default.existsSync(srcPath) ? [srcPath] : [projectRoot]);
|
|
35
|
-
const jscpdBin =
|
|
35
|
+
const jscpdBin = (0, utils_1.resolvePackageBin)('jscpd', 'bin/jscpd');
|
|
36
36
|
try {
|
|
37
37
|
const result = await (0, execa_1.execa)(process.execPath, [
|
|
38
38
|
jscpdBin,
|
|
@@ -6,11 +6,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.runLicenseCheck = runLicenseCheck;
|
|
7
7
|
const execa_1 = require("execa");
|
|
8
8
|
const utils_1 = require("../utils");
|
|
9
|
+
const loader_1 = require("../config/loader");
|
|
9
10
|
const node_path_1 = __importDefault(require("node:path"));
|
|
10
11
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
11
12
|
const FORBIDDEN_LICENSES = ['GPL-2.0', 'GPL-3.0', 'AGPL-3.0', 'LGPL-2.0', 'LGPL-2.1', 'LGPL-3.0'];
|
|
13
|
+
/**
|
|
14
|
+
* Strip the trailing "@version" from a license-checker key to get the bare
|
|
15
|
+
* package name. Handles scoped packages, e.g. "@cspell/dict-ru_ru@2.3.2" → "@cspell/dict-ru_ru".
|
|
16
|
+
*/
|
|
17
|
+
function bareName(pkgKey) {
|
|
18
|
+
const at = pkgKey.lastIndexOf('@');
|
|
19
|
+
return at > 0 ? pkgKey.slice(0, at) : pkgKey;
|
|
20
|
+
}
|
|
12
21
|
async function runLicenseCheck() {
|
|
13
22
|
utils_1.logger.info('[runLicenseCheck]: Checking dependency licenses...');
|
|
23
|
+
const cfg = (0, loader_1.loadProjectConfig)();
|
|
24
|
+
const allowPackages = new Set(cfg.licenseCheck?.allowPackages ?? []);
|
|
25
|
+
const allowLicenses = cfg.licenseCheck?.allowLicenses ?? [];
|
|
14
26
|
if (!node_fs_1.default.existsSync(node_path_1.default.join(process.cwd(), 'package.json'))) {
|
|
15
27
|
utils_1.logger.warn('[runLicenseCheck]: ⚠️ No package.json found, skipping');
|
|
16
28
|
return;
|
|
@@ -22,8 +34,12 @@ async function runLicenseCheck() {
|
|
|
22
34
|
const licenses = JSON.parse(stdout);
|
|
23
35
|
const violations = [];
|
|
24
36
|
for (const [pkg, info] of Object.entries(licenses)) {
|
|
37
|
+
if (allowPackages.has(bareName(pkg)))
|
|
38
|
+
continue;
|
|
25
39
|
const raw = info.licenses ?? '';
|
|
26
40
|
const license = Array.isArray(raw) ? raw.join(' OR ') : raw;
|
|
41
|
+
if (allowLicenses.some(a => license.includes(a)))
|
|
42
|
+
continue;
|
|
27
43
|
if (FORBIDDEN_LICENSES.some(f => license.includes(f))) {
|
|
28
44
|
violations.push(` ${pkg}: ${license}`);
|
|
29
45
|
}
|
package/dist/scripts/lint.js
CHANGED
|
@@ -9,12 +9,9 @@ const utils_1 = require("../utils");
|
|
|
9
9
|
const delta_1 = require("../utils/delta");
|
|
10
10
|
const execa_1 = require("execa");
|
|
11
11
|
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
-
/**
|
|
13
|
-
* Detect ESLint major version to choose appropriate config format
|
|
14
|
-
*/
|
|
15
|
-
const eslintBin = require.resolve('eslint/bin/eslint.js');
|
|
16
12
|
async function getESLintMajorVersion() {
|
|
17
13
|
try {
|
|
14
|
+
const eslintBin = (0, utils_1.resolvePackageBin)('eslint', 'bin/eslint.js');
|
|
18
15
|
const { stdout } = await (0, execa_1.execa)(process.execPath, [eslintBin, '--version']);
|
|
19
16
|
const match = stdout.match(/v?(\d+)\./);
|
|
20
17
|
return match ? parseInt(match[1], 10) : 8;
|
|
@@ -25,6 +22,7 @@ async function getESLintMajorVersion() {
|
|
|
25
22
|
}
|
|
26
23
|
async function runLint() {
|
|
27
24
|
utils_1.logger.info('[runLint]: 🔍 Running ESLint...');
|
|
25
|
+
const eslintBin = (0, utils_1.resolvePackageBin)('eslint', 'bin/eslint.js');
|
|
28
26
|
const projectRoot = process.cwd();
|
|
29
27
|
const sourcePath = (0, config_1.getSourcePath)();
|
|
30
28
|
const sourceFullPath = node_path_1.default.join(projectRoot, sourcePath);
|
|
@@ -90,7 +90,7 @@ async function runMarkdownLint() {
|
|
|
90
90
|
const extraIgnores = (userConfig.ignores ?? []).flatMap(p => ['--ignore', p]);
|
|
91
91
|
const gitignorePath = node_path_1.default.join(root, '.gitignore');
|
|
92
92
|
const ignorePath = node_fs_1.default.existsSync(gitignorePath) ? ['--ignore-path', gitignorePath] : [];
|
|
93
|
-
const markdownlintBin =
|
|
93
|
+
const markdownlintBin = (0, utils_1.resolvePackageBin)('markdownlint-cli', 'markdownlint.js');
|
|
94
94
|
const args = [
|
|
95
95
|
'--fix',
|
|
96
96
|
...targets,
|
|
@@ -87,7 +87,7 @@ async function runPrettier() {
|
|
|
87
87
|
]);
|
|
88
88
|
let args;
|
|
89
89
|
let tempConfig = null;
|
|
90
|
-
const prettierBin =
|
|
90
|
+
const prettierBin = (0, utils_1.resolvePackageBin)('prettier', 'bin/prettier.cjs');
|
|
91
91
|
if (hasLocal) {
|
|
92
92
|
utils_1.logger.info(`[runPrettier]: Using local Prettier config (checking: ${sourcePath})`);
|
|
93
93
|
args = ['--write', ...targets, '--ignore-path', ignorePath];
|
package/dist/scripts/security.js
CHANGED
|
@@ -68,7 +68,7 @@ async function runSecurityScan() {
|
|
|
68
68
|
...(headSha && { HEAD_SHA: headSha }),
|
|
69
69
|
...(baseSha && { BASE_SHA: baseSha }),
|
|
70
70
|
};
|
|
71
|
-
const gitleaksBin =
|
|
71
|
+
const gitleaksBin = (0, utils_1.resolvePackageBin)('gitleaks-secret-scanner-fixed', 'bin/cli.js');
|
|
72
72
|
const hasClientConfig = (0, config_1.hasLocalConfig)([
|
|
73
73
|
'.gitleaks.toml',
|
|
74
74
|
'gitleaks.toml',
|
|
@@ -35,8 +35,22 @@ function createTempCspellConfig() {
|
|
|
35
35
|
const packageConfigDir = node_path_1.default.dirname(packageConfigPath);
|
|
36
36
|
const defaultConfig = JSON.parse(node_fs_1.default.readFileSync(packageConfigPath, 'utf-8'));
|
|
37
37
|
const userConfig = loadUserCspellConfig();
|
|
38
|
-
// Resolve
|
|
39
|
-
|
|
38
|
+
// Resolve import paths to absolute so they work from any client cwd.
|
|
39
|
+
// Relative paths are resolved against the package config dir; bare package
|
|
40
|
+
// specifiers (e.g. "@cspell/dict-ru_ru/cspell-ext.json") are resolved via Node
|
|
41
|
+
// module resolution so they work regardless of npm hoisting in the client
|
|
42
|
+
// project (dicts may live in the root node_modules, not nested under us).
|
|
43
|
+
const resolvedImports = (defaultConfig.import ?? []).map(p => {
|
|
44
|
+
if (p.startsWith('.')) {
|
|
45
|
+
return node_path_1.default.resolve(packageConfigDir, p);
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
return require.resolve(p);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return p;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
40
54
|
// Merge configurations
|
|
41
55
|
const mergedConfig = {
|
|
42
56
|
...defaultConfig,
|
|
@@ -85,7 +99,7 @@ async function runSpellcheck() {
|
|
|
85
99
|
const hasLocal = (0, config_1.hasLocalConfig)(['cspell.json', '.cspell.json', 'cspell.config.json']);
|
|
86
100
|
let args;
|
|
87
101
|
let tempConfigPath = null;
|
|
88
|
-
const cspellBin =
|
|
102
|
+
const cspellBin = (0, utils_1.resolvePackageBin)('cspell', 'bin.mjs');
|
|
89
103
|
if (hasLocal) {
|
|
90
104
|
utils_1.logger.info(`📋 Using local cspell config (checking: ${sourcePath})`);
|
|
91
105
|
args = [...patterns, '--no-progress'];
|
|
@@ -21,7 +21,7 @@ async function runTypecheck() {
|
|
|
21
21
|
utils_1.logger.info('[runTypecheck]: No tsconfig.json found, skipping');
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
|
-
const tscBin =
|
|
24
|
+
const tscBin = (0, utils_1.resolvePackageBin)('typescript', 'bin/tsc');
|
|
25
25
|
const result = await (0, execa_1.execa)(process.execPath, [tscBin, '--noEmit'], { reject: false });
|
|
26
26
|
if (result.exitCode !== 0) {
|
|
27
27
|
const output = [result.stdout, result.stderr].filter(Boolean).join('\n');
|
package/dist/utils/index.js
CHANGED
|
@@ -23,6 +23,7 @@ const logger_1 = require("./logger");
|
|
|
23
23
|
__exportStar(require("./logger"), exports);
|
|
24
24
|
__exportStar(require("./delta"), exports);
|
|
25
25
|
__exportStar(require("./result-collector"), exports);
|
|
26
|
+
__exportStar(require("./resolve-bin"), exports);
|
|
26
27
|
function cleanupTempFile(filePath) {
|
|
27
28
|
try {
|
|
28
29
|
if (node_fs_1.default.existsSync(filePath)) {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolvePackageBin = resolvePackageBin;
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
+
/**
|
|
10
|
+
* Resolves a binary path for a bundled package, bypassing exports map restrictions.
|
|
11
|
+
*
|
|
12
|
+
* Strategy (tries each in order):
|
|
13
|
+
* 1. Direct subpath — fast path for packages that explicitly export their bin
|
|
14
|
+
* 2. Via package.json — for packages that export ./package.json but not the bin subpath (e.g. eslint)
|
|
15
|
+
* 3. Walk up from main entry — for packages that export neither (e.g. cspell)
|
|
16
|
+
*/
|
|
17
|
+
function resolvePackageBin(pkgName, binRelPath) {
|
|
18
|
+
// 1. Direct subpath
|
|
19
|
+
try {
|
|
20
|
+
return require.resolve(`${pkgName}/${binRelPath}`);
|
|
21
|
+
}
|
|
22
|
+
catch { }
|
|
23
|
+
// 2. Via package.json
|
|
24
|
+
try {
|
|
25
|
+
const pkgJsonPath = require.resolve(`${pkgName}/package.json`);
|
|
26
|
+
return node_path_1.default.join(node_path_1.default.dirname(pkgJsonPath), binRelPath);
|
|
27
|
+
}
|
|
28
|
+
catch { }
|
|
29
|
+
// 3. Walk up from main entry to find package root by matching package name
|
|
30
|
+
const main = require.resolve(pkgName);
|
|
31
|
+
let dir = node_path_1.default.dirname(main);
|
|
32
|
+
while (dir !== node_path_1.default.dirname(dir)) {
|
|
33
|
+
const pkgJsonPath = node_path_1.default.join(dir, 'package.json');
|
|
34
|
+
if (node_fs_1.default.existsSync(pkgJsonPath)) {
|
|
35
|
+
try {
|
|
36
|
+
const pkg = JSON.parse(node_fs_1.default.readFileSync(pkgJsonPath, 'utf-8'));
|
|
37
|
+
if (pkg.name === pkgName) {
|
|
38
|
+
return node_path_1.default.join(dir, binRelPath);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch { }
|
|
42
|
+
}
|
|
43
|
+
dir = node_path_1.default.dirname(dir);
|
|
44
|
+
}
|
|
45
|
+
throw new Error(`Cannot resolve binary "${binRelPath}" for package "${pkgName}"`);
|
|
46
|
+
}
|
package/eslint.config.mjs
CHANGED
|
@@ -76,13 +76,13 @@ function loadUserConfig() {
|
|
|
76
76
|
if (fs.existsSync(configPath)) {
|
|
77
77
|
try {
|
|
78
78
|
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
79
|
-
console.
|
|
79
|
+
console.error(`[loadUserConfig]: ✅ Loaded user config from: ${configPath}`);
|
|
80
80
|
return config;
|
|
81
81
|
} catch (err) {
|
|
82
82
|
console.warn(`[loadUserConfig]: ⚠️ Failed to parse ${configPath}:`, err.message);
|
|
83
83
|
}
|
|
84
84
|
} else {
|
|
85
|
-
console.
|
|
85
|
+
console.error(`[loadUserConfig]: ℹ️ No pr-checkmate.json found, using defaults`);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
return { sourcePath: 'src', eslint: {} };
|
|
@@ -110,13 +110,13 @@ const customRulesCount = Object.keys(userConfig.eslint?.rules || {}).length;
|
|
|
110
110
|
const customIgnoresCount = (userConfig.eslint?.ignorePatterns || []).length;
|
|
111
111
|
|
|
112
112
|
if (customRulesCount > 0) {
|
|
113
|
-
console.
|
|
113
|
+
console.error(`🔧 Applied ${customRulesCount} custom ESLint rules`);
|
|
114
114
|
}
|
|
115
115
|
if (customIgnoresCount > 0) {
|
|
116
|
-
console.
|
|
116
|
+
console.error(`🚫 Applied ${customIgnoresCount} custom ignore patterns`);
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
console.
|
|
119
|
+
console.error(`📋 ESLint checking: ${SRC}/**/*.{ts,tsx,js,jsx}`);
|
|
120
120
|
|
|
121
121
|
export default [
|
|
122
122
|
// Global ignores must be in a separate config object
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pr-checkmate",
|
|
3
|
-
"version": "1.21.
|
|
3
|
+
"version": "1.21.8",
|
|
4
4
|
"description": "Automated PR quality checks: linting, formatting, dependency analysis, and spellcheck",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"github-actions",
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
"eslint.config.mjs",
|
|
24
24
|
".eslintrc.js",
|
|
25
25
|
".prettierrc",
|
|
26
|
-
".eslintignore",
|
|
27
26
|
"cspell.json",
|
|
28
27
|
"src/config/pr-checkmate-workflow.yml",
|
|
29
28
|
".markdownlint.json",
|
|
@@ -67,10 +66,10 @@
|
|
|
67
66
|
"@cspell/dict-he": "^4.0.2",
|
|
68
67
|
"@cspell/dict-ru_ru": "^2.2.1",
|
|
69
68
|
"@cspell/dict-uk-ua": "^4.0.0",
|
|
69
|
+
"@types/node": "^25.9.4",
|
|
70
70
|
"@typescript-eslint/eslint-plugin": "^8.47.0",
|
|
71
71
|
"@typescript-eslint/parser": "^8.47.0",
|
|
72
72
|
"cspell": "^9.3.2",
|
|
73
|
-
"dotenv": "^17.2.3",
|
|
74
73
|
"eslint": "^9.26.0",
|
|
75
74
|
"eslint-config-prettier": "^9.1.2",
|
|
76
75
|
"eslint-plugin-import": "^2.29.0",
|
package/src/config/.eslintrc.js
CHANGED
|
@@ -21,7 +21,7 @@ function loadUserConfig() {
|
|
|
21
21
|
if (fs.existsSync(configPath)) {
|
|
22
22
|
try {
|
|
23
23
|
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
24
|
-
console.
|
|
24
|
+
console.error(`[ESLint]: ✅ Loaded config from: ${configPath}`);
|
|
25
25
|
return config;
|
|
26
26
|
} catch (err) {
|
|
27
27
|
console.warn(`[ESLint]: ⚠️ Failed to parse ${configPath}:`, err.message);
|
package/src/config/cspell.json
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"version": "0.2",
|
|
3
3
|
"language": "en,ru,uk,he,fr,es",
|
|
4
4
|
"import": [
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
5
|
+
"@cspell/dict-ru_ru/cspell-ext.json",
|
|
6
|
+
"@cspell/dict-uk-ua/cspell-ext.json",
|
|
7
|
+
"@cspell/dict-he/cspell-ext.json",
|
|
8
|
+
"@cspell/dict-fr-fr/cspell-ext.json",
|
|
9
|
+
"@cspell/dict-es-es/cspell-ext.json"
|
|
10
10
|
],
|
|
11
11
|
"words": [
|
|
12
12
|
"ACMR",
|
|
@@ -76,13 +76,13 @@ function loadUserConfig() {
|
|
|
76
76
|
if (fs.existsSync(configPath)) {
|
|
77
77
|
try {
|
|
78
78
|
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
79
|
-
console.
|
|
79
|
+
console.error(`[loadUserConfig]: ✅ Loaded user config from: ${configPath}`);
|
|
80
80
|
return config;
|
|
81
81
|
} catch (err) {
|
|
82
82
|
console.warn(`[loadUserConfig]: ⚠️ Failed to parse ${configPath}:`, err.message);
|
|
83
83
|
}
|
|
84
84
|
} else {
|
|
85
|
-
console.
|
|
85
|
+
console.error(`[loadUserConfig]: ℹ️ No pr-checkmate.json found, using defaults`);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
return { sourcePath: 'src', eslint: {} };
|
|
@@ -110,13 +110,13 @@ const customRulesCount = Object.keys(userConfig.eslint?.rules || {}).length;
|
|
|
110
110
|
const customIgnoresCount = (userConfig.eslint?.ignorePatterns || []).length;
|
|
111
111
|
|
|
112
112
|
if (customRulesCount > 0) {
|
|
113
|
-
console.
|
|
113
|
+
console.error(`🔧 Applied ${customRulesCount} custom ESLint rules`);
|
|
114
114
|
}
|
|
115
115
|
if (customIgnoresCount > 0) {
|
|
116
|
-
console.
|
|
116
|
+
console.error(`🚫 Applied ${customIgnoresCount} custom ignore patterns`);
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
console.
|
|
119
|
+
console.error(`📋 ESLint checking: ${SRC}/**/*.{ts,tsx,js,jsx}`);
|
|
120
120
|
|
|
121
121
|
export default [
|
|
122
122
|
// Global ignores must be in a separate config object
|
package/.eslintignore
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
# Dependencies
|
|
2
|
-
node_modules/
|
|
3
|
-
|
|
4
|
-
# Build outputs
|
|
5
|
-
dist/
|
|
6
|
-
build/
|
|
7
|
-
out/
|
|
8
|
-
.next/
|
|
9
|
-
.nuxt/
|
|
10
|
-
|
|
11
|
-
# Test reports & artifacts
|
|
12
|
-
allure-report/
|
|
13
|
-
allure-results/
|
|
14
|
-
reports/
|
|
15
|
-
report/
|
|
16
|
-
test-reports/
|
|
17
|
-
test-report/
|
|
18
|
-
test-output/
|
|
19
|
-
test-results/
|
|
20
|
-
results/
|
|
21
|
-
result/
|
|
22
|
-
coverage/
|
|
23
|
-
.coverage/
|
|
24
|
-
htmlcov/
|
|
25
|
-
|
|
26
|
-
# Jest
|
|
27
|
-
jest-html-reporters-*/
|
|
28
|
-
jest-stare/
|
|
29
|
-
jest.config.js
|
|
30
|
-
|
|
31
|
-
# Cypress
|
|
32
|
-
cypress/reports/
|
|
33
|
-
cypress/videos/
|
|
34
|
-
cypress/screenshots/
|
|
35
|
-
|
|
36
|
-
# Playwright
|
|
37
|
-
playwright-report/
|
|
38
|
-
test-results/
|
|
39
|
-
|
|
40
|
-
# WebdriverIO
|
|
41
|
-
.wdio/
|
|
42
|
-
wdio-logs/
|
|
43
|
-
|
|
44
|
-
# Mocha/Mochawesome
|
|
45
|
-
mochawesome-report/
|
|
46
|
-
mochawesome-reports/
|
|
47
|
-
|
|
48
|
-
# Maven/JUnit
|
|
49
|
-
target/
|
|
50
|
-
|
|
51
|
-
# Logs
|
|
52
|
-
logs/
|
|
53
|
-
*.log
|
|
54
|
-
npm-debug.log*
|
|
55
|
-
yarn-debug.log*
|
|
56
|
-
|
|
57
|
-
# Python
|
|
58
|
-
__pycache__/
|
|
59
|
-
.pytest_cache/
|
|
60
|
-
.venv/
|
|
61
|
-
venv/
|
|
62
|
-
|
|
63
|
-
# Git
|
|
64
|
-
.git/
|
|
65
|
-
|
|
66
|
-
# Config files
|
|
67
|
-
*.config.js
|
|
68
|
-
*.config.ts
|
|
69
|
-
jest.config.*
|
|
70
|
-
wdio.config.*
|
|
71
|
-
playwright.config.*
|
|
72
|
-
cypress.config.*
|
package/src/config/.eslintignore
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
# Dependencies
|
|
2
|
-
node_modules/
|
|
3
|
-
|
|
4
|
-
# Build outputs
|
|
5
|
-
dist/
|
|
6
|
-
build/
|
|
7
|
-
out/
|
|
8
|
-
.next/
|
|
9
|
-
.nuxt/
|
|
10
|
-
|
|
11
|
-
# Test reports & artifacts
|
|
12
|
-
allure-report/
|
|
13
|
-
allure-results/
|
|
14
|
-
reports/
|
|
15
|
-
report/
|
|
16
|
-
test-reports/
|
|
17
|
-
test-report/
|
|
18
|
-
test-output/
|
|
19
|
-
test-results/
|
|
20
|
-
results/
|
|
21
|
-
result/
|
|
22
|
-
coverage/
|
|
23
|
-
.coverage/
|
|
24
|
-
htmlcov/
|
|
25
|
-
|
|
26
|
-
# Jest
|
|
27
|
-
jest-html-reporters-*/
|
|
28
|
-
jest-stare/
|
|
29
|
-
jest.config.js
|
|
30
|
-
|
|
31
|
-
# Cypress
|
|
32
|
-
cypress/reports/
|
|
33
|
-
cypress/videos/
|
|
34
|
-
cypress/screenshots/
|
|
35
|
-
|
|
36
|
-
# Playwright
|
|
37
|
-
playwright-report/
|
|
38
|
-
test-results/
|
|
39
|
-
|
|
40
|
-
# WebdriverIO
|
|
41
|
-
.wdio/
|
|
42
|
-
wdio-logs/
|
|
43
|
-
|
|
44
|
-
# Mocha/Mochawesome
|
|
45
|
-
mochawesome-report/
|
|
46
|
-
mochawesome-reports/
|
|
47
|
-
|
|
48
|
-
# Maven/JUnit
|
|
49
|
-
target/
|
|
50
|
-
|
|
51
|
-
# Logs
|
|
52
|
-
logs/
|
|
53
|
-
*.log
|
|
54
|
-
npm-debug.log*
|
|
55
|
-
yarn-debug.log*
|
|
56
|
-
|
|
57
|
-
# Python
|
|
58
|
-
__pycache__/
|
|
59
|
-
.pytest_cache/
|
|
60
|
-
.venv/
|
|
61
|
-
venv/
|
|
62
|
-
|
|
63
|
-
# Git
|
|
64
|
-
.git/
|
|
65
|
-
|
|
66
|
-
# Config files
|
|
67
|
-
*.config.js
|
|
68
|
-
*.config.ts
|
|
69
|
-
jest.config.*
|
|
70
|
-
wdio.config.*
|
|
71
|
-
playwright.config.*
|
|
72
|
-
cypress.config.*
|