blume 1.5.2 → 1.6.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/CHANGELOG.md +85 -0
- package/dist/cli/index.js +3639 -1377
- package/dist/cli/index.js.map +103 -91
- package/dist/types/ai/component-markdown.d.ts +79 -0
- package/dist/types/components/layout/nav-utils.d.ts +60 -0
- package/dist/types/core/base-path.d.ts +9 -0
- package/dist/types/core/config-input.d.ts +206 -4
- package/dist/types/core/config.d.ts +6 -4
- package/dist/types/core/data.d.ts +23 -1
- package/dist/types/core/github.d.ts +35 -0
- package/dist/types/core/i18n-ui.d.ts +8 -0
- package/dist/types/core/navigation.d.ts +69 -0
- package/dist/types/core/schema.d.ts +117 -1
- package/dist/types/core/sources/types.d.ts +31 -6
- package/dist/types/core/types.d.ts +23 -2
- package/dist/types/markdown/features.d.ts +21 -0
- package/dist/types/openapi/references.d.ts +21 -1
- package/dist/types/seo/jsonld.d.ts +105 -0
- package/dist/types/theme/fonts.d.ts +34 -4
- package/docs/_snippets/include-demo.mdx +7 -0
- package/docs/advanced/api-reference.mdx +3 -3
- package/docs/advanced/custom-pages.mdx +1 -1
- package/docs/advanced/graphql.mdx +84 -0
- package/docs/advanced/meta.ts +8 -1
- package/docs/configuration/ai.mdx +21 -3
- package/docs/configuration/index.mdx +24 -0
- package/docs/configuration/search.mdx +13 -1
- package/docs/configuration/seo.mdx +27 -0
- package/docs/configuration/theming.mdx +17 -0
- package/docs/content/components.mdx +7 -0
- package/docs/content/includes.mdx +68 -0
- package/docs/content/meta.ts +1 -0
- package/docs/content/navigation.mdx +25 -0
- package/docs/content/sources.mdx +42 -1
- package/docs/content/syntax.mdx +69 -1
- package/docs/content/versioning.mdx +15 -9
- package/docs/reference/cli.mdx +2 -1
- package/package.json +23 -14
- package/skills/blume-migrate/SKILL.md +16 -7
- package/skills/blume-migrate/references/docusaurus.md +5 -3
- package/skills/blume-migrate/references/fumadocs.md +10 -2
- package/skills/blume-migrate/references/mintlify.md +3 -2
- package/skills/blume-migrate/references/nextra.md +2 -2
- package/skills/blume-migrate/references/starlight.md +1 -1
- package/src/ai/agent-readability.ts +2 -1
- package/src/ai/ask-data.ts +2 -1
- package/src/ai/component-markdown.ts +199 -36
- package/src/ai/llms.ts +93 -6
- package/src/ai/markdown.ts +2 -2
- package/src/ai/mcp/discovery.ts +10 -2
- package/src/ai/mcp/server.ts +74 -2
- package/src/astro/generate.ts +183 -116
- package/src/astro/include-hmr.ts +81 -0
- package/src/astro/include-refresh.ts +0 -0
- package/src/astro/index.ts +3 -5
- package/src/astro/templates.ts +125 -76
- package/src/cli/commands/build.ts +84 -15
- package/src/cli/init/questions.ts +1 -0
- package/src/cli/init/scaffold.ts +27 -4
- package/src/components/colors.ts +142 -0
- package/src/components/content/Badge.astro +5 -12
- package/src/components/content/Callout.astro +19 -36
- package/src/components/content/Card.astro +15 -21
- package/src/components/content/Component.astro +10 -1
- package/src/components/content/GithubInfo.astro +28 -9
- package/src/components/content/Tabs.astro +27 -5
- package/src/components/content/github-info.ts +20 -5
- package/src/components/dropdown-dismiss.ts +122 -0
- package/src/components/layout/Fonts.astro +15 -8
- package/src/components/layout/Header.astro +44 -0
- package/src/components/layout/LanguageSwitcher.astro +9 -1
- package/src/components/layout/NavSelector.astro +12 -3
- package/src/components/layout/NavTree.astro +6 -18
- package/src/components/layout/PageActions.astro +29 -8
- package/src/components/layout/PageLayout.astro +10 -1
- package/src/components/layout/ReferenceLayout.astro +6 -1
- package/src/components/layout/RootLayout.astro +46 -15
- package/src/components/layout/Search.astro +36 -4
- package/src/components/layout/TableOfContents.astro +8 -2
- package/src/components/layout/head-scripts.ts +53 -1
- package/src/components/openapi/ApiOverview.astro +13 -3
- package/src/components/openapi/AsyncApiOperation.astro +7 -14
- package/src/components/openapi/GraphqlChip.astro +33 -0
- package/src/components/openapi/GraphqlFieldsTable.astro +111 -0
- package/src/components/openapi/GraphqlOperation.astro +186 -0
- package/src/components/openapi/GraphqlType.astro +154 -0
- package/src/components/openapi/MethodBadge.astro +3 -14
- package/src/components/openapi/Operation.astro +12 -5
- package/src/components/openapi/OperationPanel.astro +43 -0
- package/src/components/openapi/RequestPanel.astro +5 -10
- package/src/components/openapi/Responses.astro +1 -16
- package/src/components/openapi/graphql-helpers.ts +466 -0
- package/src/components/openapi/playground-client.ts +15 -0
- package/src/components/openapi/sample-panels.ts +45 -0
- package/src/components/openapi/snippets.ts +13 -35
- package/src/core/base-path.ts +11 -0
- package/src/core/config-input.ts +209 -2
- package/src/core/config.ts +6 -4
- package/src/core/content-assets.ts +15 -4
- package/src/core/data.ts +18 -2
- package/src/core/diagnostics.ts +8 -0
- package/src/core/frontmatter.ts +20 -8
- package/src/core/github.ts +71 -0
- package/src/core/graph.ts +22 -8
- package/src/core/heading-markers.ts +96 -0
- package/src/core/i18n-ui.ts +11 -0
- package/src/core/includes.ts +632 -0
- package/src/core/last-modified.ts +36 -11
- package/src/core/links.ts +79 -13
- package/src/core/meta.ts +2 -1
- package/src/core/nav-diagnostics.ts +11 -2
- package/src/core/navigation.ts +27 -6
- package/src/core/project-graph.ts +61 -9
- package/src/core/schema.ts +226 -35
- package/src/core/server-features.ts +5 -9
- package/src/core/sources/github-releases.ts +2 -2
- package/src/core/sources/normalize.ts +502 -115
- package/src/core/sources/notion.ts +43 -8
- package/src/core/sources/obsidian.ts +1038 -0
- package/src/core/sources/read.ts +36 -1
- package/src/core/sources/resolve.ts +34 -1
- package/src/core/sources/types.ts +28 -6
- package/src/core/sources/watch.ts +12 -8
- package/src/core/tsconfig-aliases.ts +48 -35
- package/src/core/types.ts +25 -2
- package/src/core/ui-packs/ar.ts +1 -0
- package/src/core/ui-packs/bg.ts +2 -0
- package/src/core/ui-packs/bn.ts +1 -0
- package/src/core/ui-packs/ca.ts +2 -0
- package/src/core/ui-packs/cs.ts +1 -0
- package/src/core/ui-packs/da.ts +1 -0
- package/src/core/ui-packs/de.ts +2 -0
- package/src/core/ui-packs/el.ts +2 -0
- package/src/core/ui-packs/es.ts +2 -0
- package/src/core/ui-packs/fa.ts +1 -0
- package/src/core/ui-packs/fi.ts +1 -0
- package/src/core/ui-packs/fr.ts +2 -0
- package/src/core/ui-packs/he.ts +1 -0
- package/src/core/ui-packs/hi.ts +1 -0
- package/src/core/ui-packs/hr.ts +2 -0
- package/src/core/ui-packs/hu.ts +2 -0
- package/src/core/ui-packs/id.ts +2 -0
- package/src/core/ui-packs/it.ts +1 -0
- package/src/core/ui-packs/ja.ts +2 -0
- package/src/core/ui-packs/ko.ts +2 -0
- package/src/core/ui-packs/nl.ts +2 -0
- package/src/core/ui-packs/no.ts +2 -0
- package/src/core/ui-packs/pl.ts +2 -0
- package/src/core/ui-packs/pt-br.ts +2 -0
- package/src/core/ui-packs/pt.ts +2 -0
- package/src/core/ui-packs/ro.ts +2 -0
- package/src/core/ui-packs/ru.ts +2 -0
- package/src/core/ui-packs/sk.ts +1 -0
- package/src/core/ui-packs/sr.ts +1 -0
- package/src/core/ui-packs/sv.ts +2 -0
- package/src/core/ui-packs/th.ts +1 -0
- package/src/core/ui-packs/tr.ts +2 -0
- package/src/core/ui-packs/uk.ts +2 -0
- package/src/core/ui-packs/vi.ts +1 -0
- package/src/core/ui-packs/zh-tw.ts +1 -0
- package/src/core/ui-packs/zh.ts +1 -0
- package/src/core/version-cut.ts +21 -3
- package/src/core/yaml.ts +26 -0
- package/src/deploy/function-bundle.ts +251 -0
- package/src/eval/schema.ts +3 -1
- package/src/markdown/code-title.ts +22 -16
- package/src/markdown/features.ts +21 -0
- package/src/markdown/fence-meta.ts +50 -0
- package/src/markdown/heading-anchors.ts +198 -37
- package/src/markdown/include.ts +247 -0
- package/src/markdown/index.ts +43 -34
- package/src/markdown/language-icon.ts +2 -2
- package/src/markdown/mdast.ts +7 -3
- package/src/markdown/ts2js.ts +264 -0
- package/src/openapi/asyncapi.ts +4 -1
- package/src/openapi/graphql-build.ts +293 -0
- package/src/openapi/graphql.ts +212 -0
- package/src/openapi/model.ts +38 -5
- package/src/openapi/parse.ts +34 -0
- package/src/openapi/proxy.ts +30 -5
- package/src/openapi/references.ts +89 -13
- package/src/openapi/render-mdx.ts +48 -8
- package/src/openapi/scalar.ts +5 -12
- package/src/openapi/source.ts +91 -23
- package/src/registry/eject.ts +11 -0
- package/src/search/documents.ts +229 -37
- package/src/search/orama-index.ts +9 -5
- package/src/seo/jsonld.ts +293 -51
- package/src/theme/code-block-padding.ts +16 -0
- package/src/theme/entry.ts +65 -11
- package/src/theme/fonts.ts +189 -16
- package/src/translate/prompts.ts +2 -0
- package/src/translate/run.ts +7 -0
- package/src/translate/work-list.ts +0 -0
package/src/core/config-input.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type { CodeTheme } from "../markdown/themes.ts";
|
|
|
7
7
|
import type { FontSlug } from "../theme/fonts.ts";
|
|
8
8
|
import type {
|
|
9
9
|
blumeConfigSchema,
|
|
10
|
+
GraphqlSource,
|
|
10
11
|
OpenApiSource,
|
|
11
12
|
OpenInChatProvider,
|
|
12
13
|
SearchProvider,
|
|
@@ -232,6 +233,21 @@ export interface NotionSource {
|
|
|
232
233
|
publishedValue?: string;
|
|
233
234
|
}
|
|
234
235
|
|
|
236
|
+
/**
|
|
237
|
+
* An Obsidian vault, read in place. Wikilinks become route links and
|
|
238
|
+
* `%%comments%%` are stripped at load time, so the vault stays the source of
|
|
239
|
+
* truth — no export step and no generated notes in the repo.
|
|
240
|
+
*/
|
|
241
|
+
export interface ObsidianSource {
|
|
242
|
+
type: "obsidian";
|
|
243
|
+
/** Vault folder names to skip at any depth, in addition to dot-folders. */
|
|
244
|
+
exclude?: string[];
|
|
245
|
+
/** Namespaces this source's routes under `/<prefix>/`; e.g. `vault`. */
|
|
246
|
+
prefix?: string;
|
|
247
|
+
/** Vault directory, absolute or relative to the project root. */
|
|
248
|
+
vault: string;
|
|
249
|
+
}
|
|
250
|
+
|
|
235
251
|
/**
|
|
236
252
|
* A user-provided {@link ContentSource} instance, passed straight through. This
|
|
237
253
|
* is the extension point for adapters with custom serializers or any other
|
|
@@ -250,6 +266,7 @@ export type ContentSourceInput =
|
|
|
250
266
|
| GithubReleasesSource
|
|
251
267
|
| SanitySource
|
|
252
268
|
| NotionSource
|
|
269
|
+
| ObsidianSource
|
|
253
270
|
| CustomSource;
|
|
254
271
|
|
|
255
272
|
/**
|
|
@@ -446,12 +463,28 @@ export type SidebarConfig =
|
|
|
446
463
|
items?: SidebarItemConfig[];
|
|
447
464
|
};
|
|
448
465
|
|
|
466
|
+
/** A plain header link, or the header's single call to action. */
|
|
467
|
+
export interface HeaderAction {
|
|
468
|
+
/** Link target. An external href opens in a new tab. */
|
|
469
|
+
href: string;
|
|
470
|
+
/** Link label. */
|
|
471
|
+
label: string;
|
|
472
|
+
}
|
|
473
|
+
|
|
449
474
|
/** Header, sidebar, tabs, and switcher configuration. */
|
|
450
475
|
export interface NavigationConfig {
|
|
476
|
+
/** Plain links in the header, left of the icon buttons. */
|
|
477
|
+
actions?: HeaderAction[];
|
|
478
|
+
/** The single primary call to action in the header, as a filled button. */
|
|
479
|
+
cta?: HeaderAction;
|
|
451
480
|
/** Pinned links shown above the generated sidebar sections. */
|
|
452
481
|
featured?: FeaturedLink[];
|
|
453
|
-
/**
|
|
454
|
-
|
|
482
|
+
/**
|
|
483
|
+
* The GitHub link in the header. `true` derives it from `github` (the
|
|
484
|
+
* default), `false` hides it, and an absolute URL points it anywhere on
|
|
485
|
+
* GitHub — an organization, say, when the docs repo itself is private.
|
|
486
|
+
*/
|
|
487
|
+
repo?: boolean | string;
|
|
455
488
|
/** Context switchers shown in the header (versions, languages, …). */
|
|
456
489
|
selectors?: NavSelector[];
|
|
457
490
|
/** Sidebar behavior and (optionally) an explicit sidebar tree. */
|
|
@@ -478,6 +511,11 @@ export interface RemoteFontInput {
|
|
|
478
511
|
name: string;
|
|
479
512
|
/** Which provider serves the family. Defaults to `google`. */
|
|
480
513
|
provider?: "google" | "fontsource" | "bunny" | "fontshare";
|
|
514
|
+
/**
|
|
515
|
+
* Character subsets to load (`"latin"`, `"vietnamese"`, `"cyrillic"`, …).
|
|
516
|
+
* Defaults to `latin` plus whatever the configured locales need.
|
|
517
|
+
*/
|
|
518
|
+
subsets?: string[];
|
|
481
519
|
/** Weights (or variable ranges like `"100..900"`) to load. Defaults to `[400, 500, 600, 700]`. */
|
|
482
520
|
weights?: (number | string)[];
|
|
483
521
|
}
|
|
@@ -603,6 +641,12 @@ export interface SearchConfig {
|
|
|
603
641
|
algolia?: AlgoliaSearch;
|
|
604
642
|
/** Indexing behavior. */
|
|
605
643
|
indexing?: {
|
|
644
|
+
/**
|
|
645
|
+
* Index fenced code (body and title) in the source-built search indexes —
|
|
646
|
+
* the client index, hosted syncs, and the MCP `search_docs` index.
|
|
647
|
+
* Defaults to `false`; Pagefind and Mixedbread index code regardless.
|
|
648
|
+
*/
|
|
649
|
+
includeCodeBlocks?: boolean;
|
|
606
650
|
/** Include pages marked `hidden` in the search index. Defaults to `false`. */
|
|
607
651
|
includeHiddenPages?: boolean;
|
|
608
652
|
};
|
|
@@ -701,6 +745,22 @@ export interface AskConfig {
|
|
|
701
745
|
|
|
702
746
|
/** What the `llms.txt`/`llms-full.txt` files include. */
|
|
703
747
|
export interface LlmsTxtConfig {
|
|
748
|
+
/**
|
|
749
|
+
* Markdown placed after the title and summary in `llms.txt`, before the
|
|
750
|
+
* page sections — the llms.txt spec's "details" block. Use it to tell
|
|
751
|
+
* agents when to reach for the product and how to call it (a "When to use"
|
|
752
|
+
* heading, the install command, the package name). Blank values are
|
|
753
|
+
* dropped.
|
|
754
|
+
*
|
|
755
|
+
* ```ts
|
|
756
|
+
* ai: {
|
|
757
|
+
* llmsTxt: {
|
|
758
|
+
* details: "## When to use Acme\n\nUse Acme when…",
|
|
759
|
+
* },
|
|
760
|
+
* }
|
|
761
|
+
* ```
|
|
762
|
+
*/
|
|
763
|
+
details?: string;
|
|
704
764
|
/** Emit `llms.txt` and `llms-full.txt`. Defaults to `true`. */
|
|
705
765
|
enabled?: boolean;
|
|
706
766
|
/**
|
|
@@ -1108,6 +1168,68 @@ export interface OgConfig {
|
|
|
1108
1168
|
titles?: Record<string, string>;
|
|
1109
1169
|
}
|
|
1110
1170
|
|
|
1171
|
+
/** A schema.org `PostalAddress`; give whichever parts apply. */
|
|
1172
|
+
export interface PostalAddressConfig {
|
|
1173
|
+
/** Country name or ISO 3166-1 alpha-2 code (`"US"`). */
|
|
1174
|
+
addressCountry?: string;
|
|
1175
|
+
/** City or locality. */
|
|
1176
|
+
addressLocality?: string;
|
|
1177
|
+
/** State, province, or region. */
|
|
1178
|
+
addressRegion?: string;
|
|
1179
|
+
postalCode?: string;
|
|
1180
|
+
streetAddress?: string;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
/**
|
|
1184
|
+
* The organization behind the site, emitted in every page's JSON-LD as an
|
|
1185
|
+
* `Organization` node that the WebSite and article nodes cite as publisher.
|
|
1186
|
+
* Contact details become a `ContactPoint` and the address a `PostalAddress` —
|
|
1187
|
+
* the fields AI agents check to verify a business before recommending it.
|
|
1188
|
+
* Requires `deployment.site` (the node needs an absolute identifier).
|
|
1189
|
+
*/
|
|
1190
|
+
export interface OrganizationConfig {
|
|
1191
|
+
/** Postal address, emitted as a `PostalAddress` when any part is given. */
|
|
1192
|
+
address?: PostalAddressConfig;
|
|
1193
|
+
/** `ContactPoint.contactType` for the email/telephone. Defaults to `"customer support"`. */
|
|
1194
|
+
contactType?: string;
|
|
1195
|
+
/** Public contact email. */
|
|
1196
|
+
email?: string;
|
|
1197
|
+
/** Logo: an absolute URL or a root-relative path (`"/logo.svg"`). */
|
|
1198
|
+
logo?: string;
|
|
1199
|
+
/** Organization name. Defaults to the site title. */
|
|
1200
|
+
name?: string;
|
|
1201
|
+
/** Profile URLs that identify the organization (GitHub, X, LinkedIn, …). */
|
|
1202
|
+
sameAs?: string[];
|
|
1203
|
+
/** Public contact telephone number. */
|
|
1204
|
+
telephone?: string;
|
|
1205
|
+
/** Organization website. Defaults to the site origin. */
|
|
1206
|
+
url?: string;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
/**
|
|
1210
|
+
* The product the site documents, emitted on the homepage as a
|
|
1211
|
+
* `SoftwareApplication` JSON-LD node — the identity type that tells agents
|
|
1212
|
+
* what the site is about. Requires `deployment.site`.
|
|
1213
|
+
*/
|
|
1214
|
+
export interface SoftwareConfig {
|
|
1215
|
+
/** schema.org application category. Defaults to `"DeveloperApplication"`. */
|
|
1216
|
+
applicationCategory?: string;
|
|
1217
|
+
/** Product description. Defaults to the site description. */
|
|
1218
|
+
description?: string;
|
|
1219
|
+
/** License URL or SPDX identifier (`"MIT"`). */
|
|
1220
|
+
license?: string;
|
|
1221
|
+
/** Product name. Defaults to the site title. */
|
|
1222
|
+
name?: string;
|
|
1223
|
+
/** Supported platform(s), e.g. `"Node.js 22+"`. */
|
|
1224
|
+
operatingSystem?: string;
|
|
1225
|
+
/** Price, emitted as an `Offer`; `0` marks the software free. */
|
|
1226
|
+
price?: number | string;
|
|
1227
|
+
/** Currency of `price` (ISO 4217). Defaults to `"USD"`. */
|
|
1228
|
+
priceCurrency?: string;
|
|
1229
|
+
/** Package registry, repository, and profile URLs for the product. */
|
|
1230
|
+
sameAs?: string[];
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1111
1233
|
/** Discoverability: OG images, feeds, sitemap, robots, and structured data. */
|
|
1112
1234
|
export interface SeoConfig {
|
|
1113
1235
|
/**
|
|
@@ -1119,12 +1241,39 @@ export interface SeoConfig {
|
|
|
1119
1241
|
contentSignals?: ContentSignalsConfig;
|
|
1120
1242
|
/** Per-page Open Graph image generation. */
|
|
1121
1243
|
og?: OgConfig;
|
|
1244
|
+
/**
|
|
1245
|
+
* The organization behind the site, added to every page's JSON-LD as an
|
|
1246
|
+
* `Organization` node with contact point and address.
|
|
1247
|
+
*
|
|
1248
|
+
* ```ts
|
|
1249
|
+
* seo: {
|
|
1250
|
+
* organization: {
|
|
1251
|
+
* email: "hello@acme.com",
|
|
1252
|
+
* logo: "/logo.svg",
|
|
1253
|
+
* sameAs: ["https://github.com/acme", "https://x.com/acme"],
|
|
1254
|
+
* },
|
|
1255
|
+
* }
|
|
1256
|
+
* ```
|
|
1257
|
+
*/
|
|
1258
|
+
organization?: OrganizationConfig;
|
|
1122
1259
|
/** Generate robots.txt (with a Sitemap reference when available). Defaults to `true`. */
|
|
1123
1260
|
robots?: boolean;
|
|
1124
1261
|
/** RSS/Atom feeds. */
|
|
1125
1262
|
rss?: RssConfig;
|
|
1126
1263
|
/** Generate sitemap.xml (requires `deployment.site`). Defaults to `true`. */
|
|
1127
1264
|
sitemap?: boolean;
|
|
1265
|
+
/**
|
|
1266
|
+
* The documented product, added to the homepage's JSON-LD as a
|
|
1267
|
+
* `SoftwareApplication` node. `true` takes every default (name and
|
|
1268
|
+
* description from the site); the object form fills in the rest.
|
|
1269
|
+
*
|
|
1270
|
+
* ```ts
|
|
1271
|
+
* seo: {
|
|
1272
|
+
* software: { license: "MIT", operatingSystem: "Node.js 22+", price: 0 },
|
|
1273
|
+
* }
|
|
1274
|
+
* ```
|
|
1275
|
+
*/
|
|
1276
|
+
software?: boolean | SoftwareConfig;
|
|
1128
1277
|
/** Emit schema.org JSON-LD in each page's `<head>`. Defaults to `true`. */
|
|
1129
1278
|
structuredData?: boolean;
|
|
1130
1279
|
/**
|
|
@@ -1146,10 +1295,27 @@ export interface SeoConfig {
|
|
|
1146
1295
|
|
|
1147
1296
|
/** Source repository, powering "Edit this page" links and the header repo link. */
|
|
1148
1297
|
export interface GithubConfig {
|
|
1298
|
+
/**
|
|
1299
|
+
* REST API base, for a `<GithubInfo>` card against an Enterprise instance.
|
|
1300
|
+
* Derived from `host` when unset: `api.github.com` for github.com, an `api.`
|
|
1301
|
+
* subdomain for an Enterprise Cloud data-residency tenant, and `/api/v3` for
|
|
1302
|
+
* Enterprise Server. Must be an HTTP(S) URL, and is reduced to an origin plus
|
|
1303
|
+
* its path — the repository route is appended to it.
|
|
1304
|
+
*/
|
|
1305
|
+
api?: string;
|
|
1149
1306
|
/** Default branch. Defaults to `main`. */
|
|
1150
1307
|
branch?: string;
|
|
1151
1308
|
/** Path from the repo root to the project root (for monorepos). */
|
|
1152
1309
|
dir?: string;
|
|
1310
|
+
/**
|
|
1311
|
+
* Origin of the GitHub instance the repo lives on. Defaults to
|
|
1312
|
+
* `https://github.com`; set it to an Enterprise host (for example
|
|
1313
|
+
* `https://github.acme.com` or `https://acme.ghe.com`) so the header link,
|
|
1314
|
+
* edit links, and the agent manifest point at that instance. Must be an
|
|
1315
|
+
* HTTP(S) URL, and is reduced to its origin — every repo URL is built by
|
|
1316
|
+
* appending to it.
|
|
1317
|
+
*/
|
|
1318
|
+
host?: string;
|
|
1153
1319
|
/** Repository owner (user or org). */
|
|
1154
1320
|
owner: string;
|
|
1155
1321
|
/** Repository name. */
|
|
@@ -1278,6 +1444,45 @@ export interface AsyncApiConfig extends ReferenceConfig {
|
|
|
1278
1444
|
route?: string;
|
|
1279
1445
|
}
|
|
1280
1446
|
|
|
1447
|
+
/**
|
|
1448
|
+
* GraphQL reference. Blume lowers the schema — SDL text or an introspection
|
|
1449
|
+
* JSON result, local or remote — into one real page per root field (grouped
|
|
1450
|
+
* as Queries/Mutations/Subscriptions) plus one page per named type (Objects,
|
|
1451
|
+
* Input Objects, Enums, Interfaces, Unions, Scalars), all in the sidebar,
|
|
1452
|
+
* search, llms.txt, and OG. Always Blume-rendered — the embedded Scalar SPA
|
|
1453
|
+
* reads OpenAPI documents only — so unlike the other reference blocks there
|
|
1454
|
+
* is no `renderer` opt-out.
|
|
1455
|
+
*/
|
|
1456
|
+
export interface GraphqlConfig {
|
|
1457
|
+
/**
|
|
1458
|
+
* Code-sample languages shown per operation. Defaults to
|
|
1459
|
+
* `["curl", "js", "python"]`.
|
|
1460
|
+
*/
|
|
1461
|
+
codeSamples?: string[];
|
|
1462
|
+
/** Turn the reference on. Defaults to `false`. */
|
|
1463
|
+
enabled?: boolean;
|
|
1464
|
+
/**
|
|
1465
|
+
* URL of the live GraphQL endpoint the playground and code samples target —
|
|
1466
|
+
* a schema, unlike an OpenAPI document, names no server. Applies to every
|
|
1467
|
+
* source in the block; a per-source `endpoint` wins.
|
|
1468
|
+
*/
|
|
1469
|
+
endpoint?: string;
|
|
1470
|
+
/**
|
|
1471
|
+
* The interactive "Try it" panel on operation pages. On by default; `false`
|
|
1472
|
+
* hides it. The object form keeps it on and sets `proxy`, the CORS escape
|
|
1473
|
+
* hatch the Send button routes requests through: a proxy URL, or `true` for
|
|
1474
|
+
* the built-in `/_api-proxy` endpoint (which requires
|
|
1475
|
+
* `deployment.output: "server"`).
|
|
1476
|
+
*/
|
|
1477
|
+
playground?: boolean | { enabled?: boolean; proxy?: boolean | string };
|
|
1478
|
+
/** Where the reference mounts. Defaults to `/graphql`. */
|
|
1479
|
+
route?: string;
|
|
1480
|
+
/** One or more schemas; each renders on its own route by default. */
|
|
1481
|
+
sources?: GraphqlSource[];
|
|
1482
|
+
/** Shorthand for a single source: `sources: [{ spec }]`. */
|
|
1483
|
+
spec?: string;
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1281
1486
|
// ---------------------------------------------------------------------------
|
|
1282
1487
|
// Misc top-level unions
|
|
1283
1488
|
// ---------------------------------------------------------------------------
|
|
@@ -1456,6 +1661,8 @@ export interface BlumeConfig {
|
|
|
1456
1661
|
frontmatter?: FrontmatterConfig;
|
|
1457
1662
|
/** Source repository (Edit-this-page links and the header repo link). */
|
|
1458
1663
|
github?: GithubConfig;
|
|
1664
|
+
/** Native GraphQL reference (root fields and named types as real pages). */
|
|
1665
|
+
graphql?: GraphqlConfig;
|
|
1459
1666
|
/** Internationalization (opt-in multi-locale). */
|
|
1460
1667
|
i18n?: I18nConfig;
|
|
1461
1668
|
/** Image optimization: remote-host authorization for the image service. */
|
package/src/core/config.ts
CHANGED
|
@@ -50,11 +50,13 @@ import type { Diagnostic } from "./types.ts";
|
|
|
50
50
|
* custom `ContentSource`). Omit `sources` and the top-level `root` becomes one
|
|
51
51
|
* implicit filesystem source.
|
|
52
52
|
* - `navigation` — sidebar, header `tabs`, `selectors` (version/language/product
|
|
53
|
-
* switchers), pinned `featured` links,
|
|
54
|
-
* `sidebar` to generate it
|
|
53
|
+
* switchers), pinned `featured` links, header `actions` and the one `cta`,
|
|
54
|
+
* and the `repo` link (a toggle, or a URL). Omit `sidebar` to generate it
|
|
55
|
+
* from the content tree.
|
|
55
56
|
* - `redirects` — `{ from, to, status }` rules (301 by default).
|
|
56
|
-
* - `github` — `{ owner, repo, branch, dir }`, powering "Edit this
|
|
57
|
-
* and the header repo link
|
|
57
|
+
* - `github` — `{ owner, repo, branch, dir, host, api }`, powering "Edit this
|
|
58
|
+
* page" links and the header repo link; `host` points them at a GitHub
|
|
59
|
+
* Enterprise instance, `api` overrides the REST base derived from it.
|
|
58
60
|
*
|
|
59
61
|
* **Appearance**
|
|
60
62
|
* - `theme` — `accent` color, `fonts` (curated slugs, any provider family, or
|
|
@@ -19,6 +19,9 @@ import {
|
|
|
19
19
|
nextFenceState,
|
|
20
20
|
targetOffsetIn,
|
|
21
21
|
} from "./sources/normalize.ts";
|
|
22
|
+
import { readExpandedEntryText } from "./sources/read.ts";
|
|
23
|
+
import type { ContentSource } from "./sources/types.ts";
|
|
24
|
+
import type { PageRecord } from "./types.ts";
|
|
22
25
|
|
|
23
26
|
/**
|
|
24
27
|
* Colocated content images — `` next to the page that
|
|
@@ -217,22 +220,30 @@ export const rewriteRelativeImages = (options: {
|
|
|
217
220
|
* Every colocated image the project's pages reference, keyed by endpoint param.
|
|
218
221
|
* Serialized to `generated/content-assets.json`, which the
|
|
219
222
|
* `/blume-assets/[...asset]` endpoint reads to serve the original files. Runs
|
|
220
|
-
* the same rewrite the agent-Markdown builders apply
|
|
221
|
-
*
|
|
223
|
+
* the same rewrite the agent-Markdown builders apply — over the same
|
|
224
|
+
* include-expanded text, so a partial's colocated images (rebased into the
|
|
225
|
+
* including page by the expander) are served too — keeping the served set and
|
|
226
|
+
* the rewritten URLs from drifting apart.
|
|
222
227
|
*/
|
|
223
228
|
export const collectContentAssets = async (project: {
|
|
224
229
|
context: { root: string };
|
|
225
|
-
manifest: { routes: { sourcePath?: string }[] };
|
|
230
|
+
manifest: { routes: { id: string; sourcePath?: string }[] };
|
|
231
|
+
graph: { pages: PageRecord[] };
|
|
232
|
+
sources?: ContentSource[];
|
|
226
233
|
}): Promise<Record<string, string>> => {
|
|
234
|
+
const pageById = new Map(project.graph.pages.map((page) => [page.id, page]));
|
|
227
235
|
const files: Record<string, string> = {};
|
|
228
236
|
await Promise.all(
|
|
229
237
|
project.manifest.routes.map(async (route) => {
|
|
230
238
|
if (!route.sourcePath) {
|
|
231
239
|
return;
|
|
232
240
|
}
|
|
241
|
+
const page = pageById.get(route.id);
|
|
233
242
|
let source: string;
|
|
234
243
|
try {
|
|
235
|
-
source =
|
|
244
|
+
source = page
|
|
245
|
+
? await readExpandedEntryText(project, page)
|
|
246
|
+
: await readFile(route.sourcePath, "utf-8");
|
|
236
247
|
} catch {
|
|
237
248
|
return;
|
|
238
249
|
}
|
package/src/core/data.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { StructuredDataIdentity } from "../seo/jsonld.ts";
|
|
1
2
|
import type { FontHead } from "../theme/fonts.ts";
|
|
2
3
|
import type { UIStrings } from "./i18n-ui.ts";
|
|
3
4
|
import type { ResolvedConfig, SearchProvider } from "./schema.ts";
|
|
@@ -128,12 +129,27 @@ export interface BlumeDataConfig {
|
|
|
128
129
|
* Which agent-discovery resources exist for the layout to advertise in every
|
|
129
130
|
* page's `<head>` (`seo.agentReadability`, `ai.llmsTxt.enabled`) — the HTML
|
|
130
131
|
* counterpart of the homepage-only HTTP `Link` header, for agents that enter
|
|
131
|
-
* on a deep page (see `ai/link-headers.ts`).
|
|
132
|
+
* on a deep page (see `ai/link-headers.ts`). `sitemap` (`seo.sitemap` with a
|
|
133
|
+
* `deployment.site`, the condition under which one is emitted) feeds the
|
|
134
|
+
* 404 page's recovery links rather than the head.
|
|
132
135
|
*/
|
|
133
|
-
discovery: { agentReadability: boolean; llmsTxt: boolean };
|
|
136
|
+
discovery: { agentReadability: boolean; llmsTxt: boolean; sitemap: boolean };
|
|
134
137
|
favicon: BlumeFavicon;
|
|
135
138
|
feedback: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Repo coordinates for content components that address the API or build
|
|
141
|
+
* their own repo links (`<GithubInfo>`, the OG card's footer slug), carrying
|
|
142
|
+
* `host`/`api` so an Enterprise instance is reachable; `null` when `github`
|
|
143
|
+
* is unset. The plain repository URL stays on `repoUrl`.
|
|
144
|
+
*/
|
|
145
|
+
github: { api: string; host: string; owner: string; repo: string } | null;
|
|
136
146
|
i18n: BlumeDataI18n | null;
|
|
147
|
+
/**
|
|
148
|
+
* Site identity for JSON-LD (`seo.organization`, `seo.software`), read by
|
|
149
|
+
* the layouts straight from the snapshot so custom pages get it without
|
|
150
|
+
* threading a prop; `null` when neither is configured.
|
|
151
|
+
*/
|
|
152
|
+
identity: StructuredDataIdentity | null;
|
|
137
153
|
/** `markdown.imageZoom`: click-to-zoom content images. */
|
|
138
154
|
imageZoom: boolean;
|
|
139
155
|
logo: BlumeLogo | null;
|
package/src/core/diagnostics.ts
CHANGED
|
@@ -25,6 +25,7 @@ const DOCS_DEPLOYMENT = "/docs/deployment";
|
|
|
25
25
|
const DOCS_REFERENCE_CLI = "/docs/reference/cli";
|
|
26
26
|
const DOCS_CONTENT_SOURCES = "/docs/content/sources";
|
|
27
27
|
const DOCS_CONTENT_NAVIGATION = "/docs/content/navigation";
|
|
28
|
+
const DOCS_CONTENT_INCLUDES = "/docs/content/includes";
|
|
28
29
|
|
|
29
30
|
/** Diagnostic code → the docs page that explains it. */
|
|
30
31
|
const DOCS_PATHS = new Map(
|
|
@@ -42,6 +43,11 @@ const DOCS_PATHS = new Map(
|
|
|
42
43
|
BLUME_DUPLICATE_ROUTE: DOCS_CONTENT_NAVIGATION,
|
|
43
44
|
BLUME_DUPLICATE_SIDEBAR_ORDER: DOCS_CONTENT_NAVIGATION,
|
|
44
45
|
BLUME_FRONTMATTER_INVALID: "/docs/reference/frontmatter",
|
|
46
|
+
BLUME_INCLUDE_CYCLE: DOCS_CONTENT_INCLUDES,
|
|
47
|
+
BLUME_INCLUDE_NOT_FOUND: DOCS_CONTENT_INCLUDES,
|
|
48
|
+
BLUME_INCLUDE_OUTSIDE_ROOT: DOCS_CONTENT_INCLUDES,
|
|
49
|
+
BLUME_MDX_CURLY_ANCHOR: "/docs/content/syntax",
|
|
50
|
+
|
|
45
51
|
BLUME_META_INVALID: "/docs/content/meta",
|
|
46
52
|
BLUME_META_LOAD_FAILED: "/docs/content/meta",
|
|
47
53
|
BLUME_MISSING_SECRET: DOCS_DEPLOYMENT,
|
|
@@ -59,6 +65,8 @@ const DOCS_PATHS = new Map(
|
|
|
59
65
|
BLUME_SOURCE_UNAVAILABLE: DOCS_CONTENT_SOURCES,
|
|
60
66
|
BLUME_UNKNOWN_COMPONENT: "/docs/configuration/customization",
|
|
61
67
|
BLUME_UNKNOWN_ICON: DOCS_CONTENT_NAVIGATION,
|
|
68
|
+
BLUME_WIKILINK_AMBIGUOUS: DOCS_CONTENT_SOURCES,
|
|
69
|
+
BLUME_WIKILINK_UNRESOLVED: DOCS_CONTENT_SOURCES,
|
|
62
70
|
})
|
|
63
71
|
);
|
|
64
72
|
|
package/src/core/frontmatter.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import baseMatter from "gray-matter";
|
|
2
2
|
import { dump, load } from "js-yaml";
|
|
3
3
|
|
|
4
|
+
import { YAML_SCHEMA } from "./yaml.ts";
|
|
5
|
+
|
|
4
6
|
// gray-matter@4 binds js-yaml 3's `safeLoad`/`safeDump` as its default YAML
|
|
5
|
-
// engine. In a workspace that
|
|
6
|
-
//
|
|
7
|
-
// js-yaml 4." Every
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// install resolves for gray-matter.
|
|
7
|
+
// engine. In a workspace that resolves a newer js-yaml for gray-matter — v4
|
|
8
|
+
// replaced those functions with throwing stubs, v5 dropped them — parsing
|
|
9
|
+
// front matter throws "Function yaml.safeLoad is removed in js-yaml 4." Every
|
|
10
|
+
// Blume front-matter call routes through this `matter` wrapper, which supplies
|
|
11
|
+
// an explicit engine built on Blume's own `load`/`dump`, so Blume is immune to
|
|
12
|
+
// whichever version the consumer's install resolves for gray-matter.
|
|
11
13
|
|
|
12
14
|
type MatterInput = Parameters<typeof baseMatter>[0];
|
|
13
15
|
type MatterOptions = Parameters<typeof baseMatter>[1];
|
|
@@ -22,7 +24,8 @@ const yamlEngine = {
|
|
|
22
24
|
// block is a YAML mapping, and js-yaml returns a scalar only for degenerate
|
|
23
25
|
// input, which gray-matter treats the same way its bundled engine's output
|
|
24
26
|
// is treated.
|
|
25
|
-
parse: (input: string): object =>
|
|
27
|
+
parse: (input: string): object =>
|
|
28
|
+
(load(input, { schema: YAML_SCHEMA }) ?? {}) as object,
|
|
26
29
|
stringify: (data: FrontMatterData): string => dump(data),
|
|
27
30
|
};
|
|
28
31
|
|
|
@@ -109,11 +112,20 @@ const matter = Object.assign(
|
|
|
109
112
|
{
|
|
110
113
|
read: (filepath: ReadArgs[0], options?: ReadArgs[1]) =>
|
|
111
114
|
baseMatter.read(filepath, withYamlEngine(options)),
|
|
115
|
+
// A string is the body to emit, not a document to parse: gray-matter
|
|
116
|
+
// would otherwise run `matter()` over it, and a body that opens with a
|
|
117
|
+
// `---` divider reads as a second front matter block — js-yaml either
|
|
118
|
+
// throws or swallows the opening paragraph into the YAML header.
|
|
112
119
|
stringify: (
|
|
113
120
|
file: StringifyArgs[0],
|
|
114
121
|
data: StringifyArgs[1],
|
|
115
122
|
options?: StringifyArgs[2]
|
|
116
|
-
): string =>
|
|
123
|
+
): string =>
|
|
124
|
+
baseMatter.stringify(
|
|
125
|
+
isStringInput(file) ? { content: file } : file,
|
|
126
|
+
data,
|
|
127
|
+
withYamlEngine(options)
|
|
128
|
+
),
|
|
117
129
|
}
|
|
118
130
|
);
|
|
119
131
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository URL derivation for `config.github`.
|
|
3
|
+
*
|
|
4
|
+
* Every repo-derived link — the header mark, per-page edit links, the agent
|
|
5
|
+
* manifest's `repository` — is built from `host`, which defaults to github.com
|
|
6
|
+
* but accepts a GitHub Enterprise origin so self-hosted and data-resident
|
|
7
|
+
* installations get working links instead of ones pointing at the public site.
|
|
8
|
+
*
|
|
9
|
+
* The REST base is derived from the host unless `api` is set explicitly, since
|
|
10
|
+
* the two Enterprise flavors expose it differently: Enterprise Cloud with data
|
|
11
|
+
* residency serves it from an `api.` subdomain of the same host, Enterprise
|
|
12
|
+
* Server from `/api/v3` on the host itself.
|
|
13
|
+
*
|
|
14
|
+
* `host` arrives as a bare origin and `api` as an origin plus path, both with
|
|
15
|
+
* no trailing slash — the config schema normalizes them — so nothing here
|
|
16
|
+
* re-trims user input.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import type { ResolvedConfig } from "./schema.ts";
|
|
20
|
+
|
|
21
|
+
/** The resolved `github` block, which the config leaves optional. */
|
|
22
|
+
export type GithubTarget = NonNullable<ResolvedConfig["github"]>;
|
|
23
|
+
|
|
24
|
+
/** The public instance every `host` defaults to. */
|
|
25
|
+
export const PUBLIC_HOST_URL = "https://github.com";
|
|
26
|
+
/** The public instance's REST base. */
|
|
27
|
+
export const PUBLIC_API_URL = "https://api.github.com";
|
|
28
|
+
const PUBLIC_HOSTNAME = "github.com";
|
|
29
|
+
/** Enterprise Cloud with data residency: `<tenant>.ghe.com`. */
|
|
30
|
+
const DATA_RESIDENCY_SUFFIX = ".ghe.com";
|
|
31
|
+
|
|
32
|
+
/** `owner/repo` — the bare slug, with no origin attached. */
|
|
33
|
+
const repoSlug = (github: Pick<GithubTarget, "owner" | "repo">): string =>
|
|
34
|
+
`${github.owner}/${github.repo}`;
|
|
35
|
+
|
|
36
|
+
/** The repository's web URL, e.g. `https://github.com/acme/docs`. */
|
|
37
|
+
export const repoUrl = (
|
|
38
|
+
github: Pick<GithubTarget, "host" | "owner" | "repo">
|
|
39
|
+
): string => `${github.host}/${repoSlug(github)}`;
|
|
40
|
+
|
|
41
|
+
/** The base every edit link extends with a repo-relative path. */
|
|
42
|
+
export const editBaseUrl = (
|
|
43
|
+
github: Pick<GithubTarget, "branch" | "host" | "owner" | "repo">
|
|
44
|
+
): string => `${repoUrl(github)}/edit/${github.branch}`;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The REST API base for `host`. An explicit `api` always wins; otherwise
|
|
48
|
+
* github.com (and any subdomain of it, `www.` say) maps to api.github.com, a
|
|
49
|
+
* data-residency tenant to its `api.` subdomain, and anything else is treated
|
|
50
|
+
* as Enterprise Server (`/api/v3`).
|
|
51
|
+
*/
|
|
52
|
+
export const apiUrl = (github: Pick<GithubTarget, "api" | "host">): string => {
|
|
53
|
+
if (github.api) {
|
|
54
|
+
return github.api;
|
|
55
|
+
}
|
|
56
|
+
const url = new URL(github.host);
|
|
57
|
+
const { hostname } = url;
|
|
58
|
+
if (
|
|
59
|
+
hostname === PUBLIC_HOSTNAME ||
|
|
60
|
+
hostname.endsWith(`.${PUBLIC_HOSTNAME}`)
|
|
61
|
+
) {
|
|
62
|
+
return PUBLIC_API_URL;
|
|
63
|
+
}
|
|
64
|
+
if (hostname.endsWith(DATA_RESIDENCY_SUFFIX)) {
|
|
65
|
+
// Rebuilt through the URL so a non-default port survives alongside the
|
|
66
|
+
// subdomain rather than being dropped from the API base alone.
|
|
67
|
+
url.hostname = `api.${hostname}`;
|
|
68
|
+
return url.origin;
|
|
69
|
+
}
|
|
70
|
+
return `${github.host}/api/v3`;
|
|
71
|
+
};
|
package/src/core/graph.ts
CHANGED
|
@@ -142,8 +142,13 @@ const buildLocaleNavigation = (
|
|
|
142
142
|
// header tab points to its in-locale route (e.g. `/docs` -> `/fr/docs`);
|
|
143
143
|
// external paths pass through. Selectors are left alone: a language
|
|
144
144
|
// selector's items intentionally target specific locales.
|
|
145
|
+
// `//host/path` is protocol-relative — an external URL that happens to start
|
|
146
|
+
// with a slash, so it must not pick up a locale prefix. `withBasePath` draws
|
|
147
|
+
// the same line for the same reason.
|
|
145
148
|
const localizePath = (path: string): string =>
|
|
146
|
-
path.startsWith("/")
|
|
149
|
+
path.startsWith("/") && !path.startsWith("//")
|
|
150
|
+
? localizeRoute(path, code, i18n)
|
|
151
|
+
: path;
|
|
147
152
|
const tabs = resolveTabLabels(
|
|
148
153
|
options.navigation.tabs,
|
|
149
154
|
code,
|
|
@@ -178,17 +183,22 @@ const buildLocaleNavigation = (
|
|
|
178
183
|
// version dir is hoisted in front (`v1.0/fr`), matching `discoverFolderMeta`.
|
|
179
184
|
const localeDir =
|
|
180
185
|
i18n.parser === "dir" && code !== i18n.defaultLocale ? code : "";
|
|
186
|
+
// Internal featured and header hrefs are localized like tab paths — a pinned
|
|
187
|
+
// `/changelog` link rendered on `/fr/…` pages must stay inside the reader's
|
|
188
|
+
// locale, not kick them back to the default one.
|
|
189
|
+
const localizeHref = <T extends { href: string }>(item: T): T => ({
|
|
190
|
+
...item,
|
|
191
|
+
href: localizePath(item.href),
|
|
192
|
+
});
|
|
193
|
+
const { actions, cta, featured } = options.navigation;
|
|
194
|
+
|
|
181
195
|
return buildNavigation(localePages, {
|
|
196
|
+
actions: actions?.map(localizeHref),
|
|
182
197
|
basePath: options.basePath ?? "",
|
|
198
|
+
cta: cta ? localizeHref(cta) : null,
|
|
183
199
|
diagnostics,
|
|
184
200
|
display: options.navigation.sidebar.display,
|
|
185
|
-
|
|
186
|
-
// `/changelog` link rendered on `/fr/…` pages must stay inside the
|
|
187
|
-
// reader's locale, not kick them back to the default one.
|
|
188
|
-
featured: options.navigation.featured?.map((link) => ({
|
|
189
|
-
...link,
|
|
190
|
-
href: localizePath(link.href),
|
|
191
|
-
})),
|
|
201
|
+
featured: featured?.map(localizeHref),
|
|
192
202
|
folderMeta: options.folderMeta,
|
|
193
203
|
// The localized tree root ("/" for the hidden default, "/fr" otherwise;
|
|
194
204
|
// "/fr/v1.0" inside a snapshot): the tab pointing here spans the whole
|
|
@@ -283,7 +293,9 @@ const buildVersionNavigation = (
|
|
|
283
293
|
}
|
|
284
294
|
return {
|
|
285
295
|
"": buildNavigation(versionPages, {
|
|
296
|
+
actions: options.navigation.actions,
|
|
286
297
|
basePath: options.basePath ?? "",
|
|
298
|
+
cta: options.navigation.cta,
|
|
287
299
|
diagnostics,
|
|
288
300
|
display: options.navigation.sidebar.display,
|
|
289
301
|
featured: options.navigation.featured,
|
|
@@ -328,7 +340,9 @@ export const buildContentGraph = (
|
|
|
328
340
|
));
|
|
329
341
|
} else {
|
|
330
342
|
navigation = buildNavigation(currentPages, {
|
|
343
|
+
actions: options.navigation.actions,
|
|
331
344
|
basePath: options.basePath ?? "",
|
|
345
|
+
cta: options.navigation.cta,
|
|
332
346
|
diagnostics,
|
|
333
347
|
display: options.navigation.sidebar.display,
|
|
334
348
|
featured: options.navigation.featured,
|