starlight-links-validator 0.12.4 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.ts CHANGED
@@ -41,6 +41,12 @@ const starlightLinksValidatorOptionsSchema = z
41
41
  * @default true
42
42
  */
43
43
  errorOnInvalidHashes: z.boolean().default(true),
44
+ /**
45
+ * Defines whether the plugin should error on local links, e.g. URLs with a hostname of `localhost` or `127.0.0.1`.
46
+ *
47
+ * @default true
48
+ */
49
+ errorOnLocalLinks: z.boolean().default(true),
44
50
  /**
45
51
  * Defines a list of links or glob patterns that should be excluded from validation.
46
52
  *
package/libs/remark.ts CHANGED
@@ -61,7 +61,7 @@ export const remarkStarlightLinksValidator: Plugin<[{ base: string; srcDir: URL
61
61
  break
62
62
  }
63
63
  case 'link': {
64
- if (isInternalLink(node.url)) {
64
+ if (shouldValidateLink(node.url)) {
65
65
  fileLinks.push(node.url)
66
66
  }
67
67
 
@@ -70,7 +70,7 @@ export const remarkStarlightLinksValidator: Plugin<[{ base: string; srcDir: URL
70
70
  case 'linkReference': {
71
71
  const definition = fileDefinitions.get(node.identifier)
72
72
 
73
- if (definition && isInternalLink(definition)) {
73
+ if (definition && shouldValidateLink(definition)) {
74
74
  fileLinks.push(definition)
75
75
  }
76
76
 
@@ -96,7 +96,7 @@ export const remarkStarlightLinksValidator: Plugin<[{ base: string; srcDir: URL
96
96
  continue
97
97
  }
98
98
 
99
- if (isInternalLink(attribute.value)) {
99
+ if (shouldValidateLink(attribute.value)) {
100
100
  fileLinks.push(attribute.value)
101
101
  }
102
102
  }
@@ -125,7 +125,7 @@ export const remarkStarlightLinksValidator: Plugin<[{ base: string; srcDir: URL
125
125
  htmlNode.tagName === 'a' &&
126
126
  hasProperty(htmlNode, 'href') &&
127
127
  typeof htmlNode.properties.href === 'string' &&
128
- isInternalLink(htmlNode.properties.href)
128
+ shouldValidateLink(htmlNode.properties.href)
129
129
  ) {
130
130
  fileLinks.push(htmlNode.properties.href)
131
131
  }
@@ -145,8 +145,18 @@ export function getValidationData() {
145
145
  return { headings, links }
146
146
  }
147
147
 
148
- function isInternalLink(link: string) {
149
- return !isAbsoluteUrl(link)
148
+ function shouldValidateLink(link: string) {
149
+ if (!isAbsoluteUrl(link)) {
150
+ return true
151
+ }
152
+
153
+ try {
154
+ const url = new URL(link)
155
+
156
+ return url.hostname === 'localhost' || url.hostname === '127.0.0.1'
157
+ } catch {
158
+ return false
159
+ }
150
160
  }
151
161
 
152
162
  function getFilePath(base: string, filePath: string, slug: string | undefined) {
@@ -17,6 +17,7 @@ export const ValidationErrorType = {
17
17
  InconsistentLocale: 'inconsistent locale',
18
18
  InvalidHash: 'invalid hash',
19
19
  InvalidLink: 'invalid link',
20
+ LocalLink: 'local link',
20
21
  RelativeLink: 'relative link',
21
22
  TrailingSlash: 'trailing slash',
22
23
  } as const
@@ -115,6 +116,14 @@ function validateLink(context: ValidationContext) {
115
116
  return
116
117
  }
117
118
 
119
+ if (/^https?:\/\//.test(link)) {
120
+ if (options.errorOnLocalLinks) {
121
+ addError(errors, filePath, link, ValidationErrorType.LocalLink)
122
+ }
123
+
124
+ return
125
+ }
126
+
118
127
  const sanitizedLink = link.replace(/^\//, '')
119
128
  const segments = sanitizedLink.split('#')
120
129
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starlight-links-validator",
3
- "version": "0.12.4",
3
+ "version": "0.13.0",
4
4
  "license": "MIT",
5
5
  "description": "Starlight plugin to validate internal links.",
6
6
  "author": "HiDeoo <github@hideoo.dev> (https://hideoo.dev)",