Repository: HiDeoo/starlight-links-validator
Pull request #38 (2024-04-16 10:57:12)

Add a new option to `exclude` a list of links from validation


Patch:
diff --git a/docs/src/content/docs/configuration.md b/docs/src/content/docs/configuration.md
index d0d7ffc..1e41f2b 100644
--- a/docs/src/content/docs/configuration.md
+++ b/docs/src/content/docs/configuration.md
@@ -100,3 +100,28 @@ export default defineConfig({
   ],
 })
 ```
+
+### `exclude`
+
+**Type:** `string[]`  
+**Default:** `[]`
+
+A list of links that should be excluded from validation.
+
+The links in this list will be ignored by the plugin and will not be validated.
+As this option can lead to broken links in your documentation or a downgraded user/author experience, it should be used with caution.
+The list must exactly match links as they appear in Markdown.
+
+```js {6}
+export default defineConfig({
+  integrations: [
+    starlight({
+      plugins: [
+        starlightLinksValidator({
+          exclude: ['/social/discord', '/social/twitter'],
+        }),
+      ],
+    }),
+  ],
+})
+```
diff --git a/packages/starlight-links-validator/index.ts b/packages/starlight-links-validator/index.ts
index 53e5bab..2c9ee45 100644
--- a/packages/starlight-links-validator/index.ts
+++ b/packages/starlight-links-validator/index.ts
@@ -33,6 +33,15 @@ const starlightLinksValidatorOptionsSchema = z
      * @default true
      */
     errorOnRelativeLinks: z.boolean().default(true),
+    /**
+     * Defines a list of links that should be excluded from validation.
+     *
+     * The links in this list will be ignored by the plugin and will not be validated.
+     * The list must exactly match links as they appear in Markdown.
+     *
+     * @default []
+     */
+    exclude: z.array(z.string()).default([]),
   })
   .default({})
 
diff --git a/packages/starlight-links-validator/libs/validation.ts b/packages/starlight-links-validator/libs/validation.ts
index 97e6ec8..94fd81b 100644
--- a/packages/starlight-links-validator/libs/validation.ts
+++ b/packages/starlight-links-validator/libs/validation.ts
@@ -108,6 +108,10 @@ export function logErrors(pluginLogger: AstroIntegrationLogger, errors: Validati
 function validateLink(context: ValidationContext) {
   const { astroConfig, errors, filePath, link, localeConfig, options, pages } = context
 
+  if (isExcludedLink(link, context)) {
+    return
+  }
+
   const sanitizedLink = link.replace(/^\//, '')
   const segments = sanitizedLink.split('#')
 
@@ -211,6 +215,13 @@ function isValidAsset(path: string, context: ValidationContext) {
   }
 }
 
+/**
+ * Check if a link is explicitly excluded from validation by the user.
+ */
+function isExcludedLink(link: string, context: ValidationContext) {
+  return context.options.exclude.includes(link)
+}
+
 function addError(errors: ValidationErrors, filePath: string, link: string, type: ValidationErrorType) {
   const fileErrors = errors.get(filePath) ?? []
   fileErrors.push({ link, type })


Test patch:
diff --git a/packages/starlight-links-validator/tests/exclude.test.ts b/packages/starlight-links-validator/tests/exclude.test.ts
new file mode 100644
index 0000000..5ed065b
--- /dev/null
+++ b/packages/starlight-links-validator/tests/exclude.test.ts
@@ -0,0 +1,22 @@
+import { expect, test } from 'vitest'
+
+import { ValidationErrorType } from '../libs/validation'
+
+import { expectValidationErrorCount, expectValidationErrors, loadFixture } from './utils'
+
+test('should ignore links that are explicitly excluded from validation', async () => {
+  expect.assertions(2)
+
+  try {
+    await loadFixture('exclude')
+  } catch (error) {
+    expectValidationErrorCount(error, 4, 1)
+
+    expectValidationErrors(error, '/', [
+      ['/excluded/', ValidationErrorType.InvalidLink],
+      ['/excluded#test', ValidationErrorType.InvalidLink],
+      ['/test/excluded', ValidationErrorType.InvalidLink],
+      ['/test/excluded/test', ValidationErrorType.InvalidLink],
+    ])
+  }
+})
diff --git a/packages/starlight-links-validator/tests/fixtures/exclude/astro.config.ts b/packages/starlight-links-validator/tests/fixtures/exclude/astro.config.ts
new file mode 100644
index 0000000..97d7c02
--- /dev/null
+++ b/packages/starlight-links-validator/tests/fixtures/exclude/astro.config.ts
@@ -0,0 +1,13 @@
+import starlight from '@astrojs/starlight'
+import { defineConfig } from 'astro/config'
+
+import starlightLinksValidator from '../..'
+
+export default defineConfig({
+  integrations: [
+    starlight({
+      plugins: [starlightLinksValidator({ exclude: ['/excluded'] })],
+      title: 'Starlight Links Validator Tests - exclude',
+    }),
+  ],
+})
diff --git a/packages/starlight-links-validator/tests/fixtures/exclude/src/content/docs/index.md b/packages/starlight-links-validator/tests/fixtures/exclude/src/content/docs/index.md
new file mode 100644
index 0000000..753609c
--- /dev/null
+++ b/packages/starlight-links-validator/tests/fixtures/exclude/src/content/docs/index.md
@@ -0,0 +1,20 @@
+---
+title: Index
+---
+
+# Some links
+
+- [External link](https://starlight.astro.build/)
+
+- [Home page](/)
+
+- [Test page](/test)
+
+# Exclude
+
+- [Excluded link](/excluded)
+
+- [Non-excluded link](/excluded/)
+- [More non-excluded link](/excluded#test)
+- [Another non-excluded link](/test/excluded)
+- [And another non-excluded link](/test/excluded/test)
diff --git a/packages/starlight-links-validator/tests/fixtures/exclude/src/content/docs/test.md b/packages/starlight-links-validator/tests/fixtures/exclude/src/content/docs/test.md
new file mode 100644
index 0000000..2e4a900
--- /dev/null
+++ b/packages/starlight-links-validator/tests/fixtures/exclude/src/content/docs/test.md
@@ -0,0 +1,7 @@
+---
+title: Test
+---
+
+## Title
+
+Some content.