Skip to content

Commit

Permalink
feat: add no-missing-ts-file rule
Browse files Browse the repository at this point in the history
  • Loading branch information
mizdra committed Jan 18, 2025
1 parent 07fdb6d commit 3cab546
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 1 deletion.
1 change: 1 addition & 0 deletions example/stylelint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ export default {
plugins: ['stylelint-plugin-honey-css-modules'],
rules: {
'honey-css-modules/no-unused-class-names': true,
'honey-css-modules/no-missing-ts-file': true,
},
};
3 changes: 2 additions & 1 deletion packages/stylelint-plugin/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { noMissingTsFile } from './rules/no-missing-ts-file.js';
import { noUnusedClassNames } from './rules/no-unused-class-names.js';

export = [noUnusedClassNames];
export = [noUnusedClassNames, noMissingTsFile];
59 changes: 59 additions & 0 deletions packages/stylelint-plugin/src/rules/no-missing-ts-file.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import stylelint from 'stylelint';
import { describe, expect, test } from 'vitest';
import { createIFF } from '../test/fixture.js';
import { formatLinterResult } from '../test/stylelint.js';
import { noMissingTsFile } from './no-missing-ts-file.js';

async function lint(rootDir: string) {
return stylelint.lint({
config: {
plugins: [noMissingTsFile],
rules: {
'honey-css-modules/no-missing-ts-file': true,
},
},
files: ['**/*.module.css'],
cwd: rootDir,
});
}

describe('no-missing-ts-file', () => {
test('warns missing ts file', async () => {
const iff = await createIFF({
'a.module.css': '.foo {}',
});
const results = await lint(iff.rootDir);
expect(formatLinterResult(results, iff.rootDir)).toMatchInlineSnapshot(`
[
{
"source": "<rootDir>/a.module.css",
"warnings": [
{
"column": 1,
"endColumn": 2,
"endLine": 1,
"line": 1,
"rule": "honey-css-modules/no-missing-ts-file",
"text": "The corresponding TypeScript file is not found. (honey-css-modules/no-missing-ts-file)",
},
],
},
]
`);
});
test('does not warn when ts file exists', async () => {
const iff = await createIFF({
'a.module.css': '',
'a.ts': '',
});
const results = await lint(iff.rootDir);
expect(formatLinterResult(results, iff.rootDir)).toMatchInlineSnapshot(`
[
{
"source": "<rootDir>/a.module.css",
"warnings": [],
},
]
`);
});
});
44 changes: 44 additions & 0 deletions packages/stylelint-plugin/src/rules/no-missing-ts-file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { Rule } from 'stylelint';
import stylelint from 'stylelint';
import { readTsFile } from '../util.js';

// TODO: Report cjs-module-lexer compatibility problem to stylelint
const { createPlugin, utils } = stylelint;

const ruleName = 'honey-css-modules/no-missing-ts-file';

const messages = utils.ruleMessages(ruleName, {
disallow: () => `The corresponding TypeScript file is not found.`,
});

const meta = {
url: 'https://github.com/mizdra/honey-css-modules/blob/main/packages/stylelint-plugin-honey-css-modules/docs/rules/no-missing-ts-file.md',
};

const ruleFunction: Rule = (_primaryOptions, _secondaryOptions, _context) => {
return async (root, result) => {
if (root.source?.input.file === undefined) return;
const cssModulePath = root.source.input.file;

if (!cssModulePath.endsWith('.module.css')) return;

const tsFile = await readTsFile(cssModulePath);

if (tsFile === undefined) {
utils.report({
result,
ruleName,
message: messages.disallow(),
node: root,
index: 0,
endIndex: 0,
});
}
};
};

ruleFunction.ruleName = ruleName;
ruleFunction.messages = messages;
ruleFunction.meta = meta;

export const noMissingTsFile = createPlugin(ruleName, ruleFunction);

0 comments on commit 3cab546

Please sign in to comment.