pr-checkmate 1.21.2 → 1.21.4

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.
@@ -10,6 +10,7 @@ const delta_1 = require("../utils/delta");
10
10
  const config_1 = require("../config");
11
11
  const node_path_1 = __importDefault(require("node:path"));
12
12
  const node_fs_1 = __importDefault(require("node:fs"));
13
+ const node_os_1 = __importDefault(require("node:os"));
13
14
  function loadUserMarkdownConfig() {
14
15
  const configPath = node_path_1.default.join(process.cwd(), 'pr-checkmate.json');
15
16
  if (!node_fs_1.default.existsSync(configPath)) {
@@ -24,39 +25,64 @@ function loadUserMarkdownConfig() {
24
25
  return {};
25
26
  }
26
27
  }
28
+ function buildMergedConfig(bundledConfigPath, userRules) {
29
+ const bundled = JSON.parse(node_fs_1.default.readFileSync(bundledConfigPath, 'utf-8'));
30
+ const merged = { ...bundled, ...userRules };
31
+ const tmpFile = node_path_1.default.join(node_os_1.default.tmpdir(), `.markdownlint-merged-${process.pid}.json`);
32
+ node_fs_1.default.writeFileSync(tmpFile, JSON.stringify(merged, null, 2));
33
+ return tmpFile;
34
+ }
27
35
  async function runMarkdownLint() {
28
36
  utils_1.logger.info('[runMarkdownLint]: 📝 Running Markdown lint...');
29
37
  const root = process.cwd();
30
38
  const changedFiles = await (0, delta_1.getChangedFiles)(['.md', '.mdx']);
31
39
  const targets = changedFiles ?? [`${root}/**/*.md`];
32
40
  const userConfig = loadUserMarkdownConfig();
33
- // Prefer local .markdownlint.json → else fall back to bundled one
41
+ const userRules = userConfig.rules ?? {};
42
+ const hasUserRules = Object.keys(userRules).length > 0;
34
43
  let configArg;
44
+ let tempConfigFile = null;
35
45
  if ((0, config_1.hasLocalConfig)(['.markdownlint.json', '.markdownlint.jsonc', '.markdownlint.yaml', '.markdownlint.yml'])) {
36
46
  utils_1.logger.info('[runMarkdownLint]: 📋 Using local .markdownlint config');
37
47
  configArg = [];
38
48
  }
39
49
  else {
40
50
  const bundledConfig = (0, config_1.getPackageConfigPath)('.markdownlint.json');
41
- utils_1.logger.info('[runMarkdownLint]: 📋 Using pr-checkmate bundled markdownlint config');
42
- configArg = ['--config', bundledConfig];
51
+ if (hasUserRules) {
52
+ tempConfigFile = buildMergedConfig(bundledConfig, userRules);
53
+ utils_1.logger.info(`[runMarkdownLint]: 📋 Using bundled config merged with ${Object.keys(userRules).length} user rule(s)`);
54
+ configArg = ['--config', tempConfigFile];
55
+ }
56
+ else {
57
+ utils_1.logger.info('[runMarkdownLint]: 📋 Using pr-checkmate bundled markdownlint config');
58
+ configArg = ['--config', bundledConfig];
59
+ }
43
60
  }
44
61
  const extraIgnores = (userConfig.ignores ?? []).flatMap(p => ['--ignore', p]);
62
+ const gitignorePath = node_path_1.default.join(root, '.gitignore');
63
+ const ignorePath = node_fs_1.default.existsSync(gitignorePath) ? ['--ignore-path', gitignorePath] : [];
45
64
  const args = [
46
65
  'markdownlint',
47
66
  ...targets,
48
67
  ...configArg,
68
+ ...ignorePath,
49
69
  '--ignore', 'node_modules',
50
70
  '--ignore', 'dist',
51
71
  '--ignore', 'coverage',
52
72
  ...extraIgnores,
53
73
  ];
54
- const result = await (0, execa_1.execa)('npx', args, { reject: false, stdio: 'inherit' });
55
- if (result.exitCode === 0) {
56
- utils_1.logger.info('[runMarkdownLint]: ✅ Markdown lint passed');
74
+ try {
75
+ const result = await (0, execa_1.execa)('npx', args, { reject: false, stdio: 'inherit' });
76
+ if (result.exitCode === 0) {
77
+ utils_1.logger.info('[runMarkdownLint]: ✅ Markdown lint passed');
78
+ }
79
+ else {
80
+ utils_1.logger.warn('[runMarkdownLint]: ⚠️ Markdown lint found issues (see above)');
81
+ }
57
82
  }
58
- else {
59
- utils_1.logger.warn('[runMarkdownLint]: ⚠️ Markdown lint found issues (see above)');
60
- // warning only — never block
83
+ finally {
84
+ if (tempConfigFile && node_fs_1.default.existsSync(tempConfigFile)) {
85
+ node_fs_1.default.unlinkSync(tempConfigFile);
86
+ }
61
87
  }
62
88
  }
@@ -15,9 +15,20 @@ function isSeverityAtLeast(severity, level) {
15
15
  const lvlIdx = SEVERITY_ORDER.indexOf(level);
16
16
  return sevIdx >= 0 && lvlIdx >= 0 && sevIdx >= lvlIdx;
17
17
  }
18
+ function getOwnPackageName() {
19
+ try {
20
+ const ownPkg = node_path_1.default.resolve(__dirname, '../../package.json');
21
+ const content = node_fs_1.default.readFileSync(ownPkg, 'utf-8');
22
+ return JSON.parse(content).name ?? null;
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ }
18
28
  /**
19
29
  * Run npm audit on the current project.
20
30
  * Only fails on vulnerabilities in direct dependencies — transitive ones are silently ignored.
31
+ * Vulnerabilities in pr-checkmate itself are also skipped — the client cannot fix those.
21
32
  */
22
33
  async function runNpmAudit() {
23
34
  utils_1.logger.info('Running npm audit...');
@@ -29,6 +40,7 @@ async function runNpmAudit() {
29
40
  }
30
41
  const config = (0, config_1.loadProjectConfig)();
31
42
  const auditLevel = config.security?.['npm-audit']?.auditLevel ?? 'moderate';
43
+ const ownName = getOwnPackageName();
32
44
  let report;
33
45
  try {
34
46
  const { stdout } = await (0, execa_1.execa)('npm', ['audit', '--json'], {
@@ -41,7 +53,7 @@ async function runNpmAudit() {
41
53
  utils_1.logger.error('[runNpmAudit]: ❌ Failed to parse npm audit output');
42
54
  throw error;
43
55
  }
44
- const directVulns = Object.values(report.vulnerabilities ?? {}).filter(v => v.isDirect && isSeverityAtLeast(v.severity, auditLevel));
56
+ const directVulns = Object.values(report.vulnerabilities ?? {}).filter(v => v.isDirect && v.name !== ownName && isSeverityAtLeast(v.severity, auditLevel));
45
57
  if (directVulns.length === 0) {
46
58
  utils_1.logger.info('[runNpmAudit]: ✅ NPM audit finished successfully');
47
59
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pr-checkmate",
3
- "version": "1.21.2",
3
+ "version": "1.21.4",
4
4
  "description": "Automated PR quality checks: linting, formatting, dependency analysis, and spellcheck",
5
5
  "keywords": [
6
6
  "github-actions",
@@ -74,9 +74,9 @@
74
74
  "eslint-plugin-prettier": "^5.5.4",
75
75
  "execa": "^9.6.0",
76
76
  "gitleaks-secret-scanner-fixed": "^2.1.3",
77
- "jscpd": "^3.5.10",
78
- "markdownlint-cli": "^0.45.0",
79
77
  "inquirer": "^13.0.1",
78
+ "jscpd": "^3.5.10",
79
+ "markdownlint-cli": "^0.49.0",
80
80
  "prettier": ">=3.0.0",
81
81
  "ts-node": "^10.9.1",
82
82
  "typescript": "^5.9.3"