starlight-links-validator 0.6.0 → 0.7.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
@@ -64,7 +64,7 @@ export default function starlightLinksValidatorPlugin(
64
64
  })
65
65
  },
66
66
  'astro:build:done': ({ dir, pages }) => {
67
- const errors = validateLinks(pages, dir, astroConfig.base, starlightConfig, options.data)
67
+ const errors = validateLinks(pages, dir, astroConfig, starlightConfig, options.data)
68
68
 
69
69
  logErrors(logger, errors)
70
70
 
@@ -3,7 +3,7 @@ import { posix } from 'node:path'
3
3
  import { fileURLToPath } from 'node:url'
4
4
 
5
5
  import type { StarlightPlugin } from '@astrojs/starlight/types'
6
- import type { AstroIntegrationLogger } from 'astro'
6
+ import type { AstroConfig, AstroIntegrationLogger } from 'astro'
7
7
  import { bgGreen, black, blue, dim, green, red } from 'kleur/colors'
8
8
 
9
9
  import type { StarlightLinksValidatorOptions } from '..'
@@ -17,12 +17,13 @@ export const ValidationErrorType = {
17
17
  InvalidAnchor: 'invalid anchor',
18
18
  InvalidLink: 'invalid link',
19
19
  RelativeLink: 'relative link',
20
+ TrailingSlash: 'trailing slash',
20
21
  } as const
21
22
 
22
23
  export function validateLinks(
23
24
  pages: PageData[],
24
25
  outputDir: URL,
25
- base: string,
26
+ astroConfig: AstroConfig,
26
27
  starlightConfig: StarlightUserConfig,
27
28
  options: StarlightLinksValidatorOptions,
28
29
  ): ValidationErrors {
@@ -33,7 +34,9 @@ export function validateLinks(
33
34
  const allPages: Pages = new Set(
34
35
  pages.map((page) =>
35
36
  ensureTrailingSlash(
36
- base === '/' ? stripLeadingSlash(page.pathname) : posix.join(stripLeadingSlash(base), page.pathname),
37
+ astroConfig.base === '/'
38
+ ? stripLeadingSlash(page.pathname)
39
+ : posix.join(stripLeadingSlash(astroConfig.base), page.pathname),
37
40
  ),
38
41
  ),
39
42
  )
@@ -43,7 +46,7 @@ export function validateLinks(
43
46
  for (const [filePath, fileLinks] of links) {
44
47
  for (const link of fileLinks) {
45
48
  const validationContext: ValidationContext = {
46
- base,
49
+ astroConfig,
47
50
  errors,
48
51
  filePath,
49
52
  headings,
@@ -103,12 +106,12 @@ export function logErrors(pluginLogger: AstroIntegrationLogger, errors: Validati
103
106
  * Validate a link to another internal page that may or may not have a hash.
104
107
  */
105
108
  function validateLink(context: ValidationContext) {
106
- const { errors, filePath, link, localeConfig, options, pages } = context
109
+ const { astroConfig, errors, filePath, link, localeConfig, options, pages } = context
107
110
 
108
111
  const sanitizedLink = link.replace(/^\//, '')
109
112
  const segments = sanitizedLink.split('#')
110
113
 
111
- let path = segments[0]
114
+ const path = segments[0]
112
115
  const hash = segments[1]
113
116
 
114
117
  if (path === undefined) {
@@ -127,10 +130,10 @@ function validateLink(context: ValidationContext) {
127
130
  return
128
131
  }
129
132
 
130
- path = ensureTrailingSlash(path)
133
+ const sanitizedPath = ensureTrailingSlash(path)
131
134
 
132
- const isValidPage = pages.has(path)
133
- const fileHeadings = getFileHeadings(path, context)
135
+ const isValidPage = pages.has(sanitizedPath)
136
+ const fileHeadings = getFileHeadings(sanitizedPath, context)
134
137
 
135
138
  if (!isValidPage || !fileHeadings) {
136
139
  addError(errors, filePath, link, ValidationErrorType.InvalidLink)
@@ -144,6 +147,15 @@ function validateLink(context: ValidationContext) {
144
147
 
145
148
  if (hash && !fileHeadings.includes(hash)) {
146
149
  addError(errors, filePath, link, ValidationErrorType.InvalidAnchor)
150
+ return
151
+ }
152
+
153
+ if (
154
+ (astroConfig.trailingSlash === 'always' && !path.endsWith('/')) ||
155
+ (astroConfig.trailingSlash === 'never' && path.endsWith('/'))
156
+ ) {
157
+ addError(errors, filePath, link, ValidationErrorType.TrailingSlash)
158
+ return
147
159
  }
148
160
  }
149
161
 
@@ -177,8 +189,8 @@ function validateSelfAnchor({ errors, link, filePath, headings }: ValidationCont
177
189
  * Check if a link is a valid asset in the build output directory.
178
190
  */
179
191
  function isValidAsset(path: string, context: ValidationContext) {
180
- if (context.base !== '/') {
181
- const base = stripLeadingSlash(context.base)
192
+ if (context.astroConfig.base !== '/') {
193
+ const base = stripLeadingSlash(context.astroConfig.base)
182
194
 
183
195
  if (path.startsWith(base)) {
184
196
  path = path.replace(new RegExp(`^${stripLeadingSlash(base)}/?`), '')
@@ -226,7 +238,7 @@ interface PageData {
226
238
  type Pages = Set<PageData['pathname']>
227
239
 
228
240
  interface ValidationContext {
229
- base: string
241
+ astroConfig: AstroConfig
230
242
  errors: ValidationErrors
231
243
  filePath: string
232
244
  headings: Headings
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starlight-links-validator",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "license": "MIT",
5
5
  "description": "Starlight plugin to validate internal links.",
6
6
  "author": "HiDeoo <github@hideoo.dev> (https://hideoo.dev)",