Repository: stylelint/vscode-stylelint (ts)

Issue:
Unexpected option value "false" for rule "no-eol-whitespace"
When the client triggers document formatting with the `trimTrailingWhitespace` option set to `false`, for example:

```
textDocument/formatting(3):
{
  "textDocument": {
    "uri": "file:///usr/local/workspace/temp/Website/src/styles/style.css"
  },
  "workDoneToken": "wd3",
  "options": {
    "insertFinalNewline": true,
    "trimTrailingWhitespace": false,
    "trimFinalNewlines": true,
    "tabSize": 4,
    "insertSpaces": false
  }
}
```

then the server adds reference to the `no-eol-whitespace` rule with value `false` in here:

https://github.com/stylelint/vscode-stylelint/blob/d79b3a7b5585cbe74317fd59d36d73ff2d896d45/src/utils/stylelint/formatting-options-to-rules.ts#L27-L29

But value `false` is invalid and triggers:

> Unexpected option value "false" for rule "no-eol-whitespace"

It needs to be `null` to disable the rule.

Pull request description:
fix: don't pass invalid "false" rule value when formatting
<!-- Each pull request must be associated with an open issue unless it's a documentation fix. If a corresponding issue does not exist, please create one so we can discuss the change first. -->

<!-- Please answer the following. We close pull requests that don't. -->

> Which issue, if any, is this issue related to?

Closes #398

> Is there anything in the PR that needs further explanation?

"No, it's self-explanatory."


Patch:
diff --git a/package-lock.json b/package-lock.json
index bae0c92..c2e93c4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,7 +6,7 @@
   "packages": {
     "": {
       "name": "vscode-stylelint",
-      "version": "1.2.1",
+      "version": "1.2.2",
       "license": "MIT",
       "dependencies": {
         "@types/triple-beam": "^1.3.2",
@@ -19,7 +19,7 @@
         "vscode-languageclient": "^7.0.0",
         "vscode-languageserver": "^7.0.0",
         "vscode-languageserver-protocol": "^3.16.0",
-        "vscode-languageserver-textdocument": "^1.0.3",
+        "vscode-languageserver-textdocument": "^1.0.5",
         "vscode-languageserver-types": "^3.16.0",
         "vscode-uri": "^3.0.2",
         "winston": "^3.3.3",
@@ -35,7 +35,7 @@
         "@types/semver": "^7.3.9",
         "@types/vscode": "1.56.0",
         "@typescript-eslint/eslint-plugin": "^5.5.0",
-        "@typescript-eslint/parser": "^5.5.0",
+        "@typescript-eslint/parser": "^5.30.5",
         "@typescript/lib-dom": "npm:@types/web@^0.0.47",
         "@vscode/test-electron": "^1.6.2",
         "cspell": "^5.13.1",
@@ -2055,15 +2055,15 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.5.0.tgz",
-      "integrity": "sha512-JsXBU+kgQOAgzUn2jPrLA+Rd0Y1dswOlX3hp8MuRO1hQDs6xgHtbCXEiAu7bz5hyVURxbXcA2draasMbNqrhmg==",
+      "version": "5.30.5",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.5.tgz",
+      "integrity": "sha512-zj251pcPXI8GO9NDKWWmygP6+UjwWmrdf9qMW/L/uQJBM/0XbU2inxe5io/234y/RCvwpKEYjZ6c1YrXERkK4Q==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "5.5.0",
-        "@typescript-eslint/types": "5.5.0",
-        "@typescript-eslint/typescript-estree": "5.5.0",
-        "debug": "^4.3.2"
+        "@typescript-eslint/scope-manager": "5.30.5",
+        "@typescript-eslint/types": "5.30.5",
+        "@typescript-eslint/typescript-estree": "5.30.5",
+        "debug": "^4.3.4"
       },
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -2081,6 +2081,89 @@
         }
       }
     },
+    "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": {
+      "version": "5.30.5",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.5.tgz",
+      "integrity": "sha512-NJ6F+YHHFT/30isRe2UTmIGGAiXKckCyMnIV58cE3JkHmaD6e5zyEYm5hBDv0Wbin+IC0T1FWJpD3YqHUG/Ydg==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/types": "5.30.5",
+        "@typescript-eslint/visitor-keys": "5.30.5"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": {
+      "version": "5.30.5",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.5.tgz",
+      "integrity": "sha512-kZ80w/M2AvsbRvOr3PjaNh6qEW1LFqs2pLdo2s5R38B2HYXG8Z0PP48/4+j1QHJFL3ssHIbJ4odPRS8PlHrFfw==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": {
+      "version": "5.30.5",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.5.tgz",
+      "integrity": "sha512-qGTc7QZC801kbYjAr4AgdOfnokpwStqyhSbiQvqGBLixniAKyH+ib2qXIVo4P9NgGzwyfD9I0nlJN7D91E1VpQ==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/types": "5.30.5",
+        "@typescript-eslint/visitor-keys": "5.30.5",
+        "debug": "^4.3.4",
+        "globby": "^11.1.0",
+        "is-glob": "^4.0.3",
+        "semver": "^7.3.7",
+        "tsutils": "^3.21.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": {
+      "version": "5.30.5",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.5.tgz",
+      "integrity": "sha512-D+xtGo9HUMELzWIUqcQc0p2PO4NyvTrgIOK/VnSH083+8sq0tiLozNRKuLarwHYGRuA6TVBQSuuLwJUDWd3aaA==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/types": "5.30.5",
+        "eslint-visitor-keys": "^3.3.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
+      "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      }
+    },
     "node_modules/@typescript-eslint/scope-manager": {
       "version": "5.5.0",
       "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.5.0.tgz",
@@ -3298,9 +3381,9 @@
       }
     },
     "node_modules/debug": {
-      "version": "4.3.3",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
-      "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
       "dev": true,
       "dependencies": {
         "ms": "2.1.2"
@@ -7943,9 +8026,9 @@
       }
     },
     "node_modules/minimist": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
       "dev": true
     },
     "node_modules/minimist-options": {
@@ -9196,9 +9279,9 @@
       }
     },
     "node_modules/semver": {
-      "version": "7.3.5",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+      "version": "7.3.7",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
       "dependencies": {
         "lru-cache": "^6.0.0"
       },
@@ -10432,9 +10515,9 @@
       }
     },
     "node_modules/vscode-languageserver-textdocument": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.3.tgz",
-      "integrity": "sha512-ynEGytvgTb6HVSUwPJIAZgiHQmPCx8bZ8w5um5Lz+q5DjP0Zj8wTFhQpyg8xaMvefDytw2+HH5yzqS+FhsR28A=="
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.5.tgz",
+      "integrity": "sha512-1ah7zyQjKBudnMiHbZmxz5bYNM9KKZYz+5VQLj+yr8l+9w3g+WAhCkUkWbhMEdC5u0ub4Ndiye/fDyS8ghIKQg=="
     },
     "node_modules/vscode-languageserver-types": {
       "version": "3.16.0",
@@ -12401,15 +12484,64 @@
       }
     },
     "@typescript-eslint/parser": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.5.0.tgz",
-      "integrity": "sha512-JsXBU+kgQOAgzUn2jPrLA+Rd0Y1dswOlX3hp8MuRO1hQDs6xgHtbCXEiAu7bz5hyVURxbXcA2draasMbNqrhmg==",
+      "version": "5.30.5",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.5.tgz",
+      "integrity": "sha512-zj251pcPXI8GO9NDKWWmygP6+UjwWmrdf9qMW/L/uQJBM/0XbU2inxe5io/234y/RCvwpKEYjZ6c1YrXERkK4Q==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/scope-manager": "5.5.0",
-        "@typescript-eslint/types": "5.5.0",
-        "@typescript-eslint/typescript-estree": "5.5.0",
-        "debug": "^4.3.2"
+        "@typescript-eslint/scope-manager": "5.30.5",
+        "@typescript-eslint/types": "5.30.5",
+        "@typescript-eslint/typescript-estree": "5.30.5",
+        "debug": "^4.3.4"
+      },
+      "dependencies": {
+        "@typescript-eslint/scope-manager": {
+          "version": "5.30.5",
+          "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.5.tgz",
+          "integrity": "sha512-NJ6F+YHHFT/30isRe2UTmIGGAiXKckCyMnIV58cE3JkHmaD6e5zyEYm5hBDv0Wbin+IC0T1FWJpD3YqHUG/Ydg==",
+          "dev": true,
+          "requires": {
+            "@typescript-eslint/types": "5.30.5",
+            "@typescript-eslint/visitor-keys": "5.30.5"
+          }
+        },
+        "@typescript-eslint/types": {
+          "version": "5.30.5",
+          "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.5.tgz",
+          "integrity": "sha512-kZ80w/M2AvsbRvOr3PjaNh6qEW1LFqs2pLdo2s5R38B2HYXG8Z0PP48/4+j1QHJFL3ssHIbJ4odPRS8PlHrFfw==",
+          "dev": true
+        },
+        "@typescript-eslint/typescript-estree": {
+          "version": "5.30.5",
+          "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.5.tgz",
+          "integrity": "sha512-qGTc7QZC801kbYjAr4AgdOfnokpwStqyhSbiQvqGBLixniAKyH+ib2qXIVo4P9NgGzwyfD9I0nlJN7D91E1VpQ==",
+          "dev": true,
+          "requires": {
+            "@typescript-eslint/types": "5.30.5",
+            "@typescript-eslint/visitor-keys": "5.30.5",
+            "debug": "^4.3.4",
+            "globby": "^11.1.0",
+            "is-glob": "^4.0.3",
+            "semver": "^7.3.7",
+            "tsutils": "^3.21.0"
+          }
+        },
+        "@typescript-eslint/visitor-keys": {
+          "version": "5.30.5",
+          "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.5.tgz",
+          "integrity": "sha512-D+xtGo9HUMELzWIUqcQc0p2PO4NyvTrgIOK/VnSH083+8sq0tiLozNRKuLarwHYGRuA6TVBQSuuLwJUDWd3aaA==",
+          "dev": true,
+          "requires": {
+            "@typescript-eslint/types": "5.30.5",
+            "eslint-visitor-keys": "^3.3.0"
+          }
+        },
+        "eslint-visitor-keys": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
+          "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
+          "dev": true
+        }
       }
     },
     "@typescript-eslint/scope-manager": {
@@ -13337,9 +13469,9 @@
       }
     },
     "debug": {
-      "version": "4.3.3",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
-      "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
       "dev": true,
       "requires": {
         "ms": "2.1.2"
@@ -16744,9 +16876,9 @@
       }
     },
     "minimist": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
       "dev": true
     },
     "minimist-options": {
@@ -17674,9 +17806,9 @@
       }
     },
     "semver": {
-      "version": "7.3.5",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+      "version": "7.3.7",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
       "requires": {
         "lru-cache": "^6.0.0"
       }
@@ -18634,9 +18766,9 @@
       }
     },
     "vscode-languageserver-textdocument": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.3.tgz",
-      "integrity": "sha512-ynEGytvgTb6HVSUwPJIAZgiHQmPCx8bZ8w5um5Lz+q5DjP0Zj8wTFhQpyg8xaMvefDytw2+HH5yzqS+FhsR28A=="
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.5.tgz",
+      "integrity": "sha512-1ah7zyQjKBudnMiHbZmxz5bYNM9KKZYz+5VQLj+yr8l+9w3g+WAhCkUkWbhMEdC5u0ub4Ndiye/fDyS8ghIKQg=="
     },
     "vscode-languageserver-types": {
       "version": "3.16.0",
diff --git a/package.json b/package.json
index fc795c8..af12da5 100644
--- a/package.json
+++ b/package.json
@@ -197,7 +197,7 @@
     "vscode-languageclient": "^7.0.0",
     "vscode-languageserver": "^7.0.0",
     "vscode-languageserver-protocol": "^3.16.0",
-    "vscode-languageserver-textdocument": "^1.0.3",
+    "vscode-languageserver-textdocument": "^1.0.5",
     "vscode-languageserver-types": "^3.16.0",
     "vscode-uri": "^3.0.2",
     "winston": "^3.3.3",
@@ -213,7 +213,7 @@
     "@types/semver": "^7.3.9",
     "@types/vscode": "1.56.0",
     "@typescript-eslint/eslint-plugin": "^5.5.0",
-    "@typescript-eslint/parser": "^5.5.0",
+    "@typescript-eslint/parser": "^5.30.5",
     "@typescript/lib-dom": "npm:@types/web@^0.0.47",
     "@vscode/test-electron": "^1.6.2",
     "cspell": "^5.13.1",
diff --git a/src/utils/stylelint/formatting-options-to-rules.ts b/src/utils/stylelint/formatting-options-to-rules.ts
index a302a57..ccb26a0 100644
--- a/src/utils/stylelint/formatting-options-to-rules.ts
+++ b/src/utils/stylelint/formatting-options-to-rules.ts
@@ -2,8 +2,8 @@ import type LSP from 'vscode-languageserver-protocol';
 
 export type FormattingRules = {
 	indentation: [number | string];
-	'no-missing-end-of-source-newline'?: boolean;
-	'no-eol-whitespace'?: boolean;
+	'no-missing-end-of-source-newline'?: true | null;
+	'no-eol-whitespace'?: true | null;
 };
 
 /**
@@ -25,11 +25,11 @@ export function formattingOptionsToRules({
 	};
 
 	if (insertFinalNewline !== undefined) {
-		rules['no-missing-end-of-source-newline'] = insertFinalNewline;
+		rules['no-missing-end-of-source-newline'] = insertFinalNewline || null;
 	}
 
 	if (trimTrailingWhitespace !== undefined) {
-		rules['no-eol-whitespace'] = trimTrailingWhitespace;
+		rules['no-eol-whitespace'] = trimTrailingWhitespace || null;
 	}
 
 	return rules;


Test patch:
diff --git a/src/utils/stylelint/__tests__/formatting-options-to-rules.ts b/src/utils/stylelint/__tests__/formatting-options-to-rules.ts
index 8d8f501..fe092c8 100644
--- a/src/utils/stylelint/__tests__/formatting-options-to-rules.ts
+++ b/src/utils/stylelint/__tests__/formatting-options-to-rules.ts
@@ -21,7 +21,7 @@ describe('formattingOptionsToRules', () => {
 			formattingOptionsToRules({ insertSpaces: true, tabSize: 2, insertFinalNewline: false }),
 		).toStrictEqual({
 			indentation: [2],
-			'no-missing-end-of-source-newline': false,
+			'no-missing-end-of-source-newline': null,
 		});
 	});
 
@@ -36,7 +36,7 @@ describe('formattingOptionsToRules', () => {
 			formattingOptionsToRules({ insertSpaces: true, tabSize: 2, trimTrailingWhitespace: false }),
 		).toStrictEqual({
 			indentation: [2],
-			'no-eol-whitespace': false,
+			'no-eol-whitespace': null,
 		});
 	});