starlight-versions 0.10.1 → 0.10.2
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/.npmignore +5 -0
- package/CHANGELOG.md +14 -0
- package/libs/markdown.ts +93 -23
- package/libs/plugin.ts +2 -1
- package/libs/starlight.ts +12 -7
- package/libs/versions.ts +25 -22
- package/middleware.ts +7 -5
- package/package.json +4 -5
package/.npmignore
ADDED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# starlight-versions
|
|
2
2
|
|
|
3
|
+
## 0.10.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#86](https://github.com/HiDeoo/starlight-versions/pull/86) [`27959fb`](https://github.com/HiDeoo/starlight-versions/commit/27959fb72e19fbad44a79fe673a2246ab64ad05a) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Fixes versioning of public assets in media elements using both `src` and `srcset` attributes.
|
|
8
|
+
|
|
9
|
+
- [#84](https://github.com/HiDeoo/starlight-versions/pull/84) [`7cc6fdf`](https://github.com/HiDeoo/starlight-versions/commit/7cc6fdfe49f66df7a77b1f1b18891ebe50a37b1e) Thanks [@dgesteves](https://github.com/dgesteves)! - Fixes versioning of Markdown files using syntax that is not valid in MDX, like `<->` arrows.
|
|
10
|
+
|
|
11
|
+
- [#86](https://github.com/HiDeoo/starlight-versions/pull/86) [`27959fb`](https://github.com/HiDeoo/starlight-versions/commit/27959fb72e19fbad44a79fe673a2246ab64ad05a) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Fixes versioning of public assets in `srcset` attributes with multiple images or descriptors.
|
|
12
|
+
|
|
13
|
+
- [#86](https://github.com/HiDeoo/starlight-versions/pull/86) [`27959fb`](https://github.com/HiDeoo/starlight-versions/commit/27959fb72e19fbad44a79fe673a2246ab64ad05a) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Fixes versioning of images inside links.
|
|
14
|
+
|
|
15
|
+
- [#86](https://github.com/HiDeoo/starlight-versions/pull/86) [`27959fb`](https://github.com/HiDeoo/starlight-versions/commit/27959fb72e19fbad44a79fe673a2246ab64ad05a) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Fixes versioning of public assets in inline media elements in MDX files.
|
|
16
|
+
|
|
3
17
|
## 0.10.1
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/libs/markdown.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import assert from 'node:assert'
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { Element } from 'hast'
|
|
4
|
+
import { fromHtml } from 'hast-util-from-html'
|
|
5
|
+
import type { Html, Image, Link, Root } from 'mdast'
|
|
4
6
|
import type { MdxJsxFlowElement, MdxJsxTextElement } from 'mdast-util-mdx-jsx'
|
|
5
7
|
import type { MdxjsEsm } from 'mdast-util-mdxjs-esm'
|
|
6
8
|
import { remark } from 'remark'
|
|
@@ -12,6 +14,7 @@ import type { VFile } from 'vfile'
|
|
|
12
14
|
|
|
13
15
|
import {
|
|
14
16
|
ensureTrailingSlash,
|
|
17
|
+
getExtension,
|
|
15
18
|
isAbsoluteLink,
|
|
16
19
|
stripLeadingAndTrailingSlashes,
|
|
17
20
|
stripLeadingSlash,
|
|
@@ -22,12 +25,17 @@ import type { Version, VersionAsset } from './versions'
|
|
|
22
25
|
|
|
23
26
|
const importPathRegex = /(from ?["'])([^"']*)(["'];?\s?)$/gm
|
|
24
27
|
const astroAssetRegex = /\.(png|jpg|jpeg|tiff|webp|gif|svg|avif|.+\?raw)$/i
|
|
28
|
+
const htmlAttributeRegex = /^(?<prefix>[^=]+=\s*(?<quote>["']?))(?<value>.*)\k<quote>$/s
|
|
29
|
+
const srcsetUrlRegex = /(?<=(?:^|,)\s*)[^\s,]\S*?(?=,*(?:\s|$))/g
|
|
25
30
|
|
|
26
31
|
const mediaElements = new Set(['img', 'source', 'Image', 'audio', 'video'])
|
|
27
32
|
|
|
28
|
-
const
|
|
33
|
+
const markdownProcessor = remark().use(remarkDirective).use(remarkFrontmatter).use(remarkStarlightVersions)
|
|
34
|
+
const mdxProcessor = markdownProcessor().use(remarkMdx)
|
|
29
35
|
|
|
30
36
|
export async function transformMarkdown(markdown: string, context: TransformContext) {
|
|
37
|
+
const processor = getExtension(context.url.pathname) === '.mdx' ? mdxProcessor : markdownProcessor
|
|
38
|
+
|
|
31
39
|
const file = await processor.process({
|
|
32
40
|
data: { ...context },
|
|
33
41
|
value: markdown,
|
|
@@ -46,17 +54,11 @@ export function remarkStarlightVersions() {
|
|
|
46
54
|
case 'link': {
|
|
47
55
|
return handleLinks(node, file)
|
|
48
56
|
}
|
|
49
|
-
case 'mdxJsxTextElement': {
|
|
50
|
-
if (node.name === 'a') {
|
|
51
|
-
return handleLinkElements(node, file)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return CONTINUE
|
|
55
|
-
}
|
|
56
57
|
case 'mdxjsEsm': {
|
|
57
58
|
return handleImports(node, file)
|
|
58
59
|
}
|
|
59
|
-
case 'mdxJsxFlowElement':
|
|
60
|
+
case 'mdxJsxFlowElement':
|
|
61
|
+
case 'mdxJsxTextElement': {
|
|
60
62
|
if (node.name === 'a') {
|
|
61
63
|
return handleLinkElements(node, file)
|
|
62
64
|
}
|
|
@@ -70,6 +72,9 @@ export function remarkStarlightVersions() {
|
|
|
70
72
|
case 'image': {
|
|
71
73
|
return handleImages(node, file)
|
|
72
74
|
}
|
|
75
|
+
case 'html': {
|
|
76
|
+
return handleHtml(node, file)
|
|
77
|
+
}
|
|
73
78
|
default: {
|
|
74
79
|
return CONTINUE
|
|
75
80
|
}
|
|
@@ -102,7 +107,7 @@ function handleFrontmatter(tree: Root, file: VFile) {
|
|
|
102
107
|
if (file.data.locale && segments[0] === file.data.locale) {
|
|
103
108
|
segments.splice(1, 0, file.data.version.slug)
|
|
104
109
|
} else {
|
|
105
|
-
segments.
|
|
110
|
+
segments.unshift(file.data.version.slug)
|
|
106
111
|
}
|
|
107
112
|
|
|
108
113
|
frontmatter.slug = segments.join('/')
|
|
@@ -144,7 +149,7 @@ function handleFrontmatter(tree: Root, file: VFile) {
|
|
|
144
149
|
function handleLinks(node: Link, file: VFile) {
|
|
145
150
|
node.url = transformLink(node.url, file)
|
|
146
151
|
|
|
147
|
-
return
|
|
152
|
+
return CONTINUE
|
|
148
153
|
}
|
|
149
154
|
|
|
150
155
|
function handleLinkElements(node: MdxJsxFlowElement | MdxJsxTextElement, file: VFile) {
|
|
@@ -194,18 +199,74 @@ function handleImages(node: Image, file: VFile) {
|
|
|
194
199
|
return SKIP
|
|
195
200
|
}
|
|
196
201
|
|
|
197
|
-
function handleMediaElements(node: MdxJsxFlowElement, file: VFile) {
|
|
198
|
-
const
|
|
199
|
-
(attribute
|
|
200
|
-
)
|
|
202
|
+
function handleMediaElements(node: MdxJsxFlowElement | MdxJsxTextElement, file: VFile) {
|
|
203
|
+
for (const attribute of node.attributes) {
|
|
204
|
+
if (attribute.type !== 'mdxJsxAttribute' || typeof attribute.value !== 'string') continue
|
|
201
205
|
|
|
202
|
-
|
|
206
|
+
if (attribute.name === 'src' && isPublicAsset(attribute.value)) {
|
|
207
|
+
attribute.value = addVersionToPublicAsset(attribute.value, file)
|
|
208
|
+
} else if (attribute.name === 'srcset' || attribute.name === 'srcSet') {
|
|
209
|
+
attribute.value = addVersionToPublicSrcset(attribute.value, file)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
203
212
|
|
|
204
|
-
|
|
213
|
+
return CONTINUE
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Raw HTML nodes only exist in non-MDX files (MDX parses HTML as JSX) and are not re-serialized to preserve them as
|
|
217
|
+
// authored, e.g. unclosed inline tags, and only the transformed attribute values are updated.
|
|
218
|
+
function handleHtml(node: Html, file: VFile) {
|
|
219
|
+
const tree = fromHtml(node.value, { fragment: true, verbose: true })
|
|
220
|
+
// Updates are keyed by attribute offset as misnested HTML can lead the parser to recreate elements which share the
|
|
221
|
+
// source position of the original element and would be updated multiple times.
|
|
222
|
+
const updates = new Map<number, HtmlAttribute>()
|
|
223
|
+
|
|
224
|
+
visit(tree, 'element', (element) => {
|
|
225
|
+
if (element.tagName === 'a') {
|
|
226
|
+
const href = getHtmlAttribute(node.value, element, 'href')
|
|
227
|
+
if (!href || updates.has(href.start)) return
|
|
228
|
+
|
|
229
|
+
updates.set(href.start, { ...href, value: transformLink(href.value, file) })
|
|
230
|
+
} else if (mediaElements.has(element.tagName)) {
|
|
231
|
+
const src = getHtmlAttribute(node.value, element, 'src')
|
|
232
|
+
|
|
233
|
+
if (src && !updates.has(src.start) && isPublicAsset(src.value)) {
|
|
234
|
+
updates.set(src.start, { ...src, value: addVersionToPublicAsset(src.value, file) })
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const srcset = getHtmlAttribute(node.value, element, 'srcSet')
|
|
238
|
+
|
|
239
|
+
if (srcset && !updates.has(srcset.start)) {
|
|
240
|
+
updates.set(srcset.start, { ...srcset, value: addVersionToPublicSrcset(srcset.value, file) })
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
// Update attributes from the end to keep the offsets of the previous ones valid.
|
|
246
|
+
const sortedUpdates = updates
|
|
247
|
+
.values()
|
|
248
|
+
.toArray()
|
|
249
|
+
.toSorted((a, b) => b.start - a.start)
|
|
250
|
+
|
|
251
|
+
for (const { end, start, value } of sortedUpdates) {
|
|
252
|
+
node.value = `${node.value.slice(0, start)}${value}${node.value.slice(end)}`
|
|
253
|
+
}
|
|
205
254
|
|
|
206
255
|
return SKIP
|
|
207
256
|
}
|
|
208
257
|
|
|
258
|
+
function getHtmlAttribute(html: string, element: Element, property: string): HtmlAttribute | undefined {
|
|
259
|
+
const position = element.data?.position.properties?.[property]
|
|
260
|
+
if (position?.start.offset === undefined || position.end.offset === undefined) return
|
|
261
|
+
|
|
262
|
+
const match = htmlAttributeRegex.exec(html.slice(position.start.offset, position.end.offset))
|
|
263
|
+
if (!match?.groups?.['prefix'] || !match.groups['value']) return
|
|
264
|
+
|
|
265
|
+
const start = position.start.offset + match.groups['prefix'].length
|
|
266
|
+
|
|
267
|
+
return { end: start + match.groups['value'].length, start, value: match.groups['value'] }
|
|
268
|
+
}
|
|
269
|
+
|
|
209
270
|
function handleImports(node: MdxjsEsm, file: VFile) {
|
|
210
271
|
node.value = node.value.replaceAll(importPathRegex, (match, start, importPath: string, end) => {
|
|
211
272
|
if (!importPath.startsWith('../')) return match
|
|
@@ -232,8 +293,7 @@ function addVersionToLink(link: string, file: VFile) {
|
|
|
232
293
|
|
|
233
294
|
const segments = link.split('/')
|
|
234
295
|
|
|
235
|
-
|
|
236
|
-
if (file.data.locale && segments[1] === file.data.locale) slugVersionIndex = 2
|
|
296
|
+
const slugVersionIndex = file.data.locale && segments[1] === file.data.locale ? 2 : 1
|
|
237
297
|
|
|
238
298
|
segments.splice(slugVersionIndex, 0, file.data.version.slug)
|
|
239
299
|
|
|
@@ -252,11 +312,11 @@ function addVersionToAstroAsset(asset: string, file: VFile) {
|
|
|
252
312
|
if (source.href.startsWith(file.data.docsDir.href)) return asset
|
|
253
313
|
|
|
254
314
|
const segments = asset.split('/')
|
|
255
|
-
segments.splice(-1, 0, file.data.version.slug)
|
|
315
|
+
segments.splice(Math.max(segments.length - 1, 0), 0, file.data.version.slug)
|
|
256
316
|
|
|
257
317
|
addVersionAsset(file, { source, dest: new URL(segments.join('/'), file.data.url) })
|
|
258
318
|
|
|
259
|
-
segments.
|
|
319
|
+
segments.unshift('..')
|
|
260
320
|
|
|
261
321
|
return segments.join('/')
|
|
262
322
|
}
|
|
@@ -267,13 +327,17 @@ function addVersionToPublicAsset(asset: string, file: VFile) {
|
|
|
267
327
|
const source = new URL(`.${asset}`, file.data.publicDir)
|
|
268
328
|
|
|
269
329
|
const segments = asset.split('/')
|
|
270
|
-
segments.splice(-1, 0, file.data.version.slug)
|
|
330
|
+
segments.splice(Math.max(segments.length - 1, 0), 0, file.data.version.slug)
|
|
271
331
|
|
|
272
332
|
addVersionAsset(file, { source, dest: new URL(`.${segments.join('/')}`, file.data.publicDir) })
|
|
273
333
|
|
|
274
334
|
return segments.join('/')
|
|
275
335
|
}
|
|
276
336
|
|
|
337
|
+
function addVersionToPublicSrcset(srcset: string, file: VFile) {
|
|
338
|
+
return srcset.replaceAll(srcsetUrlRegex, (url) => (isPublicAsset(url) ? addVersionToPublicAsset(url, file) : url))
|
|
339
|
+
}
|
|
340
|
+
|
|
277
341
|
function addVersionAsset(file: VFile, asset: VersionAsset) {
|
|
278
342
|
file.data.assets?.push(asset)
|
|
279
343
|
}
|
|
@@ -298,6 +362,12 @@ export interface TransformContext {
|
|
|
298
362
|
version: Version
|
|
299
363
|
}
|
|
300
364
|
|
|
365
|
+
interface HtmlAttribute {
|
|
366
|
+
end: number
|
|
367
|
+
start: number
|
|
368
|
+
value: string
|
|
369
|
+
}
|
|
370
|
+
|
|
301
371
|
declare module 'vfile' {
|
|
302
372
|
interface DataMap extends TransformContext {}
|
|
303
373
|
}
|
package/libs/plugin.ts
CHANGED
|
@@ -17,7 +17,8 @@ export function overrideComponents(
|
|
|
17
17
|
): StarlightUserConfig['components'] {
|
|
18
18
|
const components = { ...starlightConfig.components }
|
|
19
19
|
for (const { name, fallback } of overrides) {
|
|
20
|
-
|
|
20
|
+
const override = starlightConfig.components?.[name]
|
|
21
|
+
if (override) {
|
|
21
22
|
logger.warn(`A \`<${name}>\` component override is already defined in your Starlight configuration.`)
|
|
22
23
|
logger.warn(
|
|
23
24
|
`To use \`starlight-versions\`, either remove this override or manually render the content from \`starlight-versions/components/${fallback}.astro\`.`,
|
package/libs/starlight.ts
CHANGED
|
@@ -59,7 +59,7 @@ export function getURLSlug(url: URL) {
|
|
|
59
59
|
} else if (segments.at(-1)?.endsWith(htmlExt)) {
|
|
60
60
|
// Remove trailing `.html`.
|
|
61
61
|
const last = segments.pop()
|
|
62
|
-
if (last) segments.push(last.slice(0, -
|
|
62
|
+
if (last) segments.push(last.slice(0, -htmlExt.length))
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
return segments.filter(Boolean).join('/')
|
|
@@ -70,7 +70,7 @@ export function getDocLocale(slug: string, starlightConfig: StarlightUserConfig)
|
|
|
70
70
|
|
|
71
71
|
if (locales.length === 0) return undefined
|
|
72
72
|
|
|
73
|
-
const localeSegment = slug.split('/')[0]
|
|
73
|
+
const localeSegment = slug.split('/', 1)[0]
|
|
74
74
|
|
|
75
75
|
if (!localeSegment) return undefined
|
|
76
76
|
|
|
@@ -89,24 +89,29 @@ export function addPrefixToSidebarConfig(
|
|
|
89
89
|
return sidebar.map((item) => {
|
|
90
90
|
if (typeof item === 'string') {
|
|
91
91
|
return isExcludedInternalSidebarSlug(item, excludedSlugs) ? item : addPrefixToSlug(prefix, item)
|
|
92
|
-
}
|
|
92
|
+
}
|
|
93
|
+
if ('items' in item) {
|
|
93
94
|
return {
|
|
94
95
|
...item,
|
|
95
96
|
items: addPrefixToSidebarConfig(prefix, item.items, excludedSlugs),
|
|
96
97
|
}
|
|
97
|
-
}
|
|
98
|
+
}
|
|
99
|
+
if (isSidebarLegacyAutoGroup(item)) {
|
|
98
100
|
return addPrefixToLegacyAutogeneratedGroup(prefix, item)
|
|
99
|
-
}
|
|
101
|
+
}
|
|
102
|
+
if ('autogenerate' in item) {
|
|
100
103
|
return {
|
|
101
104
|
...item,
|
|
102
105
|
autogenerate: addPrefixToAutogenerate(prefix, item.autogenerate),
|
|
103
106
|
}
|
|
104
|
-
}
|
|
107
|
+
}
|
|
108
|
+
if ('slug' in item) {
|
|
105
109
|
return {
|
|
106
110
|
...item,
|
|
107
111
|
slug: isExcludedInternalSidebarSlug(item.slug, excludedSlugs) ? item.slug : addPrefixToSlug(prefix, item.slug),
|
|
108
112
|
}
|
|
109
|
-
}
|
|
113
|
+
}
|
|
114
|
+
if (isAbsoluteLink(item.link)) {
|
|
110
115
|
return item
|
|
111
116
|
}
|
|
112
117
|
|
package/libs/versions.ts
CHANGED
|
@@ -82,16 +82,17 @@ export async function ensureNewVersion(
|
|
|
82
82
|
) {
|
|
83
83
|
const docsDir = new URL('content/docs/', astroConfig.srcDir)
|
|
84
84
|
const newVersion = await checkForNewVersion(config, docsDir)
|
|
85
|
-
const locales = Object.keys(starlightConfig.locales ?? {})
|
|
86
85
|
|
|
87
86
|
if (!newVersion) return
|
|
88
87
|
|
|
88
|
+
const locales = Object.keys(starlightConfig.locales ?? {})
|
|
89
|
+
|
|
89
90
|
const excludedDocs = await getExcludedDocs(
|
|
90
91
|
config,
|
|
91
92
|
locales.filter((locale) => locale !== 'root'),
|
|
92
93
|
docsDir,
|
|
93
94
|
)
|
|
94
|
-
const excludedSlugs =
|
|
95
|
+
const excludedSlugs = excludedDocs.values().toArray().toSorted()
|
|
95
96
|
|
|
96
97
|
const assets: VersionAsset[] = []
|
|
97
98
|
|
|
@@ -112,7 +113,7 @@ export async function ensureNewVersion(
|
|
|
112
113
|
}
|
|
113
114
|
|
|
114
115
|
// Skip root version directories.
|
|
115
|
-
if (
|
|
116
|
+
if (Object.hasOwn(config.versionsBySlug, entry.name)) return true
|
|
116
117
|
|
|
117
118
|
const localeDir = locales.find((locale) => locale === entry.name)
|
|
118
119
|
|
|
@@ -213,12 +214,8 @@ export function getVersionURL(
|
|
|
213
214
|
const canonicalSlug = getCanonicalSlug(config, starlightConfig, url)
|
|
214
215
|
|
|
215
216
|
if (version && isSlugExcludedFromVersion(config, version, canonicalSlug)) {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
starlightConfig,
|
|
219
|
-
url,
|
|
220
|
-
undefined,
|
|
221
|
-
)
|
|
217
|
+
config = { ...config, current: { ...config.current, redirect: 'same-page' } }
|
|
218
|
+
version = undefined
|
|
222
219
|
}
|
|
223
220
|
|
|
224
221
|
const versionURL = new URL(url)
|
|
@@ -236,7 +233,7 @@ export function getVersionURL(
|
|
|
236
233
|
let localeSegment: string | undefined
|
|
237
234
|
|
|
238
235
|
const isHTML = getExtension(versionURL.pathname) === '.html'
|
|
239
|
-
const [, firstSegment, secondSegment] = versionURL.pathname.split('/')
|
|
236
|
+
const [, firstSegment, secondSegment] = versionURL.pathname.split('/', 3)
|
|
240
237
|
|
|
241
238
|
if (starlightConfig.isMultilingual || starlightConfig.locales) {
|
|
242
239
|
const versionOrLocale = firstSegment?.replace('.html', '')
|
|
@@ -254,11 +251,11 @@ export function getVersionURL(
|
|
|
254
251
|
const isRootHTML = baseSegment && getExtension(baseSegment) === '.html'
|
|
255
252
|
const baseSlug = baseSegment && isRootHTML ? stripExtension(baseSegment) : baseSegment
|
|
256
253
|
|
|
257
|
-
if (baseSlug &&
|
|
254
|
+
if (baseSlug && Object.hasOwn(config.versionsBySlug, baseSlug)) {
|
|
258
255
|
if (versionSlug) {
|
|
259
256
|
versionURL.pathname =
|
|
260
257
|
versionRedirect === 'same-page'
|
|
261
|
-
? versionURL.pathname.replace(baseSlug, versionSlug)
|
|
258
|
+
? versionURL.pathname.replace(baseSlug, () => versionSlug)
|
|
262
259
|
: `${versionSlug}${isHTML ? '.html' : '/'}`
|
|
263
260
|
} else if (isRootHTML) {
|
|
264
261
|
versionURL.pathname = '/index.html'
|
|
@@ -458,7 +455,7 @@ export function getVersionFromPaginationLink(
|
|
|
458
455
|
|
|
459
456
|
if (locale) {
|
|
460
457
|
// Remove the locale segment if the current locale is not a root locale.
|
|
461
|
-
segments.
|
|
458
|
+
segments.shift()
|
|
462
459
|
}
|
|
463
460
|
|
|
464
461
|
const versionSegment = segments[0]
|
|
@@ -488,11 +485,14 @@ async function getExcludedDocs(config: StarlightVersionsConfig, locales: string[
|
|
|
488
485
|
const docPath = getDocPath(docsDir, entryURL)
|
|
489
486
|
|
|
490
487
|
if (isDirectory) {
|
|
491
|
-
const [firstSegment, secondSegment] = docPath.split('/')
|
|
488
|
+
const [firstSegment, secondSegment] = docPath.split('/', 2)
|
|
492
489
|
|
|
493
490
|
if (
|
|
494
|
-
(firstSegment &&
|
|
495
|
-
(firstSegment &&
|
|
491
|
+
(firstSegment && Object.hasOwn(config.versionsBySlug, firstSegment)) ||
|
|
492
|
+
(firstSegment &&
|
|
493
|
+
secondSegment &&
|
|
494
|
+
locales.includes(firstSegment) &&
|
|
495
|
+
Object.hasOwn(config.versionsBySlug, secondSegment))
|
|
496
496
|
) {
|
|
497
497
|
continue
|
|
498
498
|
}
|
|
@@ -505,7 +505,7 @@ async function getExcludedDocs(config: StarlightVersionsConfig, locales: string[
|
|
|
505
505
|
if (
|
|
506
506
|
!entry.isFile() ||
|
|
507
507
|
!docsExtensions.has(getExtension(docPath)) ||
|
|
508
|
-
|
|
508
|
+
config.exclude.every((excludeGlob) => !path.posix.matchesGlob(docPath, excludeGlob))
|
|
509
509
|
) {
|
|
510
510
|
continue
|
|
511
511
|
}
|
|
@@ -532,12 +532,15 @@ async function checkForNewVersion(config: StarlightVersionsConfig, docsDir: URL)
|
|
|
532
532
|
}
|
|
533
533
|
|
|
534
534
|
for (const version of config.versions) {
|
|
535
|
-
if (
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
535
|
+
if (docsDirDirectories.has(version.slug)) {
|
|
536
|
+
continue
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
if (newVersion) {
|
|
540
|
+
throw new Error('Only one new version can be configured at a time.')
|
|
540
541
|
}
|
|
542
|
+
|
|
543
|
+
newVersion = version
|
|
541
544
|
}
|
|
542
545
|
|
|
543
546
|
return newVersion
|
package/middleware.ts
CHANGED
|
@@ -74,7 +74,7 @@ function getPaginationFromSidebar(
|
|
|
74
74
|
route.pagination.prev,
|
|
75
75
|
)
|
|
76
76
|
const next = applyPaginationConfig(
|
|
77
|
-
currentIndex
|
|
77
|
+
currentIndex === -1 ? undefined : entries[currentIndex + 1],
|
|
78
78
|
starlightConfig.pagination,
|
|
79
79
|
route.entry.data.next,
|
|
80
80
|
route.pagination.next,
|
|
@@ -93,11 +93,12 @@ function applyPaginationConfig(
|
|
|
93
93
|
// Explicitly remove the link.
|
|
94
94
|
if (config === false) return undefined
|
|
95
95
|
// Use the generated link if any.
|
|
96
|
-
|
|
96
|
+
if (config === true) return link
|
|
97
97
|
// If a link exists, update its label if needed.
|
|
98
|
-
|
|
98
|
+
if (typeof config === 'string' && link) {
|
|
99
99
|
return { ...link, label: config }
|
|
100
|
-
}
|
|
100
|
+
}
|
|
101
|
+
if (typeof config === 'object') {
|
|
101
102
|
if (link) {
|
|
102
103
|
// If a link exists, update both its label and href if needed.
|
|
103
104
|
return {
|
|
@@ -107,7 +108,8 @@ function applyPaginationConfig(
|
|
|
107
108
|
// Explicitly remove sidebar link attributes for prev/next links.
|
|
108
109
|
attrs: {},
|
|
109
110
|
}
|
|
110
|
-
}
|
|
111
|
+
}
|
|
112
|
+
if (config.link && config.label) {
|
|
111
113
|
// If there is no link and the frontmatter contains both a URL and a label, use it.
|
|
112
114
|
return existing
|
|
113
115
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "starlight-versions",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Starlight plugin to version documentation pages.",
|
|
6
6
|
"author": "HiDeoo <github@hideoo.dev> (https://hideoo.dev)",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@pagefind/default-ui": "^1.3.0",
|
|
24
24
|
"github-slugger": "^2.0.0",
|
|
25
|
+
"hast-util-from-html": "^2.0.3",
|
|
25
26
|
"mdast-util-mdx-jsx": "^3.2.0",
|
|
26
27
|
"mdast-util-mdxjs-esm": "^2.0.1",
|
|
27
28
|
"remark": "^15.0.1",
|
|
@@ -33,6 +34,7 @@
|
|
|
33
34
|
"yaml": "^2.8.2"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
37
|
+
"@types/hast": "^3.0.4",
|
|
36
38
|
"@types/mdast": "^4.0.4",
|
|
37
39
|
"fast-glob": "^3.3.3",
|
|
38
40
|
"vitest": "^4.0.18"
|
|
@@ -40,9 +42,6 @@
|
|
|
40
42
|
"peerDependencies": {
|
|
41
43
|
"@astrojs/starlight": ">=0.39.0"
|
|
42
44
|
},
|
|
43
|
-
"engines": {
|
|
44
|
-
"node": ">=22.12.0"
|
|
45
|
-
},
|
|
46
45
|
"publishConfig": {
|
|
47
46
|
"access": "public"
|
|
48
47
|
},
|
|
@@ -64,6 +63,6 @@
|
|
|
64
63
|
"bugs": "https://github.com/HiDeoo/starlight-versions/issues",
|
|
65
64
|
"scripts": {
|
|
66
65
|
"test": "vitest",
|
|
67
|
-
"lint": "eslint . --
|
|
66
|
+
"lint": "eslint . --max-warnings=0"
|
|
68
67
|
}
|
|
69
68
|
}
|