From 9a6df918a865c2f024a890836987c4324f33ef4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20D=C4=9Bdi=C4=8D?= Date: Wed, 8 Feb 2023 10:43:11 +0100 Subject: [PATCH 01/12] test(experimental-require-slot-types): Added rule tests --- .../invalid/no-slot-types01-input.svelte | 4 ++++ .../valid/has-slot-types01-input.svelte | 7 +++++++ .../valid/named-slot01-input.svelte | 7 +++++++ .../valid/no-slots01-input.svelte | 4 ++++ .../valid/no-typescript01-input.svelte | 4 ++++ .../src/rules/experimental-require-slot-types.ts | 16 ++++++++++++++++ 6 files changed, 42 insertions(+) create mode 100644 tests/fixtures/rules/experimental-require-slot-types/invalid/no-slot-types01-input.svelte create mode 100644 tests/fixtures/rules/experimental-require-slot-types/valid/has-slot-types01-input.svelte create mode 100644 tests/fixtures/rules/experimental-require-slot-types/valid/named-slot01-input.svelte create mode 100644 tests/fixtures/rules/experimental-require-slot-types/valid/no-slots01-input.svelte create mode 100644 tests/fixtures/rules/experimental-require-slot-types/valid/no-typescript01-input.svelte create mode 100644 tests/src/rules/experimental-require-slot-types.ts diff --git a/tests/fixtures/rules/experimental-require-slot-types/invalid/no-slot-types01-input.svelte b/tests/fixtures/rules/experimental-require-slot-types/invalid/no-slot-types01-input.svelte new file mode 100644 index 000000000..2c02c7ef5 --- /dev/null +++ b/tests/fixtures/rules/experimental-require-slot-types/invalid/no-slot-types01-input.svelte @@ -0,0 +1,4 @@ + + + diff --git a/tests/fixtures/rules/experimental-require-slot-types/valid/has-slot-types01-input.svelte b/tests/fixtures/rules/experimental-require-slot-types/valid/has-slot-types01-input.svelte new file mode 100644 index 000000000..c902e4a06 --- /dev/null +++ b/tests/fixtures/rules/experimental-require-slot-types/valid/has-slot-types01-input.svelte @@ -0,0 +1,7 @@ + + + diff --git a/tests/fixtures/rules/experimental-require-slot-types/valid/named-slot01-input.svelte b/tests/fixtures/rules/experimental-require-slot-types/valid/named-slot01-input.svelte new file mode 100644 index 000000000..ac2713e44 --- /dev/null +++ b/tests/fixtures/rules/experimental-require-slot-types/valid/named-slot01-input.svelte @@ -0,0 +1,7 @@ + + + diff --git a/tests/fixtures/rules/experimental-require-slot-types/valid/no-slots01-input.svelte b/tests/fixtures/rules/experimental-require-slot-types/valid/no-slots01-input.svelte new file mode 100644 index 000000000..d0857d009 --- /dev/null +++ b/tests/fixtures/rules/experimental-require-slot-types/valid/no-slots01-input.svelte @@ -0,0 +1,4 @@ + + +content diff --git a/tests/fixtures/rules/experimental-require-slot-types/valid/no-typescript01-input.svelte b/tests/fixtures/rules/experimental-require-slot-types/valid/no-typescript01-input.svelte new file mode 100644 index 000000000..9cc1fe581 --- /dev/null +++ b/tests/fixtures/rules/experimental-require-slot-types/valid/no-typescript01-input.svelte @@ -0,0 +1,4 @@ + + + diff --git a/tests/src/rules/experimental-require-slot-types.ts b/tests/src/rules/experimental-require-slot-types.ts new file mode 100644 index 000000000..af9978d93 --- /dev/null +++ b/tests/src/rules/experimental-require-slot-types.ts @@ -0,0 +1,16 @@ +import { RuleTester } from "eslint" +import rule from "../../../src/rules/experimental-require-slot-types" +import { loadTestCases } from "../../utils/utils" + +const tester = new RuleTester({ + parserOptions: { + ecmaVersion: 2020, + sourceType: "module", + }, +}) + +tester.run( + "experimental-require-slot-types", + rule as any, + loadTestCases("experimental-require-slot-types"), +) From 0381de6f1ee8d407a901f40b546d552259b852c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20D=C4=9Bdi=C4=8D?= Date: Wed, 8 Feb 2023 11:10:57 +0100 Subject: [PATCH 02/12] feat(experimental-require-slot-types): Added rule implementation --- src/rules/experimental-require-slot-types.ts | 49 +++++++++++++++++++ src/utils/rules.ts | 2 + .../invalid/no-slot-types01-errors.yaml | 4 ++ 3 files changed, 55 insertions(+) create mode 100644 src/rules/experimental-require-slot-types.ts create mode 100644 tests/fixtures/rules/experimental-require-slot-types/invalid/no-slot-types01-errors.yaml diff --git a/src/rules/experimental-require-slot-types.ts b/src/rules/experimental-require-slot-types.ts new file mode 100644 index 000000000..eb706f830 --- /dev/null +++ b/src/rules/experimental-require-slot-types.ts @@ -0,0 +1,49 @@ +import { createRule } from "../utils" +import { getLangValue } from "../utils/ast-utils" + +export default createRule("experimental-require-slot-types", { + meta: { + docs: { + description: "require slot type declaration using the $$Slots interface", + category: "Experimental", + recommended: false, + }, + schema: [], + messages: { + missingSlotsInterface: `The component must define the $$Slots interface.`, + }, + type: "suggestion", + }, + create(context) { + let isTs = false + let hasSlot = false + let hasInterface = false + return { + SvelteScriptElement(node) { + const lang = getLangValue(node)?.toLowerCase() + isTs = lang === "ts" || lang === "typescript" + }, + SvelteElement(node) { + if (node.name.type === "SvelteName" && node.name.name === "slot") { + hasSlot = true + } + }, + TSInterfaceDeclaration(node) { + if (node.id.name === "$$Slots") { + hasInterface = true + } + }, + "Program:exit"() { + if (isTs && hasSlot && !hasInterface) { + context.report({ + loc: { + line: 1, + column: 1, + }, + messageId: "missingSlotsInterface", + }) + } + }, + } + }, +}) diff --git a/src/utils/rules.ts b/src/utils/rules.ts index e9d10b55d..26448124c 100644 --- a/src/utils/rules.ts +++ b/src/utils/rules.ts @@ -3,6 +3,7 @@ import typescriptEslintNoUnnecessaryCondition from "../rules/@typescript-eslint/ import buttonHasType from "../rules/button-has-type" import commentDirective from "../rules/comment-directive" import derivedHasSameInputsOutputs from "../rules/derived-has-same-inputs-outputs" +import experimentalRequireSlotTypes from "../rules/experimental-require-slot-types" import firstAttributeLinebreak from "../rules/first-attribute-linebreak" import htmlClosingBracketSpacing from "../rules/html-closing-bracket-spacing" import htmlQuotes from "../rules/html-quotes" @@ -55,6 +56,7 @@ export const rules = [ buttonHasType, commentDirective, derivedHasSameInputsOutputs, + experimentalRequireSlotTypes, firstAttributeLinebreak, htmlClosingBracketSpacing, htmlQuotes, diff --git a/tests/fixtures/rules/experimental-require-slot-types/invalid/no-slot-types01-errors.yaml b/tests/fixtures/rules/experimental-require-slot-types/invalid/no-slot-types01-errors.yaml new file mode 100644 index 000000000..628f8ecb1 --- /dev/null +++ b/tests/fixtures/rules/experimental-require-slot-types/invalid/no-slot-types01-errors.yaml @@ -0,0 +1,4 @@ +- message: The component must define the $$Slots interface. + line: 1 + column: 2 + suggestions: null From 78436bbfb0e8fb8783b72d22bce5bfced55e33ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20D=C4=9Bdi=C4=8D?= Date: Wed, 8 Feb 2023 11:18:06 +0100 Subject: [PATCH 03/12] docs(experimental-require-slot-types): Added rule docs --- docs/rules/experimental-require-slot-types.md | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 docs/rules/experimental-require-slot-types.md diff --git a/docs/rules/experimental-require-slot-types.md b/docs/rules/experimental-require-slot-types.md new file mode 100644 index 000000000..6e17e19c7 --- /dev/null +++ b/docs/rules/experimental-require-slot-types.md @@ -0,0 +1,78 @@ +--- +pageClass: "rule-details" +sidebarDepth: 0 +title: "svelte/experimental-require-slot-types" +description: "require slot type declaration using the $$Slots interface" +--- + +# svelte/experimental-require-slot-types + +> require slot type declaration using the $$Slots interface + +- :exclamation: **_This rule has not been released yet._** + +## :book: Rule Details + +This rule enforces the presence of the `$$Slots` interface if any slots are present in the component. This interface declares all of the used slots and their props and enables typechecking both in the component itself as well as all components that include it. +The `$$Slots` interface is experimental and is documented in [svelte RFC #38](https://github.com/dummdidumm/rfcs/blob/ts-typedefs-within-svelte-components/text/ts-typing-props-slots-events.md#typing-slots). + + + + + +```svelte + + + + + +No slots here! + + + + + + + + + + + + + + + + + + + + + + + +``` + + + +## :wrench: Options + +Nothing. + +## :mag: Implementation + +- [Rule source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/src/rules/experimental-require-slot-types.ts) +- [Test source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/tests/src/rules/experimental-require-slot-types.ts) From 19299b54c44d371de6400becb253928b4b9a976c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20D=C4=9Bdi=C4=8D?= Date: Wed, 8 Feb 2023 11:19:13 +0100 Subject: [PATCH 04/12] chore(experimental-require-slot-types): added a changeset --- .changeset/strong-wombats-worry.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/strong-wombats-worry.md diff --git a/.changeset/strong-wombats-worry.md b/.changeset/strong-wombats-worry.md new file mode 100644 index 000000000..b4fdd317c --- /dev/null +++ b/.changeset/strong-wombats-worry.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-svelte": minor +--- + +Added the experimental-require-slot-types rule From bbdf0bb9dd7fb431a1f54d6874271a202340e770 Mon Sep 17 00:00:00 2001 From: ota-meshi Date: Thu, 9 Feb 2023 19:18:41 +0900 Subject: [PATCH 05/12] chore: minor refactor --- .changeset/tasty-houses-behave.md | 2 +- README.md | 2 +- docs-svelte-kit/src/lib/eslint/scripts/linter.js | 5 +++++ docs-svelte-kit/src/lib/utils.js | 1 + docs/rules.md | 2 +- docs/rules/experimental-require-strict-events.md | 4 ++-- src/rules/experimental-require-strict-events.ts | 2 +- 7 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.changeset/tasty-houses-behave.md b/.changeset/tasty-houses-behave.md index e3a2d861f..1e8c9d32a 100644 --- a/.changeset/tasty-houses-behave.md +++ b/.changeset/tasty-houses-behave.md @@ -2,4 +2,4 @@ "eslint-plugin-svelte": minor --- -Added the experimental-require-strict-events rule +feat: added the `svelte/experimental-require-strict-events` rule diff --git a/README.md b/README.md index fa50c9e85..1919fcf15 100644 --- a/README.md +++ b/README.md @@ -379,7 +379,7 @@ These rules extend the rules provided by ESLint itself, or other plugins to work | Rule ID | Description | | |:--------|:------------|:---| -| [svelte/experimental-require-strict-events](https://ota-meshi.github.io/eslint-plugin-svelte/rules/experimental-require-strict-events/) | require the strictEvents attribute on No slots here! +``` + + + + + +```svelte + + +``` + + + +```svelte + + + +``` + + + + + +```svelte + + + +``` + + + + + + + +```svelte + No slots here! @@ -37,10 +36,10 @@ The `$$Slots` interface is experimental and is documented in [svelte RFC #38](h ```svelte - - @@ -75,13 +74,13 @@ The `$$Slots` interface is experimental and is documented in [svelte RFC #38](h ```svelte - - @@ -94,10 +93,9 @@ The `$$Slots` interface is experimental and is documented in [svelte RFC #38](h ```svelte - - From b3a38b215c3527f160a6ff2512cd9488c0c2a7b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20D=C4=9Bdi=C4=8D?= Date: Thu, 9 Feb 2023 12:05:27 +0100 Subject: [PATCH 11/12] Revert "fix: reverted spurious merge change" This reverts commit a5afef5af7b224af2ab900060c4fef090695e7c3. --- tools/render-rules.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/render-rules.ts b/tools/render-rules.ts index 096b2dd78..454c2406b 100644 --- a/tools/render-rules.ts +++ b/tools/render-rules.ts @@ -11,7 +11,7 @@ const categories = [ "System", ] as const -const descriptions: Record = { +const descriptions: Record<(typeof categories)[number], string> = { "Possible Errors": "These rules relate to possible syntax or logic errors in Svelte code:", "Security Vulnerability": From df62ef4e0146440eefe32c243bbce10dd59ede31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20D=C4=9Bdi=C4=8D?= Date: Fri, 10 Feb 2023 13:39:36 +0100 Subject: [PATCH 12/12] docs(experimental-require-slot-types): switched eslint comments to block comments --- docs/rules/experimental-require-slot-types.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/rules/experimental-require-slot-types.md b/docs/rules/experimental-require-slot-types.md index d20ab9b2b..5ab947701 100644 --- a/docs/rules/experimental-require-slot-types.md +++ b/docs/rules/experimental-require-slot-types.md @@ -23,7 +23,7 @@ The `$$Slots` interface is experimental and is documented in [svelte RFC #38](h ```svelte No slots here! @@ -38,7 +38,7 @@ The `$$Slots` interface is experimental and is documented in [svelte RFC #38](h ```svelte