Repository: ota-meshi/eslint-plugin-astro
Pull request #234 (2023-07-29 01:51:39)

Add `astro/no-deprecated-getentrybyslug` rule
In the latest Astro, the function `getEntryBySlug` has been [deprecated](https://docs.astro.build/en/reference/api-reference/#getentrybyslug). However, I noticed that there wasn't any rule regarding this function, so I added one.

I ran `npm run new` to add a new rule, followed by `npm run update`. Apologies if I've misunderstood or misfollowed any procedure!

changeset-bot[bot]: ###  ⚠️  No Changeset found

Latest commit: f442b11e9b39499825db01484604fb500b712c52

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a changeset.**

<details><summary>This PR includes no changesets</summary>

  When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

[Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/morinokami/eslint-plugin-astro/new/no-deprecated-getentrybyslug?filename=.changeset/heavy-carpets-move.md&value=---%0A%22eslint-plugin-astro%22%3A%20patch%0A---%0A%0AAdd%20%60astro%2Fno-deprecated-getentrybyslug%60%20rule%0A)



Patch:
diff --git a/.changeset/heavy-carpets-move.md b/.changeset/heavy-carpets-move.md
new file mode 100644
index 0000000..41ceded
--- /dev/null
+++ b/.changeset/heavy-carpets-move.md
@@ -0,0 +1,5 @@
+---
+"eslint-plugin-astro": minor
+---
+
+feat: add `astro/no-deprecated-getentrybyslug` rule
diff --git a/README.md b/README.md
index 873103b..057c9db 100644
--- a/README.md
+++ b/README.md
@@ -250,6 +250,7 @@ These rules relate to possible syntax or logic errors in Astro component code:
 | [astro/no-deprecated-astro-canonicalurl](https://ota-meshi.github.io/eslint-plugin-astro/rules/no-deprecated-astro-canonicalurl/) | disallow using deprecated `Astro.canonicalURL` | :star: |
 | [astro/no-deprecated-astro-fetchcontent](https://ota-meshi.github.io/eslint-plugin-astro/rules/no-deprecated-astro-fetchcontent/) | disallow using deprecated `Astro.fetchContent()` | :star::wrench: |
 | [astro/no-deprecated-astro-resolve](https://ota-meshi.github.io/eslint-plugin-astro/rules/no-deprecated-astro-resolve/) | disallow using deprecated `Astro.resolve()` | :star: |
+| [astro/no-deprecated-getentrybyslug](https://ota-meshi.github.io/eslint-plugin-astro/rules/no-deprecated-getentrybyslug/) | disallow using deprecated `getEntryBySlug()` | :star: |
 | [astro/no-unused-define-vars-in-style](https://ota-meshi.github.io/eslint-plugin-astro/rules/no-unused-define-vars-in-style/) | disallow unused `define:vars={...}` in `style` tag | :star: |
 | [astro/valid-compile](https://ota-meshi.github.io/eslint-plugin-astro/rules/valid-compile/) | disallow warnings when compiling. | :star: |
 
diff --git a/docs/rules.md b/docs/rules.md
index d5bfabe..006c628 100644
--- a/docs/rules.md
+++ b/docs/rules.md
@@ -17,6 +17,7 @@ These rules relate to possible syntax or logic errors in Astro component code:
 | [astro/no-deprecated-astro-canonicalurl](./rules/no-deprecated-astro-canonicalurl.md) | disallow using deprecated `Astro.canonicalURL` | :star: |
 | [astro/no-deprecated-astro-fetchcontent](./rules/no-deprecated-astro-fetchcontent.md) | disallow using deprecated `Astro.fetchContent()` | :star::wrench: |
 | [astro/no-deprecated-astro-resolve](./rules/no-deprecated-astro-resolve.md) | disallow using deprecated `Astro.resolve()` | :star: |
+| [astro/no-deprecated-getentrybyslug](./rules/no-deprecated-getentrybyslug.md) | disallow using deprecated `getEntryBySlug()` | :star: |
 | [astro/no-unused-define-vars-in-style](./rules/no-unused-define-vars-in-style.md) | disallow unused `define:vars={...}` in `style` tag | :star: |
 | [astro/valid-compile](./rules/valid-compile.md) | disallow warnings when compiling. | :star: |
 
diff --git a/docs/rules/no-deprecated-getentrybyslug.md b/docs/rules/no-deprecated-getentrybyslug.md
new file mode 100644
index 0000000..8779a12
--- /dev/null
+++ b/docs/rules/no-deprecated-getentrybyslug.md
@@ -0,0 +1,47 @@
+---
+title: "astro/no-deprecated-getentrybyslug"
+description: "disallow using deprecated `getEntryBySlug()`"
+---
+
+# astro/no-deprecated-getentrybyslug
+
+> disallow using deprecated `getEntryBySlug()`
+
+- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> **_This rule has not been released yet._** </badge>
+- :gear: This rule is included in `"plugin:astro/recommended"`.
+
+## :book: Rule Details
+
+This rule reports use of deprecated `getEntryBySlug()`.
+
+<ESLintCodeBlock>
+
+<!--eslint-skip-->
+
+```astro
+---
+/* eslint astro/no-deprecated-getentrybyslug: "error" */
+
+/* ✓ GOOD */
+import { getEntry } from "astro:content";
+
+/* ✗ BAD */
+import { getEntryBySlug } from "astro:content";
+---
+```
+
+</ESLintCodeBlock>
+
+## :wrench: Options
+
+Nothing.
+
+## :books: Further Reading
+
+- [Astro Documentation | API Reference - getEntryBySlug()](https://docs.astro.build/en/reference/api-reference/#getentrybyslug)
+
+## :mag: Implementation
+
+- [Rule source](https://github.com/ota-meshi/eslint-plugin-astro/blob/main/src/rules/no-deprecated-getentrybyslug.ts)
+- [Test source](https://github.com/ota-meshi/eslint-plugin-astro/blob/main/tests/src/rules/no-deprecated-getentrybyslug.ts)
+- [Test fixture sources](https://github.com/ota-meshi/eslint-plugin-astro/tree/main/tests/fixtures/rules/no-deprecated-getentrybyslug)
diff --git a/src/configs/recommended.ts b/src/configs/recommended.ts
index 250a60b..87b267f 100644
--- a/src/configs/recommended.ts
+++ b/src/configs/recommended.ts
@@ -13,6 +13,7 @@ export = {
     "astro/no-deprecated-astro-canonicalurl": "error",
     "astro/no-deprecated-astro-fetchcontent": "error",
     "astro/no-deprecated-astro-resolve": "error",
+    "astro/no-deprecated-getentrybyslug": "error",
     "astro/no-unused-define-vars-in-style": "error",
     "astro/valid-compile": "error",
   },
diff --git a/src/rules/no-deprecated-getentrybyslug.ts b/src/rules/no-deprecated-getentrybyslug.ts
new file mode 100644
index 0000000..868cf4e
--- /dev/null
+++ b/src/rules/no-deprecated-getentrybyslug.ts
@@ -0,0 +1,37 @@
+import { createRule } from "../utils"
+import type { TSESTree } from "@typescript-eslint/types"
+
+export default createRule("no-deprecated-getentrybyslug", {
+  meta: {
+    docs: {
+      description: "disallow using deprecated `getEntryBySlug()`",
+      category: "Possible Errors",
+      recommended: true,
+    },
+    schema: [],
+    messages: {
+      deprecated: "'getEntryBySlug()' is deprecated. Use 'getEntry()' instead.",
+    },
+    type: "problem",
+  },
+  create(context) {
+    if (!context.parserServices.isAstro) {
+      return {}
+    }
+
+    return {
+      ImportSpecifier(node: TSESTree.ImportSpecifier) {
+        if (
+          node.imported.name === "getEntryBySlug" &&
+          node.parent?.type === "ImportDeclaration" &&
+          node.parent.source.value === "astro:content"
+        ) {
+          context.report({
+            node,
+            messageId: "deprecated",
+          })
+        }
+      },
+    }
+  },
+})
diff --git a/src/utils/rules.ts b/src/utils/rules.ts
index ac1fb75..76b2bb5 100644
--- a/src/utils/rules.ts
+++ b/src/utils/rules.ts
@@ -6,6 +6,7 @@ import noConflictSetDirectives from "../rules/no-conflict-set-directives"
 import noDeprecatedAstroCanonicalurl from "../rules/no-deprecated-astro-canonicalurl"
 import noDeprecatedAstroFetchcontent from "../rules/no-deprecated-astro-fetchcontent"
 import noDeprecatedAstroResolve from "../rules/no-deprecated-astro-resolve"
+import noDeprecatedGetentrybyslug from "../rules/no-deprecated-getentrybyslug"
 import noSetHtmlDirective from "../rules/no-set-html-directive"
 import noSetTextDirective from "../rules/no-set-text-directive"
 import noUnusedCssSelector from "../rules/no-unused-css-selector"
@@ -22,6 +23,7 @@ export const rules = [
   noDeprecatedAstroCanonicalurl,
   noDeprecatedAstroFetchcontent,
   noDeprecatedAstroResolve,
+  noDeprecatedGetentrybyslug,
   noSetHtmlDirective,
   noSetTextDirective,
   noUnusedCssSelector,


Test patch:
diff --git a/tests/fixtures/rules/no-deprecated-getentrybyslug/invalid/test01-errors.json b/tests/fixtures/rules/no-deprecated-getentrybyslug/invalid/test01-errors.json
new file mode 100644
index 0000000..5f607ee
--- /dev/null
+++ b/tests/fixtures/rules/no-deprecated-getentrybyslug/invalid/test01-errors.json
@@ -0,0 +1,7 @@
+[
+  {
+    "message": "'getEntryBySlug()' is deprecated. Use 'getEntry()' instead.",
+    "line": 3,
+    "column": 10
+  }
+]
diff --git a/tests/fixtures/rules/no-deprecated-getentrybyslug/invalid/test01-input.astro b/tests/fixtures/rules/no-deprecated-getentrybyslug/invalid/test01-input.astro
new file mode 100644
index 0000000..5f7fab0
--- /dev/null
+++ b/tests/fixtures/rules/no-deprecated-getentrybyslug/invalid/test01-input.astro
@@ -0,0 +1,4 @@
+---
+/* ✗ BAD */
+import { getEntryBySlug } from "astro:content"
+---
diff --git a/tests/fixtures/rules/no-deprecated-getentrybyslug/valid/test01-input.astro b/tests/fixtures/rules/no-deprecated-getentrybyslug/valid/test01-input.astro
new file mode 100644
index 0000000..84f6334
--- /dev/null
+++ b/tests/fixtures/rules/no-deprecated-getentrybyslug/valid/test01-input.astro
@@ -0,0 +1,4 @@
+---
+/* ✓ GOOD */
+import { getEntry } from "astro:content"
+---
diff --git a/tests/src/rules/no-deprecated-getentrybyslug.ts b/tests/src/rules/no-deprecated-getentrybyslug.ts
new file mode 100644
index 0000000..32a7035
--- /dev/null
+++ b/tests/src/rules/no-deprecated-getentrybyslug.ts
@@ -0,0 +1,16 @@
+import { RuleTester } from "eslint"
+import rule from "../../../src/rules/no-deprecated-getentrybyslug"
+import { loadTestCases } from "../../utils/utils"
+
+const tester = new RuleTester({
+  parserOptions: {
+    ecmaVersion: 2020,
+    sourceType: "module",
+  },
+})
+
+tester.run(
+  "no-deprecated-getentrybyslug",
+  rule as any,
+  loadTestCases("no-deprecated-getentrybyslug"),
+)