Skip to content

Commit 813f19f

Browse files
mizdraclaude
andcommitted
feat: exit with error when cmkOptions.enabled is false
When css-modules-kit is disabled by configuration (`enabled: false`), the codegen now throws CMKDisabledError and exits with code 1 instead of silently proceeding. This applies to both normal and watch modes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 0e2e902 commit 813f19f

4 files changed

Lines changed: 36 additions & 1 deletion

File tree

packages/codegen/src/error.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,12 @@ export class ReadCSSModuleFileError extends SystemError {
1717
super('READ_CSS_MODULE_FILE_ERROR', `Failed to read CSS Module file ${fileName}.`, cause);
1818
}
1919
}
20+
21+
export class CMKDisabledError extends SystemError {
22+
constructor(configFileName: string) {
23+
super(
24+
'CMK_DISABLED_ERROR',
25+
`css-modules-kit is disabled by configuration. Set \`"cmkOptions": { "enabled": true }\` in ${configFileName} to enable it.`,
26+
);
27+
}
28+
}

packages/codegen/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export { runCMK, runCMKInWatchMode } from './runner.js';
22
export { type Logger, createLogger } from './logger/logger.js';
3-
export { WriteDtsFileError, ReadCSSModuleFileError } from './error.js';
3+
export { WriteDtsFileError, ReadCSSModuleFileError, CMKDisabledError } from './error.js';
44
export { parseCLIArgs, printHelpText, printVersion } from './cli.js';
55
export { shouldBePretty } from './3rd-party/typescript.js';

packages/codegen/src/runner.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { access, rm, writeFile } from 'node:fs/promises';
22
import { platform } from 'node:process';
33
import dedent from 'dedent';
44
import { afterEach, describe, expect, test, vi } from 'vitest';
5+
import { CMKDisabledError } from './error.js';
56
import type { Watcher } from './runner.js';
67
import { runCMK, runCMKInWatchMode } from './runner.js';
78
import { formatDiagnostics } from './test/diagnostic.js';
@@ -100,6 +101,13 @@ describe('runCMK', () => {
100101
await expect(access(iff.join('generated/src/a.module.css.d.ts'))).resolves.not.toThrow();
101102
await expect(access(iff.join('generated/src/old.module.css.d.ts'))).rejects.toThrow();
102103
});
104+
test('throws CMKDisabledError if enabled is false', async () => {
105+
const iff = await createIFF({
106+
'tsconfig.json': '{ "cmkOptions": { "enabled": false } }',
107+
'src/a.module.css': '.a_1 { color: red; }',
108+
});
109+
await expect(runCMK(fakeParsedArgs({ project: iff.rootDir }), createLoggerSpy())).rejects.toThrow(CMKDisabledError);
110+
});
103111
});
104112

105113
describe('runCMKInWatchMode', () => {
@@ -305,4 +313,13 @@ describe('runCMKInWatchMode', () => {
305313
watcher = await runCMKInWatchMode(fakeParsedArgs({ project: iff.rootDir, preserveWatchOutput: true }), loggerSpy2);
306314
expect(loggerSpy2.clearScreen).toHaveBeenCalledTimes(0);
307315
});
316+
test('throws CMKDisabledError if enabled is false', async () => {
317+
const iff = await createIFF({
318+
'tsconfig.json': '{ "cmkOptions": { "enabled": false } }',
319+
'src/a.module.css': '.a_1 { color: red; }',
320+
});
321+
await expect(runCMKInWatchMode(fakeParsedArgs({ project: iff.rootDir }), createLoggerSpy())).rejects.toThrow(
322+
CMKDisabledError,
323+
);
324+
});
308325
});

packages/codegen/src/runner.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { Stats } from 'node:fs';
22
import { rm } from 'node:fs/promises';
33
import chokidar, { type FSWatcher } from 'chokidar';
4+
import { CMKDisabledError } from './error.js';
45
import type { Logger } from './logger/logger.js';
56
import { createProject, type Project } from './project.js';
67

@@ -19,12 +20,16 @@ export interface Watcher {
1920
/**
2021
* Run css-modules-kit .d.ts generation.
2122
* @param project The absolute path to the project directory or the path to `tsconfig.json`.
23+
* @throws {CMKDisabledError} When css-modules-kit is disabled.
2224
* @throws {ReadCSSModuleFileError} When failed to read CSS Module file.
2325
* @throws {WriteDtsFileError}
2426
* @returns Whether the process succeeded without errors.
2527
*/
2628
export async function runCMK(args: RunnerArgs, logger: Logger): Promise<boolean> {
2729
const project = createProject(args);
30+
if (project.config.enabled === false) {
31+
throw new CMKDisabledError(project.config.configFileName);
32+
}
2833
if (args.clean) {
2934
await rm(project.config.dtsOutDir, { recursive: true, force: true });
3035
}
@@ -46,13 +51,17 @@ export async function runCMK(args: RunnerArgs, logger: Logger): Promise<boolean>
4651
*
4752
* NOTE: For implementation simplicity, config file changes are not watched.
4853
* @param project The absolute path to the project directory or the path to `tsconfig.json`.
54+
* @throws {CMKDisabledError} When css-modules-kit is disabled.
4955
* @throws {TsConfigFileNotFoundError}
5056
* @throws {ReadCSSModuleFileError}
5157
* @throws {WriteDtsFileError}
5258
*/
5359
export async function runCMKInWatchMode(args: RunnerArgs, logger: Logger): Promise<Watcher> {
5460
const fsWatchers: FSWatcher[] = [];
5561
const project = createProject(args);
62+
if (project.config.enabled === false) {
63+
throw new CMKDisabledError(project.config.configFileName);
64+
}
5665
let emitAndReportDiagnosticsTimer: NodeJS.Timeout | undefined = undefined;
5766

5867
if (args.clean) {

0 commit comments

Comments
 (0)