@css-modules-kit/codegen 0.6.0 → 0.8.0

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.
@@ -0,0 +1,174 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { checkCSSModule, createExportBuilder, createMatchesPattern, createResolver, generateDts, getFileNamesByPattern, parseCSSModule, readConfigFile, relative, } from '@css-modules-kit/core';
3
+ import ts from 'typescript';
4
+ import { writeDtsFile } from './dts-writer.js';
5
+ import { ReadCSSModuleFileError } from './error.js';
6
+ /**
7
+ * Create a Project instance.
8
+ * Project is like a facade that calls core operations such as loading settings, parsing CSS Module files, and performing checks.
9
+ * The parsing and checking results are cached, and methods are also provided to clear the cache when files change.
10
+ * @throws {TsConfigFileNotFoundError}
11
+ * @throws {ReadCSSModuleFileError}
12
+ */
13
+ export function createProject(args) {
14
+ const config = readConfigFile(args.project);
15
+ const getCanonicalFileName = (fileName) => ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
16
+ const moduleResolutionCache = ts.createModuleResolutionCache(config.basePath, getCanonicalFileName, config.compilerOptions);
17
+ const resolver = createResolver(config.compilerOptions, moduleResolutionCache);
18
+ const matchesPattern = createMatchesPattern(config);
19
+ const cssModuleMap = new Map();
20
+ const semanticDiagnosticsMap = new Map();
21
+ // Tracks whether .d.ts has been emitted after the last change
22
+ const emittedSet = new Set();
23
+ const getCSSModule = (path) => cssModuleMap.get(path);
24
+ const exportBuilder = createExportBuilder({ getCSSModule, matchesPattern, resolver });
25
+ for (const fileName of getFileNamesByPattern(config)) {
26
+ // NOTE: Files may be deleted between executing `getFileNamesByPattern` and `tryParseCSSModule`.
27
+ // Therefore, `tryParseCSSModule` may return `undefined`.
28
+ const cssModule = tryParseCSSModule(fileName);
29
+ if (cssModule)
30
+ cssModuleMap.set(fileName, cssModule);
31
+ }
32
+ /**
33
+ * @throws {ReadCSSModuleFileError}
34
+ */
35
+ function addFile(fileName) {
36
+ if (cssModuleMap.has(fileName))
37
+ return;
38
+ const cssModule = tryParseCSSModule(fileName);
39
+ if (!cssModule)
40
+ return;
41
+ cssModuleMap.set(fileName, cssModule);
42
+ // TODO: Delete only the minimum amount of check stage cache
43
+ moduleResolutionCache.clear();
44
+ exportBuilder.clearCache();
45
+ semanticDiagnosticsMap.clear();
46
+ }
47
+ /**
48
+ * @throws {ReadCSSModuleFileError}
49
+ */
50
+ function updateFile(fileName) {
51
+ if (!cssModuleMap.has(fileName))
52
+ return;
53
+ const cssModule = tryParseCSSModule(fileName);
54
+ if (!cssModule)
55
+ return;
56
+ cssModuleMap.set(fileName, cssModule);
57
+ // TODO: Delete only the minimum amount of check stage cache
58
+ exportBuilder.clearCache();
59
+ semanticDiagnosticsMap.clear();
60
+ emittedSet.delete(fileName);
61
+ }
62
+ function removeFile(fileName) {
63
+ if (!cssModuleMap.has(fileName))
64
+ return;
65
+ cssModuleMap.delete(fileName);
66
+ // TODO: Delete only the minimum amount of check stage cache
67
+ moduleResolutionCache.clear();
68
+ exportBuilder.clearCache();
69
+ semanticDiagnosticsMap.clear();
70
+ emittedSet.delete(fileName);
71
+ }
72
+ /**
73
+ * @throws {ReadCSSModuleFileError}
74
+ */
75
+ function tryParseCSSModule(fileName) {
76
+ let text;
77
+ try {
78
+ // NOTE: We are not using asynchronous APIs for the following reasons:
79
+ //
80
+ // - Asynchronous APIs are slow in Node.js.
81
+ // - https://github.com/nodejs/performance/issues/151
82
+ // - Handling race conditions is cumbersome.
83
+ // - Using an asynchronous API makes `addFile` asynchronous too.
84
+ // - If `deleteFile` runs while `addFile` is executing, a race condition occurs.
85
+ // - Avoiding this requires something like a mutex. However, implementing that is cumbersome.
86
+ text = readFileSync(fileName, 'utf-8');
87
+ }
88
+ catch (error) {
89
+ if (isNodeJSSystemError(error) && error.code === 'ENOENT') {
90
+ return undefined;
91
+ }
92
+ throw new ReadCSSModuleFileError(fileName, error);
93
+ }
94
+ return parseCSSModule(text, { fileName, includeSyntaxError: true, keyframes: config.keyframes });
95
+ }
96
+ function getDiagnostics() {
97
+ const diagnostics = [...getProjectDiagnostics(), ...getSyntacticDiagnostics()];
98
+ // If there are project or syntactic diagnostics, skip semantic diagnostics
99
+ if (diagnostics.length > 0)
100
+ return diagnostics;
101
+ diagnostics.push(...getSemanticDiagnostics());
102
+ return diagnostics;
103
+ }
104
+ function getProjectDiagnostics() {
105
+ const diagnostics = [];
106
+ diagnostics.push(...config.diagnostics);
107
+ if (config.enabled === undefined) {
108
+ diagnostics.push({
109
+ category: 'warning',
110
+ text: `"cmkOptions.enabled" will be required in a future version of css-modules-kit. Add \`"cmkOptions": { "enabled": true }\` to ${relative(config.basePath, config.configFileName)}. See https://github.com/mizdra/css-modules-kit/issues/289 for details.`,
111
+ });
112
+ }
113
+ if (cssModuleMap.size === 0) {
114
+ diagnostics.push({
115
+ category: 'error',
116
+ text: `The file specified in tsconfig.json not found.`,
117
+ });
118
+ }
119
+ return diagnostics;
120
+ }
121
+ function getSyntacticDiagnostics() {
122
+ return Array.from(cssModuleMap.values()).flatMap(({ diagnostics }) => diagnostics);
123
+ }
124
+ function getSemanticDiagnostics() {
125
+ const allDiagnostics = [];
126
+ for (const cssModule of cssModuleMap.values()) {
127
+ let diagnostics = semanticDiagnosticsMap.get(cssModule.fileName);
128
+ if (!diagnostics) {
129
+ diagnostics = checkCSSModule(cssModule, {
130
+ config,
131
+ getExportRecord: (m) => exportBuilder.build(m),
132
+ matchesPattern,
133
+ resolver,
134
+ getCSSModule,
135
+ });
136
+ semanticDiagnosticsMap.set(cssModule.fileName, diagnostics);
137
+ }
138
+ allDiagnostics.push(...diagnostics);
139
+ }
140
+ return allDiagnostics;
141
+ }
142
+ /**
143
+ * @throws {WriteDtsFileError}
144
+ */
145
+ async function emitDtsFiles() {
146
+ const promises = [];
147
+ for (const cssModule of cssModuleMap.values()) {
148
+ if (emittedSet.has(cssModule.fileName))
149
+ continue;
150
+ const dts = generateDts(cssModule, { ...config, forTsPlugin: false });
151
+ promises.push(writeDtsFile(dts.text, cssModule.fileName, {
152
+ outDir: config.dtsOutDir,
153
+ basePath: config.basePath,
154
+ arbitraryExtensions: config.arbitraryExtensions,
155
+ }).then(() => {
156
+ emittedSet.add(cssModule.fileName);
157
+ }));
158
+ }
159
+ await Promise.all(promises);
160
+ }
161
+ return {
162
+ config,
163
+ isWildcardMatchedFile: (fileName) => matchesPattern(fileName),
164
+ addFile,
165
+ updateFile,
166
+ removeFile,
167
+ getDiagnostics,
168
+ emitDtsFiles,
169
+ };
170
+ }
171
+ function isNodeJSSystemError(error) {
172
+ return typeof error === 'object' && error !== null && 'code' in error && typeof error.code === 'string';
173
+ }
174
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"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"}
package/dist/runner.d.ts CHANGED
@@ -1,10 +1,37 @@
1
- import type { ParsedArgs } from './cli.js';
2
1
  import type { Logger } from './logger/logger.js';
2
+ import { type Project } from './project.js';
3
+ interface RunnerArgs {
4
+ project: string;
5
+ clean: boolean;
6
+ preserveWatchOutput: boolean;
7
+ }
8
+ export interface Watcher {
9
+ /** Exported for testing purposes */
10
+ project: Project;
11
+ close(): Promise<void>;
12
+ }
3
13
  /**
4
14
  * Run css-modules-kit .d.ts generation.
5
15
  * @param project The absolute path to the project directory or the path to `tsconfig.json`.
16
+ * @throws {CMKDisabledError} When css-modules-kit is disabled.
6
17
  * @throws {ReadCSSModuleFileError} When failed to read CSS Module file.
7
18
  * @throws {WriteDtsFileError}
19
+ * @returns Whether the process succeeded without errors.
8
20
  */
9
- export declare function runCMK(args: ParsedArgs, logger: Logger): Promise<void>;
21
+ export declare function runCMK(args: RunnerArgs, logger: Logger): Promise<boolean>;
22
+ /**
23
+ * Run css-modules-kit .d.ts generation in watch mode.
24
+ *
25
+ * The promise resolves when the initial diagnostics report, emit, and watcher initialization are complete.
26
+ * Errors are reported through the logger.
27
+ *
28
+ * NOTE: For implementation simplicity, config file changes are not watched.
29
+ * @param project The absolute path to the project directory or the path to `tsconfig.json`.
30
+ * @throws {CMKDisabledError} When css-modules-kit is disabled.
31
+ * @throws {TsConfigFileNotFoundError}
32
+ * @throws {ReadCSSModuleFileError}
33
+ * @throws {WriteDtsFileError}
34
+ */
35
+ export declare function runCMKInWatchMode(args: RunnerArgs, logger: Logger): Promise<Watcher>;
36
+ export {};
10
37
  //# sourceMappingURL=runner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAoCjD;;;;;GAKG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiE5E"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAE3D,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,OAAO;IACtB,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAgB/E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA6G1F"}
package/dist/runner.js CHANGED
@@ -1,92 +1,157 @@
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.runCMK = runCMK;
7
- const promises_1 = require("node:fs/promises");
8
- const core_1 = require("@css-modules-kit/core");
9
- const typescript_1 = __importDefault(require("typescript"));
10
- const dts_writer_js_1 = require("./dts-writer.js");
11
- const error_js_1 = require("./error.js");
1
+ import { rm } from 'node:fs/promises';
2
+ import chokidar from 'chokidar';
3
+ import { CMKDisabledError } from './error.js';
4
+ import { createProject } from './project.js';
12
5
  /**
6
+ * Run css-modules-kit .d.ts generation.
7
+ * @param project The absolute path to the project directory or the path to `tsconfig.json`.
8
+ * @throws {CMKDisabledError} When css-modules-kit is disabled.
13
9
  * @throws {ReadCSSModuleFileError} When failed to read CSS Module file.
10
+ * @throws {WriteDtsFileError}
11
+ * @returns Whether the process succeeded without errors.
14
12
  */
15
- async function parseCSSModuleByFileName(fileName, config) {
16
- let text;
17
- try {
18
- text = await (0, promises_1.readFile)(fileName, 'utf-8');
13
+ export async function runCMK(args, logger) {
14
+ const project = createProject(args);
15
+ if (project.config.enabled === false) {
16
+ throw new CMKDisabledError(project.config);
19
17
  }
20
- catch (error) {
21
- throw new error_js_1.ReadCSSModuleFileError(fileName, error);
18
+ if (args.clean) {
19
+ await rm(project.config.dtsOutDir, { recursive: true, force: true });
22
20
  }
23
- return (0, core_1.parseCSSModule)(text, { fileName, safe: false, keyframes: config.keyframes });
24
- }
25
- /**
26
- * @throws {WriteDtsFileError}
27
- */
28
- async function writeDtsByCSSModule(cssModule, { dtsOutDir, basePath, arbitraryExtensions, namedExports, prioritizeNamedImports }, resolver, matchesPattern) {
29
- const dts = (0, core_1.createDts)(cssModule, { resolver, matchesPattern }, { namedExports, prioritizeNamedImports, forTsPlugin: false });
30
- await (0, dts_writer_js_1.writeDtsFile)(dts.text, cssModule.fileName, {
31
- outDir: dtsOutDir,
32
- basePath,
33
- arbitraryExtensions,
34
- });
21
+ await project.emitDtsFiles();
22
+ const diagnostics = project.getDiagnostics();
23
+ if (diagnostics.length > 0) {
24
+ logger.logDiagnostics(diagnostics);
25
+ const hasErrors = diagnostics.some((d) => d.category === 'error');
26
+ return !hasErrors;
27
+ }
28
+ return true;
35
29
  }
36
30
  /**
37
- * Run css-modules-kit .d.ts generation.
31
+ * Run css-modules-kit .d.ts generation in watch mode.
32
+ *
33
+ * The promise resolves when the initial diagnostics report, emit, and watcher initialization are complete.
34
+ * Errors are reported through the logger.
35
+ *
36
+ * NOTE: For implementation simplicity, config file changes are not watched.
38
37
  * @param project The absolute path to the project directory or the path to `tsconfig.json`.
39
- * @throws {ReadCSSModuleFileError} When failed to read CSS Module file.
38
+ * @throws {CMKDisabledError} When css-modules-kit is disabled.
39
+ * @throws {TsConfigFileNotFoundError}
40
+ * @throws {ReadCSSModuleFileError}
40
41
  * @throws {WriteDtsFileError}
41
42
  */
42
- async function runCMK(args, logger) {
43
- const config = (0, core_1.readConfigFile)(args.project);
44
- if (config.diagnostics.length > 0) {
45
- logger.logDiagnostics(config.diagnostics);
46
- // eslint-disable-next-line n/no-process-exit
47
- process.exit(1);
43
+ export async function runCMKInWatchMode(args, logger) {
44
+ const fsWatchers = [];
45
+ const project = createProject(args);
46
+ if (project.config.enabled === false) {
47
+ throw new CMKDisabledError(project.config);
48
48
  }
49
- const getCanonicalFileName = (fileName) => typescript_1.default.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
50
- const moduleResolutionCache = typescript_1.default.createModuleResolutionCache(config.basePath, getCanonicalFileName, config.compilerOptions);
51
- const resolver = (0, core_1.createResolver)(config.compilerOptions, moduleResolutionCache);
52
- const matchesPattern = (0, core_1.createMatchesPattern)(config);
53
- const cssModuleMap = new Map();
54
- const syntacticDiagnostics = [];
55
- const fileNames = (0, core_1.getFileNamesByPattern)(config);
56
- if (fileNames.length === 0) {
57
- logger.logDiagnostics([
58
- {
59
- category: 'warning',
60
- text: `The file specified in tsconfig.json not found.`,
61
- },
62
- ]);
63
- return;
64
- }
65
- const parseResults = await Promise.all(fileNames.map(async (fileName) => parseCSSModuleByFileName(fileName, config)));
66
- for (const parseResult of parseResults) {
67
- cssModuleMap.set(parseResult.cssModule.fileName, parseResult.cssModule);
68
- syntacticDiagnostics.push(...parseResult.diagnostics);
49
+ let emitAndReportDiagnosticsTimer = undefined;
50
+ if (args.clean) {
51
+ await rm(project.config.dtsOutDir, { recursive: true, force: true });
69
52
  }
70
- if (syntacticDiagnostics.length > 0) {
71
- logger.logDiagnostics(syntacticDiagnostics);
72
- // eslint-disable-next-line n/no-process-exit
73
- process.exit(1);
53
+ await emitAndReportDiagnostics();
54
+ // Watch project files and report diagnostics on changes
55
+ const readyPromises = [];
56
+ for (const wildcardDirectory of project.config.wildcardDirectories) {
57
+ const { promise, resolve } = promiseWithResolvers();
58
+ readyPromises.push(promise);
59
+ fsWatchers.push(chokidar
60
+ .watch(wildcardDirectory.fileName, {
61
+ ignored: (fileName, stats) => {
62
+ // The ignored function is called twice for the same path. The first time with stats undefined,
63
+ // and the second time with stats provided.
64
+ // In the first call, we can't determine if the path is a directory or file.
65
+ // So we include it in the watch target considering it might be a directory.
66
+ if (!stats)
67
+ return false;
68
+ // In the second call, we include directories or files that match wildcards in the watch target.
69
+ // However, `dtsOutDir` is excluded from the watch target.
70
+ if (stats.isDirectory()) {
71
+ return fileName === project.config.dtsOutDir;
72
+ }
73
+ else {
74
+ return !project.isWildcardMatchedFile(fileName);
75
+ }
76
+ },
77
+ ignoreInitial: true,
78
+ ...(wildcardDirectory.recursive ? {} : { depth: 0 }),
79
+ })
80
+ .on('add', (fileName) => {
81
+ try {
82
+ project.addFile(fileName);
83
+ }
84
+ catch (e) {
85
+ logger.logError(e);
86
+ return;
87
+ }
88
+ scheduleEmitAndReportDiagnostics();
89
+ })
90
+ .on('change', (fileName) => {
91
+ try {
92
+ project.updateFile(fileName);
93
+ }
94
+ catch (e) {
95
+ logger.logError(e);
96
+ return;
97
+ }
98
+ scheduleEmitAndReportDiagnostics();
99
+ })
100
+ .on('unlink', (fileName) => {
101
+ project.removeFile(fileName);
102
+ scheduleEmitAndReportDiagnostics();
103
+ })
104
+ .on('error', (e) => logger.logError(e))
105
+ .on('ready', () => resolve()));
74
106
  }
75
- const getCSSModule = (path) => cssModuleMap.get(path);
76
- const exportBuilder = (0, core_1.createExportBuilder)({ getCSSModule, matchesPattern, resolver });
77
- const semanticDiagnostics = [];
78
- for (const { cssModule } of parseResults) {
79
- const diagnostics = (0, core_1.checkCSSModule)(cssModule, config, exportBuilder, matchesPattern, resolver, getCSSModule);
80
- semanticDiagnostics.push(...diagnostics);
107
+ await Promise.all(readyPromises);
108
+ function scheduleEmitAndReportDiagnostics() {
109
+ // Switching between git branches results in numerous file changes occurring rapidly.
110
+ // Reporting diagnostics for each file change would overwhelm users.
111
+ // Therefore, we batch the processing.
112
+ if (emitAndReportDiagnosticsTimer !== undefined)
113
+ clearTimeout(emitAndReportDiagnosticsTimer);
114
+ emitAndReportDiagnosticsTimer = setTimeout(() => {
115
+ emitAndReportDiagnosticsTimer = undefined;
116
+ emitAndReportDiagnostics().catch(logger.logError.bind(logger));
117
+ }, 250);
81
118
  }
82
- if (semanticDiagnostics.length > 0) {
83
- logger.logDiagnostics(semanticDiagnostics);
84
- // eslint-disable-next-line n/no-process-exit
85
- process.exit(1);
119
+ /**
120
+ * @throws {WriteDtsFileError}
121
+ */
122
+ async function emitAndReportDiagnostics() {
123
+ if (!args.preserveWatchOutput) {
124
+ logger.clearScreen();
125
+ }
126
+ await project.emitDtsFiles();
127
+ const diagnostics = project.getDiagnostics();
128
+ if (diagnostics.length > 0) {
129
+ logger.logDiagnostics(diagnostics);
130
+ }
131
+ const errorCount = diagnostics.filter((d) => d.category === 'error').length;
132
+ const warningCount = diagnostics.filter((d) => d.category === 'warning').length;
133
+ const warningPart = warningCount > 0 ? ` and ${warningCount} warning${warningCount === 1 ? '' : 's'}` : '';
134
+ logger.logMessage(`Found ${errorCount} error${errorCount === 1 ? '' : 's'}${warningPart}. Watching for file changes.`, { time: true });
135
+ if (args.preserveWatchOutput) {
136
+ logger.logMessage('');
137
+ }
86
138
  }
87
- if (args.clean) {
88
- await (0, promises_1.rm)(config.dtsOutDir, { recursive: true, force: true });
139
+ async function close() {
140
+ await Promise.all(fsWatchers.map(async (watcher) => watcher.close()));
89
141
  }
90
- await Promise.all(parseResults.map(async (parseResult) => writeDtsByCSSModule(parseResult.cssModule, config, resolver, matchesPattern)));
142
+ return { project, close };
143
+ }
144
+ function promiseWithResolvers() {
145
+ let resolve;
146
+ let reject;
147
+ const promise = new Promise((res, rej) => {
148
+ resolve = res;
149
+ reject = rej;
150
+ });
151
+ return {
152
+ promise,
153
+ resolve: resolve,
154
+ reject: reject,
155
+ };
91
156
  }
92
157
  //# sourceMappingURL=runner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@css-modules-kit/codegen",
3
3
  "description": "A tool for generating `*.d.ts` files for `*.module.css`.",
4
- "version": "0.6.0",
5
- "type": "commonjs",
4
+ "version": "0.8.0",
5
+ "type": "module",
6
6
  "sideEffects": false,
7
7
  "repository": {
8
8
  "type": "git",
@@ -23,7 +23,7 @@
23
23
  "registry": "https://registry.npmjs.org/"
24
24
  },
25
25
  "bin": {
26
- "cmk": "bin/cmk.mjs"
26
+ "cmk": "bin/cmk.js"
27
27
  },
28
28
  "keywords": [
29
29
  "css-modules",
@@ -38,7 +38,8 @@
38
38
  "dist"
39
39
  ],
40
40
  "dependencies": {
41
- "@css-modules-kit/core": "^0.6.0"
41
+ "@css-modules-kit/core": "^0.8.0",
42
+ "chokidar": "^4.0.3"
42
43
  },
43
44
  "peerDependencies": {
44
45
  "typescript": "^5.7.3"
package/src/cli.ts CHANGED
@@ -1,17 +1,20 @@
1
1
  import { parseArgs } from 'node:util';
2
2
  import { resolve } from '@css-modules-kit/core';
3
- import packageJson from '../package.json';
3
+ import packageJson from '../package.json' with { type: 'json' };
4
4
  import { ParseCLIArgsError } from './error.js';
5
5
 
6
+ // NOTE: Keep this help text in sync with the one in packages/codegen/README.md.
6
7
  const helpText = `
7
8
  Usage: cmk [options]
8
9
 
9
10
  Options:
10
- --help, -h Show help information
11
- --version, -v Show version number
12
- --project, -p The path to its configuration file, or to a folder with a 'tsconfig.json'.
13
- --pretty Enable color and formatting in output to make errors easier to read.
14
- --clean Remove the output directory before generating files. [default: false]
11
+ --help, -h Show help information
12
+ --version, -v Show version number
13
+ --project, -p The path to its configuration file, or to a folder with a 'tsconfig.json'.
14
+ --pretty Enable color and formatting in output to make errors easier to read.
15
+ --clean Remove the output directory before generating files. [default: false]
16
+ --watch, -w Watch for changes and regenerate files. [default: false]
17
+ --preserveWatchOutput Disable wiping the console in watch mode. [default: false]
15
18
  `;
16
19
 
17
20
  export function printHelpText(): void {
@@ -30,6 +33,8 @@ export interface ParsedArgs {
30
33
  project: string;
31
34
  pretty: boolean | undefined;
32
35
  clean: boolean;
36
+ watch: boolean;
37
+ preserveWatchOutput: boolean;
33
38
  }
34
39
 
35
40
  /**
@@ -46,6 +51,8 @@ export function parseCLIArgs(args: string[], cwd: string): ParsedArgs {
46
51
  project: { type: 'string', short: 'p', default: '.' },
47
52
  pretty: { type: 'boolean' },
48
53
  clean: { type: 'boolean', default: false },
54
+ watch: { type: 'boolean', short: 'w', default: false },
55
+ preserveWatchOutput: { type: 'boolean', default: false },
49
56
  },
50
57
  allowNegative: true,
51
58
  });
@@ -55,6 +62,8 @@ export function parseCLIArgs(args: string[], cwd: string): ParsedArgs {
55
62
  project: resolve(cwd, values.project),
56
63
  pretty: values.pretty,
57
64
  clean: values.clean,
65
+ watch: values.watch,
66
+ preserveWatchOutput: values.preserveWatchOutput,
58
67
  };
59
68
  } catch (cause) {
60
69
  throw new ParseCLIArgsError(cause);
package/src/error.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { SystemError } from '@css-modules-kit/core';
1
+ import type { CMKConfig } from '@css-modules-kit/core';
2
+ import { relative, SystemError } from '@css-modules-kit/core';
2
3
 
3
4
  export class ParseCLIArgsError extends SystemError {
4
5
  constructor(cause: unknown) {
@@ -17,3 +18,12 @@ export class ReadCSSModuleFileError extends SystemError {
17
18
  super('READ_CSS_MODULE_FILE_ERROR', `Failed to read CSS Module file ${fileName}.`, cause);
18
19
  }
19
20
  }
21
+
22
+ export class CMKDisabledError extends SystemError {
23
+ constructor(config: CMKConfig) {
24
+ super(
25
+ 'CMK_DISABLED_ERROR',
26
+ `css-modules-kit is disabled by configuration. Set \`"cmkOptions": { "enabled": true }\` in ${relative(config.basePath, config.configFileName)} to enable it.`,
27
+ );
28
+ }
29
+ }
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { runCMK } from './runner.js';
1
+ export { runCMK, runCMKInWatchMode } from './runner.js';
2
2
  export { type Logger, createLogger } from './logger/logger.js';
3
- export { WriteDtsFileError, ReadCSSModuleFileError } from './error.js';
3
+ export { WriteDtsFileError, ReadCSSModuleFileError, CMKDisabledError } from './error.js';
4
4
  export { parseCLIArgs, printHelpText, printVersion } from './cli.js';
5
5
  export { shouldBePretty } from './3rd-party/typescript.js';
@@ -1,5 +1,8 @@
1
1
  import ts from 'typescript';
2
2
 
3
+ const GRAY = '\u001b[90m';
4
+ const RESET = '\u001b[0m';
5
+
3
6
  export function formatDiagnostics(
4
7
  diagnostics: ts.Diagnostic[],
5
8
  host: ts.FormatDiagnosticsHost,
@@ -12,3 +15,12 @@ export function formatDiagnostics(
12
15
  }
13
16
  return result;
14
17
  }
18
+
19
+ export function formatTime(date: Date, pretty: boolean): string {
20
+ const text = date.toLocaleTimeString('en-US', { timeZone: 'UTC' });
21
+ if (pretty) {
22
+ return `[${GRAY}${text}${RESET}]`;
23
+ } else {
24
+ return `[${text}]`;
25
+ }
26
+ }