Skip to content

Commit cf4ae99

Browse files
playing with settings
1 parent 9e929a0 commit cf4ae99

File tree

3 files changed

+54
-15
lines changed

3 files changed

+54
-15
lines changed

docs/rules/my-rule.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,14 @@ Examples would normally go here.
1616

1717
<!-- begin auto-generated rule options list -->
1818

19-
| Name | Description | Type | Choices | Default |
20-
| :--------- | :-------------------- | :------ | :---------------- | :------- |
21-
| `someBool` | someBool description. | Boolean | | `true` |
22-
| `someEnum` | someEnum description. | String | `always`, `never` | `always` |
19+
| Name | Description | Type | Choices | Default |
20+
| :------------------- | :------------------------------------------------------------------- | :------- | :---------------- | :--------------------- |
21+
| `callees` | List of function names to validate classnames | String[] | | [`ctl`] |
22+
| `cssConfigPath` | Path to the Tailwind CSS configuration file (*.css) | String | | `default-path/app.css` |
23+
| `removeDuplicates` | Remove duplicated classnames | Boolean | | `true` |
24+
| `skipClassAttribute` | If you only want to lint the classnames inside one of the `callees`. | Boolean | | `false` |
25+
| `someBool` | someBool description. | Boolean | | `true` |
26+
| `someEnum` | someEnum description. | String | `always`, `never` | `always` |
27+
| `tags` | List of tags to be detected in template literals | String[] | | [`tw`] |
2328

2429
<!-- end auto-generated rule options list -->

src/rules/my-rule.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ ruleTester.run(RULE_NAME, myRule, {
1919
{
2020
// a code snippet that should pass the linter
2121
code: `const x = 5;`,
22+
options: [
23+
{
24+
callees: ["ctl2"],
25+
someBool: true,
26+
someEnum: "always",
27+
},
28+
],
2229
},
2330
{
2431
code: `let y = 'abc123';`,

src/rules/my-rule.ts

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ import { RuleCreator } from "@typescript-eslint/utils/eslint-utils";
22

33
import { PluginSharedSettings } from "../types";
44
import urlCreator from "../url-creator";
5+
import {
6+
DEFAULTS,
7+
parsePluginSettings,
8+
type PluginSettings,
9+
sharedSettingsSchema,
10+
} from "../utils/parse-plugin-settings";
511

612
export { ESLintUtils } from "@typescript-eslint/utils";
713

@@ -10,13 +16,18 @@ export const RULE_NAME = "my-rule";
1016
// Message IDs don't need to be prefixed, I just find it easier to keep track of them this way
1117
type MessageIds = "issue:var" | "fix:let" | "fix:const";
1218

13-
// The options that the rule can take
14-
type Options = [
15-
{
16-
someBool: boolean;
17-
someEnum: string;
18-
}
19-
];
19+
/**
20+
* The extra options that the rule can accept.
21+
* These options are merged with the shared settings.
22+
* The typing is not used by `eslint-doc-generator` which uses the `schema` property in the rule's metadata.
23+
* Yet, it is useful for the IDE to provide autocompletion and type checking.
24+
*/
25+
export type RuleOptions = {
26+
someBool: boolean;
27+
someEnum: string;
28+
} & PluginSettings;
29+
30+
type Options = [RuleOptions];
2031

2132
// The Rule creator returns a function that is used to create a well-typed ESLint rule
2233
// The parameter passed into RuleCreator is a URL generator function.
@@ -34,10 +45,12 @@ export const myRule = createRule<Options, MessageIds>({
3445
"fix:let": "Replace this `var` declaration with `let`",
3546
"fix:const": "Replace this `var` declaration with `const`",
3647
},
48+
// Schema is also parsed by `eslint-doc-generator`
3749
schema: [
3850
{
3951
type: "object",
4052
properties: {
53+
...sharedSettingsSchema,
4154
someBool: {
4255
description: "someBool description.",
4356
type: "boolean",
@@ -62,21 +75,35 @@ export const myRule = createRule<Options, MessageIds>({
6275
* - If some configuration is provided as the second argument, it is ignored, not merged
6376
* - In other words, the `defaultOptions` is only used when the rule is used without configuration
6477
*/
65-
defaultOptions: [{ someBool: false, someEnum: "always" }],
78+
defaultOptions: [
79+
{
80+
...DEFAULTS,
81+
someBool: false,
82+
someEnum: "always",
83+
},
84+
],
6685
create: (context, options) => {
6786
return {
6887
VariableDeclaration: (node) => {
6988
if (node.kind === "var") {
7089
// Reading inline configuration
71-
console.log("\n", "Options:", "\n", options[0]);
72-
90+
console.log(
91+
"\n",
92+
new Date(),
93+
"\n",
94+
"Options (rule):",
95+
"\n",
96+
options[0]
97+
);
7398
// Shared settings
7499
const sharedSettings = (context.settings?.tailwindcss || {
75100
stylesheet: "",
76101
functions: [],
77102
}) as PluginSharedSettings;
78-
console.log("\n", "sharedSettings:", "\n", sharedSettings);
103+
console.log("\n", "sharedSettings (rule):", "\n", sharedSettings);
79104

105+
const merged: PluginSettings = parsePluginSettings(context.settings);
106+
console.log("\n", "merged (rule):", "\n", merged);
80107
const rangeStart = node.range[0];
81108
const range: readonly [number, number] = [
82109
rangeStart,

0 commit comments

Comments
 (0)