@astrojs/starlight 0.41.10 → 0.42.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/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/components/MobileMenuToggle.astro +65 -0
- package/{components → dist/components}/PageFrame.astro +32 -8
- package/dist/components-internals/Icons.d.ts +415 -0
- package/dist/components-internals/Icons.js +140 -0
- package/dist/components-internals/SidebarPersistState.d.ts +1 -0
- package/dist/components-internals/SidebarPersistState.js +53 -0
- package/dist/components-internals/TableOfContents/starlight-toc.d.ts +18 -0
- package/dist/components-internals/TableOfContents/starlight-toc.js +88 -0
- package/dist/constants.d.ts +4 -0
- package/dist/constants.js +4 -0
- package/{expressive-code.d.ts → dist/expressive-code.d.ts} +6 -13
- package/dist/expressive-code.js +31 -0
- package/dist/global.d.ts +62 -0
- package/dist/global.js +2 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +109 -0
- package/dist/integrations/aside-utils.d.ts +9 -0
- package/dist/integrations/aside-utils.js +35 -0
- package/dist/integrations/expressive-code/hast.d.ts +1 -0
- package/dist/integrations/expressive-code/hast.js +2 -0
- package/dist/integrations/expressive-code/index.d.ts +60 -0
- package/dist/integrations/expressive-code/index.js +48 -0
- package/dist/integrations/expressive-code/preprocessor.d.ts +17 -0
- package/dist/integrations/expressive-code/preprocessor.js +76 -0
- package/dist/integrations/expressive-code/themes/night-owl-dark.js +4 -0
- package/dist/integrations/expressive-code/themes/night-owl-light.js +4 -0
- package/dist/integrations/expressive-code/theming.d.ts +16 -0
- package/dist/integrations/expressive-code/theming.js +71 -0
- package/dist/integrations/expressive-code/translations.d.ts +8 -0
- package/dist/integrations/expressive-code/translations.js +26 -0
- package/dist/integrations/markdown-icon.d.ts +8 -0
- package/dist/integrations/markdown-icon.js +14 -0
- package/dist/integrations/markdown-plugins.d.ts +18 -0
- package/dist/integrations/markdown-plugins.js +36 -0
- package/dist/integrations/markdown-processor.d.ts +29 -0
- package/dist/integrations/markdown-processor.js +44 -0
- package/dist/integrations/pagefind.d.ts +7 -0
- package/dist/integrations/pagefind.js +34 -0
- package/dist/integrations/rehype-code-rtl-support.d.ts +21 -0
- package/dist/integrations/rehype-code-rtl-support.js +36 -0
- package/dist/integrations/rehype-heading-links.d.ts +10 -0
- package/dist/integrations/rehype-heading-links.js +57 -0
- package/dist/integrations/remark-asides.d.ts +32 -0
- package/dist/integrations/remark-asides.js +166 -0
- package/dist/integrations/remark-rehype.d.ts +17 -0
- package/dist/integrations/remark-rehype.js +51 -0
- package/dist/integrations/satteri.d.ts +13 -0
- package/dist/integrations/satteri.js +209 -0
- package/dist/integrations/shared/absolutePathToLang.d.ts +10 -0
- package/dist/integrations/shared/absolutePathToLang.js +13 -0
- package/dist/integrations/shared/localeToLang.d.ts +10 -0
- package/dist/integrations/shared/localeToLang.js +13 -0
- package/dist/integrations/shared/slugToLocale.d.ts +12 -0
- package/dist/integrations/shared/slugToLocale.js +15 -0
- package/dist/integrations/sitemap.d.ts +12 -0
- package/dist/integrations/sitemap.js +19 -0
- package/dist/integrations/vite-layer-order.d.ts +15 -0
- package/dist/integrations/vite-layer-order.js +56 -0
- package/dist/integrations/vite-lazy-barrel-optimization.d.ts +12 -0
- package/dist/integrations/vite-lazy-barrel-optimization.js +33 -0
- package/dist/integrations/vite-virtual-modules.d.ts +14 -0
- package/dist/integrations/vite-virtual-modules.js +108 -0
- package/dist/internal.d.ts +3 -0
- package/dist/internal.js +3 -0
- package/dist/loaders.d.ts +20 -0
- package/dist/loaders.js +49 -0
- package/dist/locals.d.ts +15 -0
- package/dist/locals.js +33 -0
- package/dist/package.js +4 -0
- package/{props.ts → dist/props.d.ts} +6 -4
- package/dist/props.js +1 -0
- package/dist/route-data.d.ts +7 -0
- package/dist/route-data.js +6 -0
- package/dist/schema.d.ts +426 -0
- package/dist/schema.js +103 -0
- package/dist/schemas/badge.d.ts +86 -0
- package/dist/schemas/badge.js +39 -0
- package/dist/schemas/components.d.ts +236 -0
- package/dist/schemas/components.js +36 -0
- package/dist/schemas/expressiveCode.d.ts +7 -0
- package/dist/schemas/expressiveCode.js +5 -0
- package/dist/schemas/favicon.d.ts +9 -0
- package/dist/schemas/favicon.js +32 -0
- package/dist/schemas/head.d.ts +33 -0
- package/dist/schemas/head.js +41 -0
- package/dist/schemas/hero.d.ts +319 -0
- package/dist/schemas/hero.js +73 -0
- package/dist/schemas/i18n.d.ts +125 -0
- package/dist/schemas/i18n.js +76 -0
- package/dist/schemas/icon.d.ts +284 -0
- package/dist/schemas/icon.js +7 -0
- package/dist/schemas/locale.d.ts +20 -0
- package/dist/schemas/locale.js +11 -0
- package/dist/schemas/logo.d.ts +32 -0
- package/dist/schemas/logo.js +14 -0
- package/dist/schemas/pagefind.d.ts +166 -0
- package/dist/schemas/pagefind.js +31 -0
- package/dist/schemas/prevNextLink.d.ts +10 -0
- package/dist/schemas/prevNextLink.js +14 -0
- package/dist/schemas/sidebar.d.ts +205 -0
- package/dist/schemas/sidebar.js +71 -0
- package/dist/schemas/site-title.d.ts +7 -0
- package/dist/schemas/site-title.js +17 -0
- package/dist/schemas/social.d.ts +292 -0
- package/dist/schemas/social.js +18 -0
- package/dist/schemas/tableOfContents.d.ts +24 -0
- package/dist/schemas/tableOfContents.js +16 -0
- package/{style → dist/style}/anchor-links.css +13 -1
- package/dist/translations/ar.js +36 -0
- package/dist/translations/ca.js +46 -0
- package/dist/translations/cs.js +46 -0
- package/dist/translations/da.js +33 -0
- package/dist/translations/de.js +33 -0
- package/dist/translations/el.js +33 -0
- package/dist/translations/en.js +33 -0
- package/dist/translations/es.js +46 -0
- package/dist/translations/fa.js +33 -0
- package/dist/translations/fi.js +33 -0
- package/dist/translations/fr.js +36 -0
- package/dist/translations/gl.js +46 -0
- package/dist/translations/he.js +33 -0
- package/dist/translations/hi.js +36 -0
- package/dist/translations/hu.js +46 -0
- package/dist/translations/id.js +33 -0
- package/dist/translations/index.d.ts +48 -0
- package/dist/translations/index.js +75 -0
- package/dist/translations/it.js +36 -0
- package/dist/translations/ja.js +36 -0
- package/dist/translations/ko.js +36 -0
- package/dist/translations/lv.js +33 -0
- package/dist/translations/nb.js +33 -0
- package/dist/translations/nl.js +33 -0
- package/dist/translations/pl.js +36 -0
- package/dist/translations/pt.js +36 -0
- package/dist/translations/ro.js +33 -0
- package/dist/translations/ru.js +36 -0
- package/dist/translations/sk.js +33 -0
- package/dist/translations/sv.js +33 -0
- package/dist/translations/th.js +33 -0
- package/dist/translations/tr.js +33 -0
- package/dist/translations/uk.js +33 -0
- package/dist/translations/vi.js +33 -0
- package/dist/translations/zh-CN.js +36 -0
- package/dist/translations/zh-TW.js +36 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.js +1 -0
- package/{user-components → dist/user-components}/FileTree.astro +1 -1
- package/{user-components → dist/user-components}/Steps.astro +1 -1
- package/{user-components → dist/user-components}/TabItem.astro +1 -1
- package/{user-components → dist/user-components}/Tabs.astro +1 -1
- package/dist/user-components/file-tree-icons.d.ts +178 -0
- package/dist/user-components/file-tree-icons.js +632 -0
- package/dist/user-components/file-tree-processor.d.ts +16 -0
- package/dist/user-components/file-tree-processor.js +132 -0
- package/dist/user-components/steps-processor.d.ts +10 -0
- package/dist/user-components/steps-processor.js +39 -0
- package/dist/user-components/tabs-processor.d.ts +23 -0
- package/dist/user-components/tabs-processor.js +70 -0
- package/dist/utils/base.d.ts +7 -0
- package/dist/utils/base.js +15 -0
- package/dist/utils/canonical.d.ts +10 -0
- package/dist/utils/canonical.js +14 -0
- package/dist/utils/collection-fs.d.ts +13 -0
- package/dist/utils/collection-fs.js +19 -0
- package/{utils/collection.ts → dist/utils/collection.d.ts} +9 -20
- package/dist/utils/collection.js +26 -0
- package/dist/utils/createPathFormatter.d.ts +9 -0
- package/dist/utils/createPathFormatter.js +35 -0
- package/dist/utils/createTranslationSystem.d.ts +23 -0
- package/dist/utils/createTranslationSystem.js +84 -0
- package/dist/utils/error-map.d.ts +23 -0
- package/dist/utils/error-map.js +125 -0
- package/dist/utils/format-path.d.ts +4 -0
- package/dist/utils/format-path.js +9 -0
- package/dist/utils/generateToC.d.ts +14 -0
- package/dist/utils/generateToC.js +25 -0
- package/dist/utils/git.d.ts +12 -0
- package/dist/utils/git.js +71 -0
- package/dist/utils/gitInlined.d.ts +6 -0
- package/dist/utils/gitInlined.js +11 -0
- package/dist/utils/head.d.ts +7 -0
- package/dist/utils/head.js +233 -0
- package/dist/utils/i18n.d.ts +50 -0
- package/dist/utils/i18n.js +141 -0
- package/dist/utils/localizedUrl.d.ts +8 -0
- package/dist/utils/localizedUrl.js +28 -0
- package/dist/utils/navigation.d.ts +19 -0
- package/dist/utils/navigation.js +353 -0
- package/dist/utils/path.d.ts +21 -0
- package/dist/utils/path.js +51 -0
- package/dist/utils/plugins.d.ts +721 -0
- package/dist/utils/plugins.js +174 -0
- package/dist/utils/routing/data.d.ts +20 -0
- package/dist/utils/routing/data.js +127 -0
- package/dist/utils/routing/index.d.ts +21 -0
- package/dist/utils/routing/index.js +106 -0
- package/dist/utils/routing/middleware.d.ts +11 -0
- package/dist/utils/routing/middleware.js +65 -0
- package/dist/utils/routing/types.d.ts +93 -0
- package/dist/utils/routing/types.js +1 -0
- package/dist/utils/slugs.d.ts +45 -0
- package/dist/utils/slugs.js +104 -0
- package/dist/utils/starlight-page.d.ts +36 -0
- package/dist/utils/starlight-page.js +120 -0
- package/dist/utils/translations-fs.d.ts +15 -0
- package/dist/utils/translations-fs.js +39 -0
- package/dist/utils/translations.d.ts +20 -0
- package/dist/utils/translations.js +29 -0
- package/dist/utils/types.d.ts +5 -0
- package/dist/utils/types.js +1 -0
- package/dist/utils/url.d.ts +7 -0
- package/{utils/url.ts → dist/utils/url.js} +5 -4
- package/dist/utils/user-config.d.ts +2055 -0
- package/dist/utils/user-config.js +136 -0
- package/dist/utils/validateLogoImports.d.ts +5 -0
- package/dist/utils/validateLogoImports.js +16 -0
- package/dist/utils/zodDeepMerge.d.ts +16 -0
- package/dist/utils/zodDeepMerge.js +53 -0
- package/package.json +62 -33
- package/CHANGELOG.md +0 -3043
- package/components/MobileMenuToggle.astro +0 -114
- package/components-internals/Icons.ts +0 -248
- package/components-internals/SidebarPersistState.ts +0 -71
- package/components-internals/TableOfContents/starlight-toc.ts +0 -127
- package/constants.ts +0 -4
- package/expressive-code.mjs +0 -23
- package/global.d.ts +0 -11
- package/i18n.d.ts +0 -18
- package/index.ts +0 -200
- package/integrations/aside-utils.ts +0 -41
- package/integrations/expressive-code/hast.d.ts +0 -5
- package/integrations/expressive-code/hast.mjs +0 -9
- package/integrations/expressive-code/index.ts +0 -125
- package/integrations/expressive-code/preprocessor.ts +0 -126
- package/integrations/expressive-code/themes/night-owl-dark.jsonc +0 -1796
- package/integrations/expressive-code/themes/night-owl-light.jsonc +0 -1695
- package/integrations/expressive-code/theming.ts +0 -105
- package/integrations/expressive-code/translations.ts +0 -36
- package/integrations/markdown-icon.ts +0 -13
- package/integrations/markdown-plugins.ts +0 -71
- package/integrations/markdown-processor.ts +0 -64
- package/integrations/pagefind.ts +0 -60
- package/integrations/rehype-code-rtl-support.ts +0 -37
- package/integrations/rehype-heading-links.ts +0 -79
- package/integrations/remark-asides.ts +0 -219
- package/integrations/remark-rehype.ts +0 -87
- package/integrations/satteri.ts +0 -265
- package/integrations/shared/absolutePathToLang.ts +0 -26
- package/integrations/shared/localeToLang.ts +0 -15
- package/integrations/shared/slugToLocale.ts +0 -18
- package/integrations/sitemap.ts +0 -23
- package/integrations/vite-layer-order.ts +0 -69
- package/integrations/vite-lazy-barrel-optimization.ts +0 -40
- package/integrations/vite-virtual-modules.ts +0 -175
- package/internal.ts +0 -6
- package/loaders.ts +0 -63
- package/locals.d.ts +0 -43
- package/locals.ts +0 -43
- package/route-data.ts +0 -11
- package/schema.ts +0 -167
- package/schemas/badge.ts +0 -40
- package/schemas/components.ts +0 -265
- package/schemas/expressiveCode.ts +0 -12
- package/schemas/favicon.ts +0 -40
- package/schemas/head.ts +0 -50
- package/schemas/hero.ts +0 -69
- package/schemas/i18n.ts +0 -244
- package/schemas/icon.ts +0 -7
- package/schemas/logo.ts +0 -28
- package/schemas/pagefind.ts +0 -128
- package/schemas/prevNextLink.ts +0 -18
- package/schemas/sidebar.ts +0 -163
- package/schemas/site-title.ts +0 -20
- package/schemas/social.ts +0 -23
- package/schemas/tableOfContents.ts +0 -21
- package/translations/README.md +0 -14
- package/translations/ar.json +0 -33
- package/translations/ca.json +0 -43
- package/translations/cs.json +0 -43
- package/translations/da.json +0 -30
- package/translations/de.json +0 -30
- package/translations/el.json +0 -30
- package/translations/en.json +0 -30
- package/translations/es.json +0 -43
- package/translations/fa.json +0 -30
- package/translations/fi.json +0 -30
- package/translations/fr.json +0 -33
- package/translations/gl.json +0 -43
- package/translations/he.json +0 -30
- package/translations/hi.json +0 -33
- package/translations/hu.json +0 -43
- package/translations/id.json +0 -30
- package/translations/index.ts +0 -76
- package/translations/it.json +0 -33
- package/translations/ja.json +0 -33
- package/translations/ko.json +0 -33
- package/translations/lv.json +0 -30
- package/translations/nb.json +0 -30
- package/translations/nl.json +0 -30
- package/translations/pl.json +0 -33
- package/translations/pt.json +0 -33
- package/translations/ro.json +0 -30
- package/translations/ru.json +0 -33
- package/translations/sk.json +0 -30
- package/translations/sv.json +0 -30
- package/translations/th.json +0 -30
- package/translations/tr.json +0 -30
- package/translations/uk.json +0 -30
- package/translations/vi.json +0 -30
- package/translations/zh-CN.json +0 -33
- package/translations/zh-TW.json +0 -33
- package/types.ts +0 -7
- package/user-components/file-tree-icons.ts +0 -782
- package/user-components/rehype-file-tree.ts +0 -251
- package/user-components/rehype-steps.ts +0 -85
- package/user-components/rehype-tabs.ts +0 -121
- package/utils/base.ts +0 -15
- package/utils/canonical.ts +0 -19
- package/utils/collection-fs.ts +0 -20
- package/utils/createPathFormatter.ts +0 -60
- package/utils/createTranslationSystem.ts +0 -137
- package/utils/error-map.ts +0 -222
- package/utils/format-path.ts +0 -7
- package/utils/generateToC.ts +0 -33
- package/utils/git.ts +0 -121
- package/utils/gitInlined.ts +0 -20
- package/utils/head.ts +0 -235
- package/utils/i18n.ts +0 -221
- package/utils/localizedUrl.ts +0 -51
- package/utils/navigation.ts +0 -566
- package/utils/path.ts +0 -58
- package/utils/plugins.ts +0 -498
- package/utils/routing/data.ts +0 -154
- package/utils/routing/index.ts +0 -135
- package/utils/routing/middleware.ts +0 -81
- package/utils/routing/types.ts +0 -101
- package/utils/slugs.ts +0 -119
- package/utils/starlight-page.ts +0 -205
- package/utils/translations-fs.ts +0 -54
- package/utils/translations.ts +0 -57
- package/utils/types.ts +0 -15
- package/utils/user-config.ts +0 -348
- package/utils/validateLogoImports.ts +0 -21
- package/utils/zodDeepMerge.ts +0 -144
- package/virtual-internal.d.ts +0 -149
- package/virtual.d.ts +0 -27
- /package/{components → dist/components}/AnchorHeading.astro +0 -0
- /package/{components → dist/components}/Banner.astro +0 -0
- /package/{components → dist/components}/ContentNotice.astro +0 -0
- /package/{components → dist/components}/ContentPanel.astro +0 -0
- /package/{components → dist/components}/DraftContentNotice.astro +0 -0
- /package/{components → dist/components}/EditLink.astro +0 -0
- /package/{components → dist/components}/FallbackContentNotice.astro +0 -0
- /package/{components → dist/components}/Footer.astro +0 -0
- /package/{components → dist/components}/Head.astro +0 -0
- /package/{components → dist/components}/Header.astro +0 -0
- /package/{components → dist/components}/Hero.astro +0 -0
- /package/{components → dist/components}/LanguageSelect.astro +0 -0
- /package/{components → dist/components}/LastUpdated.astro +0 -0
- /package/{components → dist/components}/MarkdownContent.astro +0 -0
- /package/{components → dist/components}/MobileMenuFooter.astro +0 -0
- /package/{components → dist/components}/MobileTableOfContents.astro +0 -0
- /package/{components → dist/components}/Page.astro +0 -0
- /package/{components → dist/components}/PageSidebar.astro +0 -0
- /package/{components → dist/components}/PageTitle.astro +0 -0
- /package/{components → dist/components}/Pagination.astro +0 -0
- /package/{components → dist/components}/Search.astro +0 -0
- /package/{components → dist/components}/Select.astro +0 -0
- /package/{components → dist/components}/Sidebar.astro +0 -0
- /package/{components → dist/components}/SidebarPersister.astro +0 -0
- /package/{components → dist/components}/SidebarRestorePoint.astro +0 -0
- /package/{components → dist/components}/SidebarSublist.astro +0 -0
- /package/{components → dist/components}/SiteTitle.astro +0 -0
- /package/{components → dist/components}/SkipLink.astro +0 -0
- /package/{components → dist/components}/SocialIcons.astro +0 -0
- /package/{components → dist/components}/StarlightPage.astro +0 -0
- /package/{components → dist/components}/TableOfContents.astro +0 -0
- /package/{components → dist/components}/ThemeProvider.astro +0 -0
- /package/{components → dist/components}/ThemeSelect.astro +0 -0
- /package/{components → dist/components}/TwoColumnContent.astro +0 -0
- /package/{components-internals → dist/components-internals}/TableOfContents/TableOfContentsList.astro +0 -0
- /package/{components.ts → dist/components.ts} +0 -0
- /package/{routes → dist/routes}/common.astro +0 -0
- /package/{routes → dist/routes}/ssr/404.astro +0 -0
- /package/{routes → dist/routes}/ssr/index.astro +0 -0
- /package/{routes → dist/routes}/static/404.astro +0 -0
- /package/{routes → dist/routes}/static/index.astro +0 -0
- /package/{style → dist/style}/asides.css +0 -0
- /package/{style → dist/style}/layers.css +0 -0
- /package/{style → dist/style}/markdown.css +0 -0
- /package/{style → dist/style}/print.css +0 -0
- /package/{style → dist/style}/props.css +0 -0
- /package/{style → dist/style}/reset.css +0 -0
- /package/{style → dist/style}/util.css +0 -0
- /package/{user-components → dist/user-components}/Aside.astro +0 -0
- /package/{user-components → dist/user-components}/Badge.astro +0 -0
- /package/{user-components → dist/user-components}/Card.astro +0 -0
- /package/{user-components → dist/user-components}/CardGrid.astro +0 -0
- /package/{user-components → dist/user-components}/Icon.astro +0 -0
- /package/{user-components → dist/user-components}/LinkButton.astro +0 -0
- /package/{user-components → dist/user-components}/LinkCard.astro +0 -0
package/utils/routing/index.ts
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import type { GetStaticPathsItem } from 'astro';
|
|
2
|
-
import { getCollection } from 'astro:content';
|
|
3
|
-
import config from 'virtual:starlight/user-config';
|
|
4
|
-
import { localizedSlug, slugToLocaleData, slugToParam } from '../slugs';
|
|
5
|
-
import { validateLogoImports } from '../validateLogoImports';
|
|
6
|
-
import { BuiltInDefaultLocale } from '../i18n';
|
|
7
|
-
import type { Route, StarlightDocsCollectionEntry, StarlightDocsEntry } from './types';
|
|
8
|
-
|
|
9
|
-
// Validate any user-provided logos imported correctly.
|
|
10
|
-
// We do this here so all pages trigger it and at the top level so it runs just once.
|
|
11
|
-
validateLogoImports();
|
|
12
|
-
|
|
13
|
-
interface Path extends GetStaticPathsItem {
|
|
14
|
-
params: { slug: string | undefined };
|
|
15
|
-
props: Route;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Astro is inconsistent in its `index.md` slug generation. In most cases,
|
|
20
|
-
* `index` is stripped, but in the root of a collection, we get a slug of `index`.
|
|
21
|
-
* We map that to an empty string for consistent behaviour.
|
|
22
|
-
*/
|
|
23
|
-
const normalizeIndexSlug = (slug: string) => (slug === 'index' ? '' : slug);
|
|
24
|
-
|
|
25
|
-
/** Normalize a collection entry. */
|
|
26
|
-
export function normalizeCollectionEntry(entry: StarlightDocsCollectionEntry): StarlightDocsEntry {
|
|
27
|
-
return {
|
|
28
|
-
...entry,
|
|
29
|
-
// The `id` is a slug and should be normalized.
|
|
30
|
-
id: normalizeIndexSlug(entry.id),
|
|
31
|
-
// At the moment, Starlight only supports file-based loaders which always include a `filePath`.
|
|
32
|
-
filePath: entry.filePath!,
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/** All entries in the docs content collection. */
|
|
37
|
-
const docs: StarlightDocsEntry[] = (
|
|
38
|
-
(await getCollection('docs', ({ data }) => {
|
|
39
|
-
// In production, filter out drafts.
|
|
40
|
-
return import.meta.env.MODE !== 'production' || data.draft === false;
|
|
41
|
-
})) ?? []
|
|
42
|
-
).map(normalizeCollectionEntry);
|
|
43
|
-
|
|
44
|
-
function getRoutes(): Route[] {
|
|
45
|
-
const routes: Route[] = docs.map((entry) => ({
|
|
46
|
-
entry,
|
|
47
|
-
id: entry.id,
|
|
48
|
-
entryMeta: slugToLocaleData(entry.id),
|
|
49
|
-
...slugToLocaleData(entry.id),
|
|
50
|
-
}));
|
|
51
|
-
|
|
52
|
-
// In multilingual sites, add required fallback routes.
|
|
53
|
-
if (config.isMultilingual) {
|
|
54
|
-
/** Entries in the docs content collection for the default locale. */
|
|
55
|
-
const defaultLocaleDocs = getLocaleDocs(
|
|
56
|
-
config.defaultLocale?.locale === 'root' ? undefined : config.defaultLocale?.locale
|
|
57
|
-
);
|
|
58
|
-
for (const key in config.locales) {
|
|
59
|
-
if (key === config.defaultLocale.locale) continue;
|
|
60
|
-
const localeConfig = config.locales[key];
|
|
61
|
-
if (!localeConfig) continue;
|
|
62
|
-
const locale = key === 'root' ? undefined : key;
|
|
63
|
-
const localeDocs = getLocaleDocs(locale);
|
|
64
|
-
for (const fallback of defaultLocaleDocs) {
|
|
65
|
-
const id = localizedSlug(fallback.id, locale);
|
|
66
|
-
const doesNotNeedFallback = localeDocs.some((doc) => doc.id === id);
|
|
67
|
-
if (doesNotNeedFallback) continue;
|
|
68
|
-
routes.push({
|
|
69
|
-
entry: fallback,
|
|
70
|
-
id,
|
|
71
|
-
isFallback: true,
|
|
72
|
-
lang: localeConfig.lang || BuiltInDefaultLocale.lang,
|
|
73
|
-
locale,
|
|
74
|
-
dir: localeConfig.dir,
|
|
75
|
-
entryMeta: slugToLocaleData(fallback.id),
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return routes;
|
|
82
|
-
}
|
|
83
|
-
export const routes = getRoutes();
|
|
84
|
-
|
|
85
|
-
function getParamRouteMapping(): ReadonlyMap<string | undefined, Route> {
|
|
86
|
-
const map = new Map<string | undefined, Route>();
|
|
87
|
-
for (const route of routes) {
|
|
88
|
-
map.set(slugToParam(route.id), route);
|
|
89
|
-
}
|
|
90
|
-
return map;
|
|
91
|
-
}
|
|
92
|
-
const routesBySlugParam = getParamRouteMapping();
|
|
93
|
-
|
|
94
|
-
export function getRouteBySlugParam(slugParam: string | undefined): Route | undefined {
|
|
95
|
-
return routesBySlugParam.get(slugParam?.replace(/\/$/, '') || undefined);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function getPaths(): Path[] {
|
|
99
|
-
return routes.map((route) => ({
|
|
100
|
-
params: { slug: slugToParam(route.id) },
|
|
101
|
-
props: route,
|
|
102
|
-
}));
|
|
103
|
-
}
|
|
104
|
-
export const paths = getPaths();
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Get all routes for a specific locale.
|
|
108
|
-
* A locale of `undefined` is treated as the “root” locale, if configured.
|
|
109
|
-
*/
|
|
110
|
-
export function getLocaleRoutes(locale: string | undefined): Route[] {
|
|
111
|
-
return filterByLocale(routes, locale);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Get all entries in the docs content collection for a specific locale.
|
|
116
|
-
* A locale of `undefined` is treated as the “root” locale, if configured.
|
|
117
|
-
*/
|
|
118
|
-
function getLocaleDocs(locale: string | undefined): StarlightDocsEntry[] {
|
|
119
|
-
return filterByLocale(docs, locale);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/** Filter an array to find items whose slug matches the passed locale. */
|
|
123
|
-
function filterByLocale<T extends { id: string }>(items: T[], locale: string | undefined): T[] {
|
|
124
|
-
if (config.locales) {
|
|
125
|
-
if (locale && locale in config.locales) {
|
|
126
|
-
return items.filter((i) => i.id === locale || i.id.startsWith(locale + '/'));
|
|
127
|
-
} else if (config.locales.root) {
|
|
128
|
-
const langKeys = Object.keys(config.locales).filter((k) => k !== 'root');
|
|
129
|
-
const isLangIndex = new RegExp(`^(${langKeys.join('|')})$`);
|
|
130
|
-
const isLangDir = new RegExp(`^(${langKeys.join('|')})/`);
|
|
131
|
-
return items.filter((i) => !isLangIndex.test(i.id) && !isLangDir.test(i.id));
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return items;
|
|
135
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import type { APIContext } from 'astro';
|
|
2
|
-
import { klona } from 'klona/lite';
|
|
3
|
-
import { routeMiddleware } from 'virtual:starlight/route-middleware';
|
|
4
|
-
import type { StarlightRouteData } from './types';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Adds a deep clone of the passed `routeData` object to locals and then runs middleware.
|
|
8
|
-
* @param context Astro context object
|
|
9
|
-
* @param routeData Initial route data object to attach.
|
|
10
|
-
*/
|
|
11
|
-
export async function attachRouteDataAndRunMiddleware(
|
|
12
|
-
context: APIContext,
|
|
13
|
-
routeData: StarlightRouteData
|
|
14
|
-
) {
|
|
15
|
-
context.locals.starlightRoute = klona(routeData);
|
|
16
|
-
const runner = new MiddlewareRunner(context, routeMiddleware);
|
|
17
|
-
await runner.run();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
type MiddlewareHandler<T> = (context: T, next: () => Promise<void>) => void | Promise<void>;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* A middleware function wrapper that only allows a single execution of the wrapped function.
|
|
24
|
-
* Subsequent calls to `run()` are no-ops.
|
|
25
|
-
*/
|
|
26
|
-
class MiddlewareRunnerStep<T> {
|
|
27
|
-
#callback: MiddlewareHandler<T> | null;
|
|
28
|
-
constructor(callback: MiddlewareHandler<T>) {
|
|
29
|
-
this.#callback = callback;
|
|
30
|
-
}
|
|
31
|
-
async run(context: T, next: () => Promise<void>): Promise<void> {
|
|
32
|
-
if (this.#callback) {
|
|
33
|
-
await this.#callback(context, next);
|
|
34
|
-
this.#callback = null;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Class that runs a stack of middleware handlers with an initial context object.
|
|
41
|
-
* Middleware functions can mutate properties of the `context` object, but cannot replace it.
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* const context = { value: 10 };
|
|
45
|
-
* const timesTwo = async (ctx, next) => {
|
|
46
|
-
* await next();
|
|
47
|
-
* ctx.value *= 2;
|
|
48
|
-
* };
|
|
49
|
-
* const addFive = async (ctx) => {
|
|
50
|
-
* ctx.value += 5;
|
|
51
|
-
* }
|
|
52
|
-
* const runner = new MiddlewareRunner(context, [timesTwo, addFive]);
|
|
53
|
-
* runner.run();
|
|
54
|
-
* console.log(context); // { value: 30 }
|
|
55
|
-
*/
|
|
56
|
-
class MiddlewareRunner<T> {
|
|
57
|
-
#context: T;
|
|
58
|
-
#steps: Array<MiddlewareRunnerStep<T>>;
|
|
59
|
-
|
|
60
|
-
constructor(
|
|
61
|
-
/** Context object passed as the first argument to each middleware function. */
|
|
62
|
-
context: T,
|
|
63
|
-
/** Array of middleware functions to run in sequence. */
|
|
64
|
-
stack: Array<MiddlewareHandler<T>> = []
|
|
65
|
-
) {
|
|
66
|
-
this.#context = context;
|
|
67
|
-
this.#steps = stack.map((callback) => new MiddlewareRunnerStep(callback));
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async #stepThrough(steps: Array<MiddlewareRunnerStep<T>>) {
|
|
71
|
-
let currentStep: MiddlewareRunnerStep<T>;
|
|
72
|
-
while (steps.length > 0) {
|
|
73
|
-
[currentStep, ...steps] = steps as [MiddlewareRunnerStep<T>, ...MiddlewareRunnerStep<T>[]];
|
|
74
|
-
await currentStep.run(this.#context, async () => this.#stepThrough(steps));
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
async run() {
|
|
79
|
-
await this.#stepThrough(this.#steps);
|
|
80
|
-
}
|
|
81
|
-
}
|
package/utils/routing/types.ts
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import type { MarkdownHeading } from 'astro';
|
|
2
|
-
import type { CollectionEntry, RenderResult } from 'astro:content';
|
|
3
|
-
import type { TocItem } from '../generateToC';
|
|
4
|
-
import type { LinkHTMLAttributes } from '../../schemas/sidebar';
|
|
5
|
-
import type { Badge } from '../../schemas/badge';
|
|
6
|
-
import type { HeadConfig } from '../../schemas/head';
|
|
7
|
-
|
|
8
|
-
export interface LocaleData {
|
|
9
|
-
/** Writing direction. */
|
|
10
|
-
dir: 'ltr' | 'rtl';
|
|
11
|
-
/** BCP-47 language tag. */
|
|
12
|
-
lang: string;
|
|
13
|
-
/** The base path at which a language is served. `undefined` for root locale slugs. */
|
|
14
|
-
locale: string | undefined;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface SidebarAutogenerateRouteData {
|
|
18
|
-
directory: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface SidebarManualLink {
|
|
22
|
-
type: 'link';
|
|
23
|
-
label: string;
|
|
24
|
-
href: string;
|
|
25
|
-
isCurrent: boolean;
|
|
26
|
-
badge: Badge | undefined;
|
|
27
|
-
attrs: LinkHTMLAttributes;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface SidebarAutoLink extends SidebarManualLink {
|
|
31
|
-
autogenerate: SidebarAutogenerateRouteData;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export interface SidebarManualGroup {
|
|
35
|
-
type: 'group';
|
|
36
|
-
label: string;
|
|
37
|
-
entries: (SidebarLink | SidebarGroup)[];
|
|
38
|
-
collapsed: boolean;
|
|
39
|
-
badge: Badge | undefined;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export interface SidebarAutoGroup extends SidebarManualGroup {
|
|
43
|
-
autogenerate: SidebarAutogenerateRouteData;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export type SidebarLink = SidebarManualLink | SidebarAutoLink;
|
|
47
|
-
export type SidebarGroup = SidebarManualGroup | SidebarAutoGroup;
|
|
48
|
-
export type SidebarEntry = SidebarLink | SidebarGroup;
|
|
49
|
-
|
|
50
|
-
export interface PaginationLinks {
|
|
51
|
-
/** Link to previous page in the sidebar. */
|
|
52
|
-
prev: SidebarLink | undefined;
|
|
53
|
-
/** Link to next page in the sidebar. */
|
|
54
|
-
next: SidebarLink | undefined;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// A type representing a docs collection entry returned by the `docsLoader()`.
|
|
58
|
-
export type StarlightDocsCollectionEntry = CollectionEntry<'docs'>;
|
|
59
|
-
|
|
60
|
-
// A normalized type representing a docs collection entry used throughout Starlight.
|
|
61
|
-
export type StarlightDocsEntry = StarlightDocsCollectionEntry & {
|
|
62
|
-
// At the moment, Starlight only supports file-based loaders which always include a `filePath`.
|
|
63
|
-
filePath: string;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export interface Route extends LocaleData {
|
|
67
|
-
/** Content collection entry for the current page. Includes frontmatter at `data`. */
|
|
68
|
-
entry: StarlightDocsEntry;
|
|
69
|
-
/** Locale metadata for the page content. Can be different from top-level locale values when a page is using fallback content. */
|
|
70
|
-
entryMeta: LocaleData;
|
|
71
|
-
/** The slug. */
|
|
72
|
-
id: string;
|
|
73
|
-
/** Whether this page is untranslated in the current language and using fallback content from the default locale. */
|
|
74
|
-
isFallback?: boolean;
|
|
75
|
-
[key: string]: unknown;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export interface StarlightRouteData extends Route {
|
|
79
|
-
/** Title of the site. */
|
|
80
|
-
siteTitle: string;
|
|
81
|
-
/** URL or path used as the link when clicking on the site title. */
|
|
82
|
-
siteTitleHref: string;
|
|
83
|
-
/** Array of Markdown headings extracted from the current page. */
|
|
84
|
-
headings: MarkdownHeading[];
|
|
85
|
-
/** Site navigation sidebar entries for this page. */
|
|
86
|
-
sidebar: SidebarEntry[];
|
|
87
|
-
/** Whether or not the sidebar should be displayed on this page. */
|
|
88
|
-
hasSidebar: boolean;
|
|
89
|
-
/** Links to the previous and next page in the sidebar if enabled. */
|
|
90
|
-
pagination: PaginationLinks;
|
|
91
|
-
/** Table of contents for this page if enabled. */
|
|
92
|
-
toc: { minHeadingLevel: number; maxHeadingLevel: number; items: TocItem[] } | undefined;
|
|
93
|
-
/** JS Date object representing when this page was last updated if enabled. */
|
|
94
|
-
lastUpdated: Date | undefined;
|
|
95
|
-
/** URL object for the address where this page can be edited if enabled. */
|
|
96
|
-
editUrl: URL | undefined;
|
|
97
|
-
/** An Astro component to render the current page’s content if this route is a Markdown page. */
|
|
98
|
-
Content?: RenderResult['Content'];
|
|
99
|
-
/** Array of tags to include in the `<head>` of the current page. */
|
|
100
|
-
head: HeadConfig;
|
|
101
|
-
}
|
package/utils/slugs.ts
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import config from 'virtual:starlight/user-config';
|
|
2
|
-
import { slugToLocale as getLocaleFromSlug } from '../integrations/shared/slugToLocale';
|
|
3
|
-
import { BuiltInDefaultLocale } from './i18n';
|
|
4
|
-
import { stripTrailingSlash } from './path';
|
|
5
|
-
import type { LocaleData } from './routing/types';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Get the “locale” of a slug. This is the base path at which a language is served.
|
|
9
|
-
* For example, if French docs are in `src/content/docs/french/`, the locale is `french`.
|
|
10
|
-
* Root locale slugs will return `undefined`.
|
|
11
|
-
* @param slug A collection entry slug
|
|
12
|
-
*/
|
|
13
|
-
function slugToLocale(slug: string): string | undefined {
|
|
14
|
-
return getLocaleFromSlug(slug, config);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/** Get locale information for a given slug. */
|
|
18
|
-
export function slugToLocaleData(slug: string): LocaleData {
|
|
19
|
-
const locale = slugToLocale(slug);
|
|
20
|
-
return { dir: localeToDir(locale), lang: localeToLang(locale), locale };
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Get the BCP-47 language tag for the given locale.
|
|
25
|
-
* @param locale Locale string or `undefined` for the root locale.
|
|
26
|
-
*/
|
|
27
|
-
export function localeToLang(locale: string | undefined): string {
|
|
28
|
-
const lang = locale ? config.locales?.[locale]?.lang : config.locales?.root?.lang;
|
|
29
|
-
const defaultLang = config.defaultLocale?.lang || config.defaultLocale?.locale;
|
|
30
|
-
return lang || defaultLang || BuiltInDefaultLocale.lang;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Get the configured writing direction for the given locale.
|
|
35
|
-
* @param locale Locale string or `undefined` for the root locale.
|
|
36
|
-
*/
|
|
37
|
-
function localeToDir(locale: string | undefined): 'ltr' | 'rtl' {
|
|
38
|
-
const dir = locale ? config.locales?.[locale]?.dir : config.locales?.root?.dir;
|
|
39
|
-
return dir || config.defaultLocale.dir;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Convert a content collection slug to a param as expected by Astro’s router.
|
|
44
|
-
* This utility handles stripping `index` from file names and matches
|
|
45
|
-
* [Astro’s param sanitization logic](https://github.com/withastro/astro/blob/687d25365a41ff8a9e6da155d3527f841abb70dd/packages/astro/src/core/routing/manifest/generator.ts#L4-L18)
|
|
46
|
-
* by normalizing strings to their canonical representations.
|
|
47
|
-
* @param slug Content collection slug
|
|
48
|
-
* @returns Param compatible with Astro’s router
|
|
49
|
-
*/
|
|
50
|
-
export function slugToParam(slug: string): string | undefined {
|
|
51
|
-
return slug === 'index' || slug === '' || slug === '/'
|
|
52
|
-
? undefined
|
|
53
|
-
: (slug.endsWith('/index') ? slug.slice(0, -6) : slug).normalize();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function slugToPathname(slug: string): string {
|
|
57
|
-
const param = slugToParam(slug);
|
|
58
|
-
return param ? '/' + param + '/' : '/';
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Convert a slug to a different locale.
|
|
63
|
-
* For example, passing a slug of `en/home` and a locale of `fr` results in `fr/home`.
|
|
64
|
-
* An undefined locale is treated as the root locale, resulting in `home`
|
|
65
|
-
* @param slug A collection entry slug
|
|
66
|
-
* @param locale The target locale
|
|
67
|
-
* @example
|
|
68
|
-
* localizedSlug('en/home', 'fr') // => 'fr/home'
|
|
69
|
-
* localizedSlug('en/home', undefined) // => 'home'
|
|
70
|
-
*/
|
|
71
|
-
export function localizedSlug(slug: string, locale: string | undefined): string {
|
|
72
|
-
const slugLocale = slugToLocale(slug);
|
|
73
|
-
if (slugLocale === locale) return slug;
|
|
74
|
-
locale = locale || '';
|
|
75
|
-
if (slugLocale === slug) return locale;
|
|
76
|
-
if (slugLocale) {
|
|
77
|
-
return stripTrailingSlash(slug.replace(slugLocale + '/', locale ? locale + '/' : ''));
|
|
78
|
-
}
|
|
79
|
-
return slug ? locale + '/' + slug : locale;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Convert a file path relative to the collection root to a different locale.
|
|
84
|
-
* For example, passing a file path of `en/home.md` and a locale of `fr` results in `fr/home.md`.
|
|
85
|
-
* An undefined locale is treated as the root locale, resulting in `home.md`.
|
|
86
|
-
* @param filePath A collection entry file path relative to the collection root
|
|
87
|
-
* @param locale The target locale
|
|
88
|
-
* @example
|
|
89
|
-
* localizedFilePath('en/home.md', 'fr') // => 'fr/home.md'
|
|
90
|
-
* localizedFilePath('en/home.md', undefined) // => 'home.md'
|
|
91
|
-
*/
|
|
92
|
-
export function localizedFilePath(filePath: string, locale: string | undefined): string {
|
|
93
|
-
const filePathLocale = slugToLocale(filePath);
|
|
94
|
-
if (filePathLocale) {
|
|
95
|
-
return filePath.replace(filePathLocale + '/', locale ? locale + '/' : '');
|
|
96
|
-
} else if (locale) {
|
|
97
|
-
return locale + '/' + filePath;
|
|
98
|
-
} else {
|
|
99
|
-
return filePath;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/** Extract the slug from a URL. */
|
|
104
|
-
export function urlToSlug(url: URL): string {
|
|
105
|
-
let pathname = url.pathname;
|
|
106
|
-
const base = stripTrailingSlash(import.meta.env.BASE_URL);
|
|
107
|
-
if (pathname.startsWith(base)) pathname = pathname.replace(base, '');
|
|
108
|
-
const segments = pathname.split('/');
|
|
109
|
-
const htmlExt = '.html';
|
|
110
|
-
if (segments.at(-1) === 'index.html') {
|
|
111
|
-
// Remove trailing `index.html`.
|
|
112
|
-
segments.pop();
|
|
113
|
-
} else if (segments.at(-1)?.endsWith(htmlExt)) {
|
|
114
|
-
// Remove trailing `.html`.
|
|
115
|
-
const last = segments.pop();
|
|
116
|
-
if (last) segments.push(last.slice(0, -1 * htmlExt.length));
|
|
117
|
-
}
|
|
118
|
-
return segments.filter(Boolean).join('/');
|
|
119
|
-
}
|
package/utils/starlight-page.ts
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import { z } from 'astro/zod';
|
|
2
|
-
import { type ContentConfig, type ImageFunction, type SchemaContext } from 'astro:content';
|
|
3
|
-
import project from 'virtual:starlight/project-context';
|
|
4
|
-
import config from 'virtual:starlight/user-config';
|
|
5
|
-
import { getCollectionPathFromRoot } from './collection';
|
|
6
|
-
import { parseWithFriendlyErrors, parseAsyncWithFriendlyErrors } from './error-map';
|
|
7
|
-
import { stripLeadingAndTrailingSlashes } from './path';
|
|
8
|
-
import {
|
|
9
|
-
getSiteTitle,
|
|
10
|
-
getSiteTitleHref,
|
|
11
|
-
getToC,
|
|
12
|
-
type PageProps,
|
|
13
|
-
type RouteDataContext,
|
|
14
|
-
} from './routing/data';
|
|
15
|
-
import type { StarlightDocsEntry, StarlightRouteData } from './routing/types';
|
|
16
|
-
import { slugToLocaleData, urlToSlug } from './slugs';
|
|
17
|
-
import { getPrevNextLinks, getSidebar, getSidebarFromConfig } from './navigation';
|
|
18
|
-
import { docsSchema } from '../schema';
|
|
19
|
-
import type { Prettify, RemoveIndexSignature } from './types';
|
|
20
|
-
import { SidebarItemSchema } from '../schemas/sidebar';
|
|
21
|
-
import type { StarlightConfig, StarlightUserConfig } from './user-config';
|
|
22
|
-
import { getHead } from './head';
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* The frontmatter schema for Starlight pages derived from the default schema for Starlight’s
|
|
26
|
-
* `docs` content collection.
|
|
27
|
-
* The frontmatter schema for Starlight pages cannot include some properties which will be omitted
|
|
28
|
-
* and some others needs to be refined to a stricter type.
|
|
29
|
-
*/
|
|
30
|
-
const StarlightPageFrontmatterSchema = async (context: SchemaContext) => {
|
|
31
|
-
const userDocsSchema = await getUserDocsSchema();
|
|
32
|
-
const schema = typeof userDocsSchema === 'function' ? userDocsSchema(context) : userDocsSchema;
|
|
33
|
-
|
|
34
|
-
return schema.transform((frontmatter) => {
|
|
35
|
-
/**
|
|
36
|
-
* Starlight pages can only be edited if an edit URL is explicitly provided.
|
|
37
|
-
* The `sidebar` frontmatter prop only works for pages in an autogenerated links group.
|
|
38
|
-
* Starlight pages edit links cannot be autogenerated.
|
|
39
|
-
*
|
|
40
|
-
* These changes to the schema are done using a transformer and not using the usual `omit`
|
|
41
|
-
* method because when the frontmatter schema is extended by the user, an intersection between
|
|
42
|
-
* the default schema and the user schema is created using the `and` method. Intersections in
|
|
43
|
-
* Zod returns a `ZodIntersection` object which does not have some methods like `omit` or
|
|
44
|
-
* `pick`.
|
|
45
|
-
*
|
|
46
|
-
* This transformer only sets the `editUrl` default value and removes the `sidebar` property
|
|
47
|
-
* from the validated output but does not apply any changes to the input schema type itself so
|
|
48
|
-
* this needs to be done manually.
|
|
49
|
-
*
|
|
50
|
-
* @see StarlightPageFrontmatter
|
|
51
|
-
* @see https://github.com/colinhacks/zod#intersections
|
|
52
|
-
*/
|
|
53
|
-
const { editUrl, sidebar, ...others } = frontmatter;
|
|
54
|
-
const pageEditUrl = editUrl === undefined || editUrl === true ? false : editUrl;
|
|
55
|
-
return { ...others, editUrl: pageEditUrl };
|
|
56
|
-
});
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Type of Starlight pages frontmatter schema.
|
|
61
|
-
* We manually refines the `editUrl` type and omit the `sidebar` property as it's not possible to
|
|
62
|
-
* do that on the schema itself using Zod but the proper validation is still using a transformer.
|
|
63
|
-
* @see StarlightPageFrontmatterSchema
|
|
64
|
-
*/
|
|
65
|
-
type StarlightPageFrontmatter = Omit<
|
|
66
|
-
z.input<Awaited<ReturnType<typeof StarlightPageFrontmatterSchema>>>,
|
|
67
|
-
'editUrl' | 'sidebar'
|
|
68
|
-
> & { editUrl?: string | false };
|
|
69
|
-
|
|
70
|
-
/** Parse sidebar prop to ensure it's valid. */
|
|
71
|
-
const validateSidebarProp = (
|
|
72
|
-
sidebarProp: StarlightUserConfig['sidebar']
|
|
73
|
-
): StarlightConfig['sidebar'] => {
|
|
74
|
-
return parseWithFriendlyErrors(
|
|
75
|
-
SidebarItemSchema.array().optional(),
|
|
76
|
-
sidebarProp,
|
|
77
|
-
'Invalid sidebar prop passed to the `<StarlightPage/>` component.'
|
|
78
|
-
);
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* The props accepted by the `<StarlightPage/>` component.
|
|
83
|
-
*/
|
|
84
|
-
export type StarlightPageProps = Prettify<
|
|
85
|
-
// Remove the index signature from `Route`, omit undesired properties and make the rest optional.
|
|
86
|
-
Partial<Omit<RemoveIndexSignature<PageProps>, 'entry' | 'entryMeta' | 'id' | 'locale'>> &
|
|
87
|
-
// Add the sidebar definitions for a Starlight page.
|
|
88
|
-
Partial<Pick<StarlightRouteData, 'hasSidebar'>> & {
|
|
89
|
-
sidebar?: StarlightUserConfig['sidebar'];
|
|
90
|
-
// And finally add the Starlight page frontmatter properties in a `frontmatter` property.
|
|
91
|
-
frontmatter: StarlightPageFrontmatter;
|
|
92
|
-
}
|
|
93
|
-
>;
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* A docs entry used for Starlight pages meant to be rendered by plugins and which is safe to cast
|
|
97
|
-
* to a `StarlightDocsEntry`.
|
|
98
|
-
* A Starlight page docs entry cannot be rendered like a content collection entry.
|
|
99
|
-
*/
|
|
100
|
-
type StarlightPageDocsEntry = Omit<StarlightDocsEntry, 'render'>;
|
|
101
|
-
|
|
102
|
-
export async function generateStarlightPageRouteData({
|
|
103
|
-
props,
|
|
104
|
-
context,
|
|
105
|
-
}: {
|
|
106
|
-
props: StarlightPageProps;
|
|
107
|
-
context: RouteDataContext;
|
|
108
|
-
}): Promise<StarlightRouteData> {
|
|
109
|
-
const { frontmatter, ...routeProps } = props;
|
|
110
|
-
const { url } = context;
|
|
111
|
-
const id = urlToSlug(url);
|
|
112
|
-
const pageFrontmatter = await getStarlightPageFrontmatter(frontmatter);
|
|
113
|
-
const localeData = slugToLocaleData(id);
|
|
114
|
-
const sidebar = props.sidebar
|
|
115
|
-
? getSidebarFromConfig(validateSidebarProp(props.sidebar), url.pathname, localeData.locale)
|
|
116
|
-
: getSidebar(url.pathname, localeData.locale);
|
|
117
|
-
const headings = props.headings ?? [];
|
|
118
|
-
const pageDocsEntry: StarlightPageDocsEntry = {
|
|
119
|
-
id,
|
|
120
|
-
body: '',
|
|
121
|
-
collection: 'docs',
|
|
122
|
-
filePath: `${getCollectionPathFromRoot('docs', project)}/${stripLeadingAndTrailingSlashes(id)}.md`,
|
|
123
|
-
data: {
|
|
124
|
-
...pageFrontmatter,
|
|
125
|
-
sidebar: {
|
|
126
|
-
attrs: {},
|
|
127
|
-
hidden: false,
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
};
|
|
131
|
-
const entry = pageDocsEntry as StarlightDocsEntry;
|
|
132
|
-
const entryMeta: StarlightRouteData['entryMeta'] = {
|
|
133
|
-
dir: props.dir ?? localeData.dir,
|
|
134
|
-
lang: props.lang ?? localeData.lang,
|
|
135
|
-
locale: localeData.locale,
|
|
136
|
-
};
|
|
137
|
-
const editUrl = pageFrontmatter.editUrl ? new URL(pageFrontmatter.editUrl) : undefined;
|
|
138
|
-
const lastUpdated =
|
|
139
|
-
pageFrontmatter.lastUpdated instanceof Date ? pageFrontmatter.lastUpdated : undefined;
|
|
140
|
-
const pageProps: PageProps = {
|
|
141
|
-
...routeProps,
|
|
142
|
-
...localeData,
|
|
143
|
-
entry,
|
|
144
|
-
entryMeta,
|
|
145
|
-
headings,
|
|
146
|
-
id,
|
|
147
|
-
locale: localeData.locale,
|
|
148
|
-
};
|
|
149
|
-
const siteTitle = getSiteTitle(localeData.lang);
|
|
150
|
-
const routeData: StarlightRouteData = {
|
|
151
|
-
...routeProps,
|
|
152
|
-
...localeData,
|
|
153
|
-
id,
|
|
154
|
-
editUrl,
|
|
155
|
-
entry,
|
|
156
|
-
entryMeta,
|
|
157
|
-
hasSidebar: props.hasSidebar ?? entry.data.template !== 'splash',
|
|
158
|
-
head: getHead(pageProps, context, siteTitle),
|
|
159
|
-
headings,
|
|
160
|
-
lastUpdated,
|
|
161
|
-
pagination: getPrevNextLinks(sidebar, config.pagination, entry.data),
|
|
162
|
-
sidebar,
|
|
163
|
-
siteTitle,
|
|
164
|
-
siteTitleHref: getSiteTitleHref(localeData.locale),
|
|
165
|
-
toc: getToC(pageProps),
|
|
166
|
-
};
|
|
167
|
-
return routeData;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/** Validates the Starlight page frontmatter properties from the props received by a Starlight page. */
|
|
171
|
-
async function getStarlightPageFrontmatter(frontmatter: StarlightPageFrontmatter) {
|
|
172
|
-
const schema = await StarlightPageFrontmatterSchema({
|
|
173
|
-
image: (() =>
|
|
174
|
-
// Mock validator for ImageMetadata.
|
|
175
|
-
// https://github.com/withastro/astro/blob/cf993bc263b58502096f00d383266cd179f331af/packages/astro/src/assets/types.ts#L32
|
|
176
|
-
// It uses a custom validation approach because imported SVGs have a type of `function` as
|
|
177
|
-
// well as containing the metadata properties and this ensures we handle those correctly.
|
|
178
|
-
z.custom<ReturnType<ImageFunction>>(
|
|
179
|
-
(value) =>
|
|
180
|
-
value &&
|
|
181
|
-
(typeof value === 'function' || typeof value === 'object') &&
|
|
182
|
-
'src' in value &&
|
|
183
|
-
'width' in value &&
|
|
184
|
-
'height' in value &&
|
|
185
|
-
'format' in value,
|
|
186
|
-
'Invalid image passed to `<StarlightPage>` component. Expected imported `ImageMetadata` object.'
|
|
187
|
-
)) as unknown as ImageFunction,
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
// Starting with Astro 4.14.0, a frontmatter schema that contains collection references will
|
|
191
|
-
// contain an async transform.
|
|
192
|
-
return parseAsyncWithFriendlyErrors(
|
|
193
|
-
schema,
|
|
194
|
-
frontmatter,
|
|
195
|
-
'Invalid frontmatter props passed to the `<StarlightPage/>` component.'
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/** Returns the user docs schema and falls back to the default schema if needed. */
|
|
200
|
-
async function getUserDocsSchema(): Promise<
|
|
201
|
-
NonNullable<ContentConfig['collections']['docs']['schema']>
|
|
202
|
-
> {
|
|
203
|
-
const userCollections = (await import('virtual:starlight/collection-config')).collections;
|
|
204
|
-
return userCollections?.docs?.schema ?? docsSchema();
|
|
205
|
-
}
|