Skip to content
This repository was archived by the owner on Mar 7, 2025. It is now read-only.

Commit 01c4a95

Browse files
committed
Add generate rule script
1 parent fa0d0ce commit 01c4a95

File tree

3 files changed

+102
-1
lines changed

3 files changed

+102
-1
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ module.exports = defineConfig({
8282
skipWords: [
8383
'amd',
8484
'applescript',
85+
'argv',
8586
'asyncgenerator',
8687
'asynciterable',
8788
'atomtest',

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"check": "tsc",
99
"format": "prettier --write .",
1010
"lint": "eslint .",
11-
"prepublishOnly": "yarn clean && yarn install --cache-folder .yarn && yarn check"
11+
"prepublishOnly": "yarn clean && yarn install --cache-folder .yarn && yarn check",
12+
"generate": "node ./scripts/generate-rule.js"
1213
},
1314
"keywords": [
1415
"config",

scripts/generate-rule.js

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/* eslint-disable */
2+
3+
const fs = require('fs');
4+
const path = require('path');
5+
6+
const rulesDir = path.resolve(__dirname, '../src/rules');
7+
8+
const ruleNameInput = process.argv[2];
9+
if (!ruleNameInput) {
10+
console.warn('No rule name provided');
11+
return;
12+
}
13+
14+
let ruleProvider = 'eslint';
15+
let ruleName = ruleNameInput;
16+
17+
if (ruleNameInput.includes('/')) {
18+
const parts = ruleNameInput.split('/');
19+
ruleProvider = parts[0];
20+
ruleName = parts[1];
21+
}
22+
23+
function normalizeRuleProvider(provider) {
24+
if (provider.startsWith('@')) {
25+
return provider.slice(1);
26+
}
27+
return provider;
28+
}
29+
30+
console.log({ ruleName, ruleProvider });
31+
32+
const ruleProviderDir = path.resolve(rulesDir, normalizeRuleProvider(ruleProvider));
33+
const rulePath = path.resolve(ruleProviderDir, `${ruleName}.d.ts`);
34+
35+
/**
36+
* @param {string} name
37+
* @param {string} provider
38+
*/
39+
function generateRuleFileContent(name, provider) {
40+
const PascalCase = name.replace(/(\w)(\w*)/g, (_, g1, g2) => g1.toUpperCase() + g2.toLowerCase()).replace(/-/g, '');
41+
const kebabCase = name;
42+
43+
let RuleLink = '<RuleLink>';
44+
switch (provider) {
45+
case 'eslint':
46+
RuleLink = `https://eslint.org/docs/rules/${kebabCase}`;
47+
break;
48+
case '@typescript-eslint':
49+
RuleLink = `https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/${kebabCase}.md`;
50+
break;
51+
}
52+
53+
provider = provider === 'eslint' ? '' : `${provider}/`;
54+
55+
return `import type { RuleConfig } from '../rule-config';
56+
57+
/**
58+
* Option.
59+
*/
60+
export type ${PascalCase}Option = {
61+
/**
62+
* <OptionDescription>.
63+
*
64+
* @default '<default>'
65+
*
66+
* @see [example](<OptionLink>)
67+
*/
68+
example: string;
69+
};
70+
71+
/**
72+
* Options.
73+
*/
74+
export type ${PascalCase}Options = [${PascalCase}Option?];
75+
76+
/**
77+
* <RuleDescription>.
78+
*
79+
* @see [${kebabCase}](${RuleLink})
80+
*/
81+
export type ${PascalCase}RuleConfig = RuleConfig<${PascalCase}Options>;
82+
83+
/**
84+
* <RuleDescription>.
85+
*
86+
* @see [${kebabCase}](${RuleLink})
87+
*/
88+
export interface ${PascalCase}Rule {
89+
/**
90+
* <RuleDescription>.
91+
*
92+
* @see [${kebabCase}](${RuleLink})
93+
*/
94+
'${provider}${kebabCase}': ${PascalCase}RuleConfig;
95+
}
96+
`;
97+
}
98+
99+
fs.writeFileSync(rulePath, generateRuleFileContent(ruleName, ruleProvider));

0 commit comments

Comments
 (0)