@astrojs/starlight 0.41.11 → 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/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 +60 -34
- package/CHANGELOG.md +0 -3051
- 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 -574
- 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 -139
- 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}/anchor-links.css +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
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
import { AstroError } from 'astro/errors';
|
|
2
|
-
import type { Element, ElementContent, Text } from 'hast';
|
|
3
|
-
import { type Child, h, s } from 'hastscript';
|
|
4
|
-
import { select } from 'hast-util-select';
|
|
5
|
-
import { fromHtml } from 'hast-util-from-html';
|
|
6
|
-
import { toString } from 'hast-util-to-string';
|
|
7
|
-
import { rehype } from 'rehype';
|
|
8
|
-
import { CONTINUE, SKIP, visit } from 'unist-util-visit';
|
|
9
|
-
import { Icons, type StarlightIcon } from '../components-internals/Icons';
|
|
10
|
-
import { definitions } from './file-tree-icons';
|
|
11
|
-
|
|
12
|
-
declare module 'vfile' {
|
|
13
|
-
interface DataMap {
|
|
14
|
-
directoryLabel: string;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const folderIcon = makeSVGIcon(Icons['seti:folder']);
|
|
19
|
-
const defaultFileIcon = makeSVGIcon(Icons['seti:default']);
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Process the HTML for a file tree to create the necessary markup for each file and directory
|
|
23
|
-
* including icons.
|
|
24
|
-
* @param html Inner HTML passed to the `<FileTree>` component.
|
|
25
|
-
* @param directoryLabel The localized label for a directory.
|
|
26
|
-
* @returns The processed HTML for the file tree.
|
|
27
|
-
*/
|
|
28
|
-
export function processFileTree(html: string, directoryLabel: string) {
|
|
29
|
-
const file = fileTreeProcessor.processSync({ data: { directoryLabel }, value: html });
|
|
30
|
-
|
|
31
|
-
return file.toString();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/** Rehype processor to extract file tree data and turn each entry into its associated markup. */
|
|
35
|
-
const fileTreeProcessor = rehype()
|
|
36
|
-
.data('settings', { fragment: true })
|
|
37
|
-
.use(function fileTree() {
|
|
38
|
-
return (tree: Element, file) => {
|
|
39
|
-
const { directoryLabel } = file.data;
|
|
40
|
-
|
|
41
|
-
validateFileTree(tree);
|
|
42
|
-
|
|
43
|
-
visit(tree, 'element', (node) => {
|
|
44
|
-
// Strip nodes that only contain newlines.
|
|
45
|
-
node.children = node.children.filter(
|
|
46
|
-
(child) => child.type === 'comment' || child.type !== 'text' || !/^\n+$/.test(child.value)
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
// Skip over non-list items.
|
|
50
|
-
if (node.tagName !== 'li') return CONTINUE;
|
|
51
|
-
|
|
52
|
-
const [firstChild, ...otherChildren] = node.children;
|
|
53
|
-
|
|
54
|
-
// Keep track of comments associated with the current file or directory.
|
|
55
|
-
const comment: Child[] = [];
|
|
56
|
-
|
|
57
|
-
// Extract text comment that follows the file name, e.g. `README.md This is a comment`
|
|
58
|
-
if (firstChild?.type === 'text') {
|
|
59
|
-
const [filename, ...fragments] = firstChild.value.split(' ');
|
|
60
|
-
firstChild.value = filename || '';
|
|
61
|
-
const textComment = fragments.join(' ').trim();
|
|
62
|
-
if (textComment.length > 0) {
|
|
63
|
-
comment.push(fragments.join(' '));
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Comments may not always be entirely part of the first child text node,
|
|
68
|
-
// e.g. `README.md This is an __important__ comment` where the `__important__` and `comment`
|
|
69
|
-
// nodes would also be children of the list item node.
|
|
70
|
-
const subTreeIndex = otherChildren.findIndex(
|
|
71
|
-
(child) => child.type === 'element' && child.tagName === 'ul'
|
|
72
|
-
);
|
|
73
|
-
const commentNodes =
|
|
74
|
-
subTreeIndex > -1 ? otherChildren.slice(0, subTreeIndex) : [...otherChildren];
|
|
75
|
-
otherChildren.splice(0, subTreeIndex > -1 ? subTreeIndex : otherChildren.length);
|
|
76
|
-
comment.push(...commentNodes);
|
|
77
|
-
|
|
78
|
-
const firstChildTextContent = firstChild ? toString(firstChild) : '';
|
|
79
|
-
|
|
80
|
-
// Decide a node is a directory if it ends in a `/` or contains another list.
|
|
81
|
-
const isDirectory =
|
|
82
|
-
/\/\s*$/.test(firstChildTextContent) ||
|
|
83
|
-
otherChildren.some((child) => child.type === 'element' && child.tagName === 'ul');
|
|
84
|
-
// A placeholder is a node that only contains 3 dots or an ellipsis.
|
|
85
|
-
const isPlaceholder = /^\s*(\.{3}|…)\s*$/.test(firstChildTextContent);
|
|
86
|
-
// A node is highlighted if its first child is bold text, e.g. `**README.md**`.
|
|
87
|
-
const isHighlighted = firstChild?.type === 'element' && firstChild.tagName === 'strong';
|
|
88
|
-
|
|
89
|
-
// Create an icon for the file or directory (placeholder do not have icons).
|
|
90
|
-
const icon = h('span', isDirectory ? folderIcon : getFileIcon(firstChildTextContent));
|
|
91
|
-
if (isDirectory) {
|
|
92
|
-
// Add a screen reader only label for directories before the icon so that it is announced
|
|
93
|
-
// as such before reading the directory name.
|
|
94
|
-
icon.children.unshift(h('span', { class: 'sr-only' }, directoryLabel));
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Add classes and data attributes to the list item node.
|
|
98
|
-
node.properties.class = isDirectory ? 'directory' : 'file';
|
|
99
|
-
if (isPlaceholder) node.properties.class += ' empty';
|
|
100
|
-
|
|
101
|
-
// Create the tree entry node that contains the icon, file name and comment which will end up
|
|
102
|
-
// as the list item’s children.
|
|
103
|
-
const treeEntryChildren: Child[] = [
|
|
104
|
-
h('span', { class: isHighlighted ? 'highlight' : '' }, [
|
|
105
|
-
isPlaceholder ? null : icon,
|
|
106
|
-
firstChild,
|
|
107
|
-
]),
|
|
108
|
-
];
|
|
109
|
-
|
|
110
|
-
if (comment.length > 0) {
|
|
111
|
-
treeEntryChildren.push(makeText(' '), h('span', { class: 'comment' }, ...comment));
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const treeEntry = h('span', { class: 'tree-entry' }, ...treeEntryChildren);
|
|
115
|
-
|
|
116
|
-
if (isDirectory) {
|
|
117
|
-
const hasContents = otherChildren.length > 0;
|
|
118
|
-
|
|
119
|
-
node.children = [
|
|
120
|
-
h('details', { open: hasContents }, [
|
|
121
|
-
h('summary', treeEntry),
|
|
122
|
-
...(hasContents ? otherChildren : [h('ul', h('li', '…'))]),
|
|
123
|
-
]),
|
|
124
|
-
];
|
|
125
|
-
|
|
126
|
-
// Continue down the tree.
|
|
127
|
-
return CONTINUE;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
node.children = [treeEntry, ...otherChildren];
|
|
131
|
-
|
|
132
|
-
// Files can’t contain further files or directories, so skip iterating children.
|
|
133
|
-
return SKIP;
|
|
134
|
-
});
|
|
135
|
-
};
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
/** Make a text node with the pass string as its contents. */
|
|
139
|
-
function makeText(value = ''): Text {
|
|
140
|
-
return { type: 'text', value };
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/** Make a node containing an SVG icon from the passed HTML string. */
|
|
144
|
-
function makeSVGIcon(svgString: string) {
|
|
145
|
-
return s(
|
|
146
|
-
'svg',
|
|
147
|
-
{
|
|
148
|
-
width: 16,
|
|
149
|
-
height: 16,
|
|
150
|
-
class: 'tree-icon',
|
|
151
|
-
'aria-hidden': 'true',
|
|
152
|
-
viewBox: '0 0 24 24',
|
|
153
|
-
},
|
|
154
|
-
fromHtml(svgString, { fragment: true })
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/** Return the icon for a file based on its file name. */
|
|
159
|
-
function getFileIcon(fileName: string) {
|
|
160
|
-
const name = getFileIconName(fileName);
|
|
161
|
-
if (!name) return defaultFileIcon;
|
|
162
|
-
if (name in Icons) {
|
|
163
|
-
const path = Icons[name as StarlightIcon];
|
|
164
|
-
return makeSVGIcon(path);
|
|
165
|
-
}
|
|
166
|
-
return defaultFileIcon;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/** Return the icon name for a file based on its file name. */
|
|
170
|
-
function getFileIconName(fileName: string) {
|
|
171
|
-
let icon: string | undefined = definitions.files[fileName];
|
|
172
|
-
if (icon) return icon;
|
|
173
|
-
icon = getFileIconTypeFromExtension(fileName);
|
|
174
|
-
if (icon) return icon;
|
|
175
|
-
for (const [partial, partialIcon] of Object.entries(definitions.partials)) {
|
|
176
|
-
if (fileName.includes(partial)) return partialIcon;
|
|
177
|
-
}
|
|
178
|
-
return icon;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Get an icon from a file name based on its extension.
|
|
183
|
-
* Note that an extension in Seti is everything after a dot, so `README.md` would be `.md` and
|
|
184
|
-
* `name.with.dots` will try to look for an icon for `.with.dots` and then `.dots` if the first one
|
|
185
|
-
* is not found.
|
|
186
|
-
*/
|
|
187
|
-
function getFileIconTypeFromExtension(fileName: string) {
|
|
188
|
-
const firstDotIndex = fileName.indexOf('.');
|
|
189
|
-
if (firstDotIndex === -1) return;
|
|
190
|
-
let extension = fileName.slice(firstDotIndex);
|
|
191
|
-
while (extension !== '') {
|
|
192
|
-
const icon = definitions.extensions[extension];
|
|
193
|
-
if (icon) return icon;
|
|
194
|
-
const nextDotIndex = extension.indexOf('.', 1);
|
|
195
|
-
if (nextDotIndex === -1) return;
|
|
196
|
-
extension = extension.slice(nextDotIndex);
|
|
197
|
-
}
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/** Validate that the user provided HTML for a file tree is valid. */
|
|
202
|
-
function validateFileTree(tree: Element) {
|
|
203
|
-
const rootElements = tree.children.filter(isElementNode);
|
|
204
|
-
const [rootElement] = rootElements;
|
|
205
|
-
|
|
206
|
-
if (rootElements.length === 0) {
|
|
207
|
-
throwFileTreeValidationError(
|
|
208
|
-
'The `<FileTree>` component expects its content to be a single unordered list but found no child elements.'
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (rootElements.length !== 1) {
|
|
213
|
-
throwFileTreeValidationError(
|
|
214
|
-
`The \`<FileTree>\` component expects its content to be a single unordered list but found multiple child elements: ${rootElements
|
|
215
|
-
.map((element) => `\`<${element.tagName}>\``)
|
|
216
|
-
.join(' - ')}.`
|
|
217
|
-
);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (!rootElement || rootElement.tagName !== 'ul') {
|
|
221
|
-
throwFileTreeValidationError(
|
|
222
|
-
`The \`<FileTree>\` component expects its content to be an unordered list but found the following element: \`<${rootElement?.tagName}>\`.`
|
|
223
|
-
);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const listItemElement = select('li', rootElement);
|
|
227
|
-
|
|
228
|
-
if (!listItemElement) {
|
|
229
|
-
throwFileTreeValidationError(
|
|
230
|
-
'The `<FileTree>` component expects its content to be an unordered list with at least one list item.'
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
function isElementNode(node: ElementContent): node is Element {
|
|
236
|
-
return node.type === 'element';
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
/** Throw a validation error for a file tree linking to the documentation. */
|
|
240
|
-
function throwFileTreeValidationError(message: string): never {
|
|
241
|
-
throw new AstroError(
|
|
242
|
-
message,
|
|
243
|
-
'To learn more about the `<FileTree>` component, see https://starlight.astro.build/components/file-tree/'
|
|
244
|
-
);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
export interface Definitions {
|
|
248
|
-
files: Record<string, string>;
|
|
249
|
-
extensions: Record<string, string>;
|
|
250
|
-
partials: Record<string, string>;
|
|
251
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { AstroError } from 'astro/errors';
|
|
2
|
-
import type { Element, Root } from 'hast';
|
|
3
|
-
import { rehype } from 'rehype';
|
|
4
|
-
import rehypeFormat from 'rehype-format';
|
|
5
|
-
import type { VFile } from 'vfile';
|
|
6
|
-
|
|
7
|
-
const prettyPrintProcessor = rehype().data('settings', { fragment: true }).use(rehypeFormat);
|
|
8
|
-
const prettyPrintHtml = (html: string) =>
|
|
9
|
-
prettyPrintProcessor.processSync({ value: html }).toString();
|
|
10
|
-
|
|
11
|
-
const stepsProcessor = rehype()
|
|
12
|
-
.data('settings', { fragment: true })
|
|
13
|
-
.use(function steps() {
|
|
14
|
-
return (tree: Root, vfile: VFile) => {
|
|
15
|
-
const rootElements = tree.children.filter(
|
|
16
|
-
(item): item is Element =>
|
|
17
|
-
item.type === 'element' &&
|
|
18
|
-
// Since Astro 5.16.9, `<script>` elements from nested child elements can end up hoisted
|
|
19
|
-
// into the `<Steps>` slot due to our use of `Astro.slots.render()`. We can safely ignore
|
|
20
|
-
// these, so we filter them out here.
|
|
21
|
-
// TODO: we may be able to remove this in the future if the upstream issue is fixed.
|
|
22
|
-
// See: https://github.com/withastro/astro/issues/15627
|
|
23
|
-
item.tagName !== 'script'
|
|
24
|
-
);
|
|
25
|
-
const [rootElement] = rootElements;
|
|
26
|
-
|
|
27
|
-
if (!rootElement) {
|
|
28
|
-
throw new StepsError(
|
|
29
|
-
'The `<Steps>` component expects its content to be a single ordered list (`<ol>`) but found no child elements.'
|
|
30
|
-
);
|
|
31
|
-
} else if (rootElements.length > 1) {
|
|
32
|
-
throw new StepsError(
|
|
33
|
-
'The `<Steps>` component expects its content to be a single ordered list (`<ol>`) but found multiple child elements: ' +
|
|
34
|
-
rootElements.map((element: Element) => `\`<${element.tagName}>\``).join(', ') +
|
|
35
|
-
'.',
|
|
36
|
-
vfile.value.toString()
|
|
37
|
-
);
|
|
38
|
-
} else if (rootElement.tagName !== 'ol') {
|
|
39
|
-
throw new StepsError(
|
|
40
|
-
'The `<Steps>` component expects its content to be a single ordered list (`<ol>`) but found the following element: ' +
|
|
41
|
-
`\`<${rootElement.tagName}>\`.`,
|
|
42
|
-
vfile.value.toString()
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Ensure `role="list"` is set on the ordered list.
|
|
47
|
-
// We use `list-style: none` in the styles for this component and need to ensure the list
|
|
48
|
-
// retains its semantics in Safari, which will remove them otherwise.
|
|
49
|
-
rootElement.properties.role = 'list';
|
|
50
|
-
// Add the required CSS class name, preserving existing classes if present.
|
|
51
|
-
if (!Array.isArray(rootElement.properties.className)) {
|
|
52
|
-
rootElement.properties.className = ['sl-steps'];
|
|
53
|
-
} else {
|
|
54
|
-
rootElement.properties.className.push('sl-steps');
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Add the `start` attribute as a CSS custom property so we can use it as the starting index
|
|
58
|
-
// of the steps custom counter.
|
|
59
|
-
if (typeof rootElement.properties.start === 'number') {
|
|
60
|
-
const styles = [`--sl-steps-start: ${rootElement.properties.start - 1}`];
|
|
61
|
-
if (rootElement.properties.style) styles.push(String(rootElement.properties.style));
|
|
62
|
-
rootElement.properties.style = styles.join(';');
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Process steps children: validates the HTML and adds `role="list"` to the ordered list.
|
|
69
|
-
* @param html Inner HTML passed to the `<Steps>` component.
|
|
70
|
-
*/
|
|
71
|
-
export const processSteps = (html: string | undefined) => {
|
|
72
|
-
const file = stepsProcessor.processSync({ value: html });
|
|
73
|
-
return { html: file.toString() };
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
class StepsError extends AstroError {
|
|
77
|
-
constructor(message: string, html?: string) {
|
|
78
|
-
let hint =
|
|
79
|
-
'To learn more about the `<Steps>` component, see https://starlight.astro.build/components/steps/';
|
|
80
|
-
if (html) {
|
|
81
|
-
hint += '\n\nFull HTML passed to `<Steps>`:\n' + prettyPrintHtml(html);
|
|
82
|
-
}
|
|
83
|
-
super(message, hint);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import type { Element } from 'hast';
|
|
2
|
-
import { select } from 'hast-util-select';
|
|
3
|
-
import { rehype } from 'rehype';
|
|
4
|
-
import { CONTINUE, SKIP, visit } from 'unist-util-visit';
|
|
5
|
-
import { VFile } from 'vfile';
|
|
6
|
-
import type { StarlightIcon } from '../components-internals/Icons';
|
|
7
|
-
|
|
8
|
-
interface Panel {
|
|
9
|
-
panelId: string;
|
|
10
|
-
tabId: string;
|
|
11
|
-
label: string;
|
|
12
|
-
icon?: StarlightIcon;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
declare module 'vfile' {
|
|
16
|
-
interface DataMap {
|
|
17
|
-
panels: Panel[];
|
|
18
|
-
index: number;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const TabItemTagname = 'starlight-tab-item';
|
|
23
|
-
|
|
24
|
-
// https://github.com/adobe/react-spectrum/blob/99ca82e87ba2d7fdd54f5b49326fd242320b4b51/packages/%40react-aria/focus/src/FocusScope.tsx#L256-L275
|
|
25
|
-
const focusableElementSelectors = [
|
|
26
|
-
'input:not([disabled]):not([type=hidden])',
|
|
27
|
-
'select:not([disabled])',
|
|
28
|
-
'textarea:not([disabled])',
|
|
29
|
-
'button:not([disabled])',
|
|
30
|
-
'a[href]',
|
|
31
|
-
'area[href]',
|
|
32
|
-
'summary',
|
|
33
|
-
'iframe',
|
|
34
|
-
'object',
|
|
35
|
-
'embed',
|
|
36
|
-
'audio[controls]',
|
|
37
|
-
'video[controls]',
|
|
38
|
-
'[contenteditable]',
|
|
39
|
-
'[tabindex]:not([disabled])',
|
|
40
|
-
]
|
|
41
|
-
.map((selector) => `${selector}:not([hidden]):not([tabindex="-1"])`)
|
|
42
|
-
.join(',');
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Rehype processor to extract tab panel data and turn each
|
|
46
|
-
* `<starlight-tab-item>` into a `<div>` with the necessary
|
|
47
|
-
* attributes.
|
|
48
|
-
*/
|
|
49
|
-
const tabsProcessor = rehype()
|
|
50
|
-
.data('settings', { fragment: true })
|
|
51
|
-
.use(function tabs() {
|
|
52
|
-
return (tree: Element, file) => {
|
|
53
|
-
file.data.panels = [];
|
|
54
|
-
let isFirst = true;
|
|
55
|
-
let count = 0;
|
|
56
|
-
const getIDs = () => {
|
|
57
|
-
const id = count++;
|
|
58
|
-
return {
|
|
59
|
-
panelId: `tab-panel-${file.data.index}-${id}`,
|
|
60
|
-
tabId: `tab-${file.data.index}-${id}`,
|
|
61
|
-
};
|
|
62
|
-
};
|
|
63
|
-
visit(tree, 'element', (node) => {
|
|
64
|
-
if (node.tagName !== TabItemTagname || !node.properties) {
|
|
65
|
-
return CONTINUE;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const { dataLabel, dataIcon } = node.properties;
|
|
69
|
-
const ids = getIDs();
|
|
70
|
-
const panel: Panel = {
|
|
71
|
-
...ids,
|
|
72
|
-
label: String(dataLabel),
|
|
73
|
-
};
|
|
74
|
-
if (dataIcon) panel.icon = String(dataIcon) as StarlightIcon;
|
|
75
|
-
file.data.panels?.push(panel);
|
|
76
|
-
|
|
77
|
-
// Remove `<TabItem>` props
|
|
78
|
-
delete node.properties.dataLabel;
|
|
79
|
-
delete node.properties.dataIcon;
|
|
80
|
-
// Turn into `<div>` with required attributes
|
|
81
|
-
node.tagName = 'div';
|
|
82
|
-
node.properties.id = ids.panelId;
|
|
83
|
-
node.properties['aria-labelledby'] = ids.tabId;
|
|
84
|
-
node.properties.role = 'tabpanel';
|
|
85
|
-
|
|
86
|
-
const focusableChild = select(focusableElementSelectors, node);
|
|
87
|
-
// If the panel does not contain any focusable elements, include it in
|
|
88
|
-
// the tab sequence of the page.
|
|
89
|
-
if (!focusableChild) {
|
|
90
|
-
node.properties.tabindex = 0;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Hide all panels except the first
|
|
94
|
-
// TODO: make initially visible tab configurable
|
|
95
|
-
if (isFirst) {
|
|
96
|
-
isFirst = false;
|
|
97
|
-
} else {
|
|
98
|
-
node.properties.hidden = true;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Skip over the tab panel’s children.
|
|
102
|
-
return SKIP;
|
|
103
|
-
});
|
|
104
|
-
};
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Process tab panel items to extract data for the tab links and format
|
|
109
|
-
* each tab panel correctly.
|
|
110
|
-
* @param html Inner HTML passed to the `<Tabs>` component.
|
|
111
|
-
* @param index The index of the `<Tabs>` component on the page.
|
|
112
|
-
*/
|
|
113
|
-
export const processPanels = (html: string, index: number) => {
|
|
114
|
-
const file = tabsProcessor.processSync(new VFile({ value: html, data: { index } }));
|
|
115
|
-
return {
|
|
116
|
-
/** Data for each tab panel. */
|
|
117
|
-
panels: file.data.panels,
|
|
118
|
-
/** Processed HTML for the tab panels. */
|
|
119
|
-
html: file.toString(),
|
|
120
|
-
};
|
|
121
|
-
};
|
package/utils/base.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { stripLeadingSlash, stripTrailingSlash } from './path';
|
|
2
|
-
|
|
3
|
-
const base = stripTrailingSlash(import.meta.env.BASE_URL);
|
|
4
|
-
|
|
5
|
-
/** Get the a root-relative URL path with the site’s `base` prefixed. */
|
|
6
|
-
export function pathWithBase(path: string) {
|
|
7
|
-
path = stripLeadingSlash(path);
|
|
8
|
-
return path ? base + '/' + path : base + '/';
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/** Get the a root-relative file URL path with the site’s `base` prefixed. */
|
|
12
|
-
export function fileWithBase(path: string) {
|
|
13
|
-
path = stripLeadingSlash(path);
|
|
14
|
-
return path ? base + '/' + path : base;
|
|
15
|
-
}
|
package/utils/canonical.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { AstroConfig } from 'astro';
|
|
2
|
-
import { ensureTrailingSlash, stripTrailingSlash } from './path';
|
|
3
|
-
|
|
4
|
-
export interface FormatCanonicalOptions {
|
|
5
|
-
format: AstroConfig['build']['format'];
|
|
6
|
-
trailingSlash: AstroConfig['trailingSlash'];
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const canonicalTrailingSlashStrategies = {
|
|
10
|
-
always: ensureTrailingSlash,
|
|
11
|
-
never: stripTrailingSlash,
|
|
12
|
-
ignore: ensureTrailingSlash,
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
/** Format a canonical link based on the project config. */
|
|
16
|
-
export function formatCanonical(href: string, opts: FormatCanonicalOptions) {
|
|
17
|
-
if (opts.format === 'file') return href;
|
|
18
|
-
return canonicalTrailingSlashStrategies[opts.trailingSlash](href);
|
|
19
|
-
}
|
package/utils/collection-fs.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'node:path';
|
|
2
|
-
import { fileURLToPath } from 'node:url';
|
|
3
|
-
import { getCollectionUrl, type StarlightCollection } from './collection';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @see {@link file://./collection.ts} for more context about this file.
|
|
7
|
-
*
|
|
8
|
-
* Below are various functions to easily get paths to collections used in Starlight that rely on
|
|
9
|
-
* Node.js builtins. They exist in a separate file from {@link file://./collection.ts} to avoid
|
|
10
|
-
* potentially importing Node.js builtins in the final bundle.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
export function resolveCollectionPath(collection: StarlightCollection, srcDir: URL) {
|
|
14
|
-
return resolve(fileURLToPath(srcDir), `content/${collection}`);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function getCollectionPosixPath(collection: StarlightCollection, srcDir: URL) {
|
|
18
|
-
// Return POSIX path with leading slash even on Windows, e.g. `/C:/project/src/content/docs/`.
|
|
19
|
-
return fileURLToPath(getCollectionUrl(collection, srcDir), { windows: false });
|
|
20
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import type { AstroConfig } from 'astro';
|
|
2
|
-
import { fileWithBase, pathWithBase } from './base';
|
|
3
|
-
import {
|
|
4
|
-
ensureHtmlExtension,
|
|
5
|
-
ensureTrailingSlash,
|
|
6
|
-
stripHtmlExtension,
|
|
7
|
-
stripTrailingSlash,
|
|
8
|
-
} from './path';
|
|
9
|
-
|
|
10
|
-
interface FormatPathOptions {
|
|
11
|
-
format?: AstroConfig['build']['format'];
|
|
12
|
-
trailingSlash?: AstroConfig['trailingSlash'];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const defaultFormatStrategy = {
|
|
16
|
-
addBase: pathWithBase,
|
|
17
|
-
handleExtension: (href: string) => stripHtmlExtension(href),
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const formatStrategies = {
|
|
21
|
-
file: {
|
|
22
|
-
addBase: fileWithBase,
|
|
23
|
-
handleExtension: (href: string) => ensureHtmlExtension(href),
|
|
24
|
-
},
|
|
25
|
-
directory: defaultFormatStrategy,
|
|
26
|
-
preserve: defaultFormatStrategy,
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const trailingSlashStrategies = {
|
|
30
|
-
always: ensureTrailingSlash,
|
|
31
|
-
never: stripTrailingSlash,
|
|
32
|
-
ignore: (href: string) => href,
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
/** Format a path based on the project config. */
|
|
36
|
-
function formatPath(
|
|
37
|
-
href: string,
|
|
38
|
-
{ format = 'directory', trailingSlash = 'ignore' }: FormatPathOptions
|
|
39
|
-
) {
|
|
40
|
-
const formatStrategy = formatStrategies[format];
|
|
41
|
-
const trailingSlashStrategy = trailingSlashStrategies[trailingSlash];
|
|
42
|
-
|
|
43
|
-
// Handle extension
|
|
44
|
-
href = formatStrategy.handleExtension(href);
|
|
45
|
-
|
|
46
|
-
// Add base
|
|
47
|
-
href = formatStrategy.addBase(href);
|
|
48
|
-
|
|
49
|
-
// Skip trailing slash handling for `build.format: 'file'`
|
|
50
|
-
if (format === 'file') return href;
|
|
51
|
-
|
|
52
|
-
// Handle trailing slash
|
|
53
|
-
href = href === '/' ? href : trailingSlashStrategy(href);
|
|
54
|
-
|
|
55
|
-
return href;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function createPathFormatter(opts: FormatPathOptions) {
|
|
59
|
-
return (href: string) => formatPath(href, opts);
|
|
60
|
-
}
|