fix(hooks): recognize Prettier's TypeScript and JSON5 config files

Prettier's config searcher also reads .prettierrc.json5, .prettierrc.ts/.mts/.cts and prettier.config.ts/.mts/.cts. resolve-formatter knew none of them, so a project configured only through prettier.config.ts was never formatted by post-edit-format, quality-gate or the Stop batch. config-protection's rc pattern stopped at .yaml/.toml, so an existing .prettierrc.ts or .prettierrc.json5 could be edited freely.
This commit is contained in:
L4XB committed 2026-10-22 23:51:32 +02:00
1 parent 90606c8315
commit 10e7c5800f
4 files changed
+47 -3

No files matched your search

+19
View File
@@ -447,6 +447,25 @@ function runTests() {
})
);
results.push(
test("blocks Prettier's TypeScript and JSON5 rc files", () => {
return withOwnedDirectory(fs.mkdtempSync(path.join(os.tmpdir(), 'ecc-config-protect-prettier-')), tmpDir => {
for (const name of ['.prettierrc.ts', '.prettierrc.mts', '.prettierrc.cts', '.prettierrc.json5', '.prettierrc.shared.ts']) {
const absPath = path.join(tmpDir, name);
fs.writeFileSync(absPath, 'export default {};\n');
const result = runHook({ tool_name: 'Edit', tool_input: { file_path: absPath } });
assert.strictEqual(result.code, 2, 'Expected ' + name + ' to be blocked');
assert.ok(
result.stderr.includes('BLOCKED: Modifying ' + name + ' is not allowed.'),
'Expected block message for ' + name + ', got: ' + result.stderr
);
}
});
})
);
results.push(
test('does not block build or test tooling configs', () => {
// Pins the boundary: this hook guards LINTER configs. A future widening
+15
View File
@@ -155,6 +155,21 @@ function runTests() {
assert.strictEqual(detectFormatter(root), 'prettier');
});
run("detectFormatter: detects Prettier's TypeScript and JSON5 config files", () => {
const names = ['.prettierrc.json5', '.prettierrc.ts', '.prettierrc.mts', '.prettierrc.cts',
'prettier.config.ts', 'prettier.config.mts', 'prettier.config.cts'];
for (const name of names) {
const root = makeTmpDir();
fs.writeFileSync(path.join(root, 'package.json'), JSON.stringify({ name: 'test' }));
fs.writeFileSync(path.join(root, name), 'export default {};\n');
assert.strictEqual(detectFormatter(root), 'prettier', name);
const nested = path.join(root, 'src');
fs.mkdirSync(nested);
fs.rmSync(path.join(root, 'package.json'));
assert.strictEqual(findProjectRoot(nested), root, `${name} marks the project root`);
}
});
run('detectFormatter: detects prettier key in package.json', () => {
const root = makeTmpDir();
fs.writeFileSync(path.join(root, 'package.json'), JSON.stringify({ name: 'test', prettier: { singleQuote: true } }));