@umami/shiso 1.10.0 → 1.12.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/bin/shiso.mjs +20 -1
- package/dist/chunks/App.js +363 -29
- package/dist/chunks/docs.js +33 -41
- package/dist/entry-client.js +1 -1
- package/dist/entry-server.js +30 -2
- package/docs.schema.json +90 -0
- package/mdx.config.ts +13 -97
- package/package.json +5 -4
- package/scripts/build-runtime.mjs +1 -0
- package/scripts/check-content.mjs +358 -0
- package/scripts/expand-navigation-globs.mjs +208 -0
- package/scripts/expand-openapi-navigation.mjs +94 -0
- package/scripts/generate-openapi.mjs +117 -0
- package/scripts/generate-search-index.mjs +31 -1
- package/scripts/lib/openapi.mjs +653 -0
- package/scripts/load-docs-config.mjs +52 -6
- package/scripts/load-shiso-config.mjs +45 -3
- package/scripts/prerender.mjs +83 -3
- package/scripts/vite-docs-config.mjs +27 -6
- package/src/App.tsx +0 -1
- package/src/components/CodeBlock.tsx +73 -9
- package/src/components/DocContent.tsx +24 -3
- package/src/components/Docs.tsx +6 -1
- package/src/components/OpenApiOperation.tsx +197 -0
- package/src/components/SideNav.tsx +8 -2
- package/src/components/docs/Card.tsx +1 -1
- package/src/components/docs/CodeGroup.tsx +6 -2
- package/src/components/docs/Expandable.tsx +1 -1
- package/src/components/docs/PropertiesTable.tsx +12 -25
- package/src/components/docs/styles.ts +7 -4
- package/src/entry-server.tsx +50 -0
- package/src/lib/code-blocks.ts +18 -0
- package/src/lib/code-meta.ts +87 -0
- package/src/lib/docs-config.ts +4 -1
- package/src/lib/openapi.generated.ts +4 -0
- package/src/lib/openapi.ts +63 -0
- package/src/lib/rehype-shiki.ts +196 -0
- package/src/lib/site-model.ts +2 -0
- package/src/lib/types.ts +116 -2
- package/src/styles/global.css +75 -76
- package/types/config.d.ts +11 -4
- package/vite.config.ts +49 -3
- package/CHANGELOG.md +0 -171
package/dist/chunks/docs.js
CHANGED
|
@@ -9832,7 +9832,8 @@ const styles = {
|
|
|
9832
9832
|
accordionItem: "",
|
|
9833
9833
|
accordionTrigger: "text-foreground",
|
|
9834
9834
|
accordionContent: "text-muted-foreground [&_p]:mt-0 [&_p:last-child]:mb-0",
|
|
9835
|
-
expandableTrigger: "items-center
|
|
9835
|
+
expandableTrigger: "items-center py-3 text-sm font-normal text-foreground hover:no-underline",
|
|
9836
|
+
expandableContent: "pl-6",
|
|
9836
9837
|
callout: "my-4 flex items-start gap-3 rounded-lg border px-3 py-2.5 text-sm leading-6",
|
|
9837
9838
|
calloutIcon: "flex h-6 w-5 shrink-0 items-center justify-center [&_svg]:block [&_svg]:size-4",
|
|
9838
9839
|
calloutBody: "flex min-w-0 flex-1 flex-col gap-[0.35rem] [&>:first-child]:mt-0 [&>:last-child]:mb-0 [&_:where(p,ul,ol)]:my-[0.35rem] [&>:where(p,ul,ol):first-child]:mt-0 [&>:where(p,ul,ol):last-child]:mb-0",
|
|
@@ -9844,7 +9845,8 @@ const styles = {
|
|
|
9844
9845
|
tip: "border-green-300 bg-green-50 text-green-900 dark:border-green-400/40 dark:bg-green-400/10 dark:text-green-300",
|
|
9845
9846
|
check: "border-emerald-300 bg-emerald-50 text-emerald-900 dark:border-emerald-400/40 dark:bg-emerald-400/10 dark:text-emerald-300",
|
|
9846
9847
|
danger: "border-destructive/40 bg-destructive/10 text-destructive",
|
|
9847
|
-
card: "block h-full gap-0 rounded-lg border border-border
|
|
9848
|
+
card: "block h-full gap-0 rounded-lg border border-border p-4 text-sm ring-0 hover:border-primary",
|
|
9849
|
+
cardPlain: "bg-card",
|
|
9848
9850
|
cardHorizontal: "[&_[data-slot=card-inner]]:items-center [&_[data-slot=card-main]]:flex-row [&_[data-slot=card-main]]:items-center [&_[data-slot=card-main]]:gap-3 [&_[data-slot=card-body]]:m-0 [&_[data-slot=card-header]]:flex-row [&_[data-slot=card-header]]:items-center [&_[data-slot=card-header]]:gap-2",
|
|
9849
9851
|
cardTyped: "[&_[data-slot=card-title]]:text-inherit [&_[data-slot=card-body]]:text-inherit [&_[data-slot=card-cta]]:text-inherit [&_[data-slot=card-arrow]]:text-inherit",
|
|
9850
9852
|
cardImageLayout: "p-0 [&_[data-slot=card-inner]]:p-6",
|
|
@@ -9853,7 +9855,7 @@ const styles = {
|
|
|
9853
9855
|
cardMain: "flex min-w-0 flex-col gap-2",
|
|
9854
9856
|
cardHeader: "flex flex-col items-start gap-3",
|
|
9855
9857
|
cardIcon: "inline-flex shrink-0 items-center justify-center [&_img]:size-6 [&_svg]:size-6",
|
|
9856
|
-
cardTitle: "text-
|
|
9858
|
+
cardTitle: "text-sm font-semibold text-foreground",
|
|
9857
9859
|
cardBody: "text-muted-foreground [&>:first-child]:mt-0 [&>:last-child]:mb-0",
|
|
9858
9860
|
cardCta: "flex shrink-0 items-center gap-[0.35rem] text-[0.9rem] font-medium text-muted-foreground",
|
|
9859
9861
|
cardArrow: "shrink-0 text-muted-foreground",
|
|
@@ -10377,7 +10379,7 @@ function DocsCardContent({ title, icon, color, img, cta, arrow, type, children }
|
|
|
10377
10379
|
function Card({ title, href, icon, color, img, cta, horizontal, arrow, type, children }) {
|
|
10378
10380
|
const external = typeof href === "string" && /^https?:\/\//i.test(href);
|
|
10379
10381
|
const showArrow = arrow ?? external;
|
|
10380
|
-
const className = `${styles.card} ${type ? `${styles.cardTyped} ${styles[type]} ${CARD_TYPE_HOVER[type]}` :
|
|
10382
|
+
const className = `${styles.card} ${type ? `${styles.cardTyped} ${styles[type]} ${CARD_TYPE_HOVER[type]}` : styles.cardPlain} ${horizontal ? styles.cardHorizontal : ""} ${img ? styles.cardImageLayout : ""}`;
|
|
10381
10383
|
const content = /* @__PURE__ */ jsx(Card$1, {
|
|
10382
10384
|
className,
|
|
10383
10385
|
children: /* @__PURE__ */ jsx(DocsCardContent, {
|
|
@@ -11298,13 +11300,13 @@ function CodeGroup({ children }) {
|
|
|
11298
11300
|
const selected = blocks.some((block) => block.id === selectedKey) ? selectedKey : blocks[0]?.id;
|
|
11299
11301
|
if (!blocks.length) return null;
|
|
11300
11302
|
if (blocks.length === 1) return /* @__PURE__ */ jsx("div", {
|
|
11301
|
-
className: styles.tabs
|
|
11303
|
+
className: `${styles.tabs} [&_[data-slot=code-block-header]]:hidden`,
|
|
11302
11304
|
children: blocks[0].content
|
|
11303
11305
|
});
|
|
11304
11306
|
return /* @__PURE__ */ jsxs(Tabs$1, {
|
|
11305
11307
|
value: selected,
|
|
11306
11308
|
onValueChange: setSelectedKey,
|
|
11307
|
-
className: "my-4 gap-0 overflow-hidden rounded-lg bg-
|
|
11309
|
+
className: "my-4 gap-0 overflow-hidden rounded-lg bg-card [&_[data-slot=code-block]]:my-0 [&_[data-slot=code-block]]:rounded-none [&_[data-slot=code-block]]:border-0 [&_[data-slot=code-block]]:bg-transparent [&_[data-slot=code-block-header]]:hidden",
|
|
11308
11310
|
children: [/* @__PURE__ */ jsx(TabsList, {
|
|
11309
11311
|
variant: "line",
|
|
11310
11312
|
className: "h-9 w-full justify-start gap-5 overflow-x-auto overflow-y-hidden rounded-none px-3 py-0 shadow-[inset_0_-1px_0_var(--border)] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
@@ -11541,7 +11543,7 @@ function Expandable({ title, children, defaultOpen = false }) {
|
|
|
11541
11543
|
className: `${styles.expandableTrigger} group/collapsible-trigger flex w-full justify-start gap-2 text-left outline-none focus-visible:ring-3 focus-visible:ring-ring/50`,
|
|
11542
11544
|
children: [/* @__PURE__ */ jsx(ChevronRight, { className: "size-4 shrink-0 text-muted-foreground transition-transform group-aria-expanded/collapsible-trigger:rotate-90" }), title]
|
|
11543
11545
|
}), /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("div", {
|
|
11544
|
-
className: styles.accordionContent
|
|
11546
|
+
className: `${styles.accordionContent} ${styles.expandableContent}`,
|
|
11545
11547
|
children
|
|
11546
11548
|
}) })]
|
|
11547
11549
|
})
|
|
@@ -11725,53 +11727,43 @@ function PropertiesTable({ children }) {
|
|
|
11725
11727
|
const rows = toElementArray(children);
|
|
11726
11728
|
if (!rows.length) return null;
|
|
11727
11729
|
return /* @__PURE__ */ jsx("div", {
|
|
11728
|
-
className: "my-4 overflow-x-auto
|
|
11730
|
+
className: "my-4 overflow-x-auto",
|
|
11729
11731
|
children: /* @__PURE__ */ jsxs("table", {
|
|
11730
|
-
className: "m-0 min-w-[40rem] table-fixed
|
|
11732
|
+
className: "m-0 min-w-[40rem] table-fixed",
|
|
11731
11733
|
children: [/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
11732
11734
|
/* @__PURE__ */ jsx("th", {
|
|
11733
|
-
className: "w-1/5
|
|
11735
|
+
className: "w-1/5",
|
|
11734
11736
|
children: "Name"
|
|
11735
11737
|
}),
|
|
11736
11738
|
/* @__PURE__ */ jsx("th", {
|
|
11737
|
-
className: "w-1/4
|
|
11739
|
+
className: "w-1/4",
|
|
11738
11740
|
children: "Type"
|
|
11739
11741
|
}),
|
|
11740
|
-
/* @__PURE__ */ jsx("th", {
|
|
11741
|
-
|
|
11742
|
-
children: "Description"
|
|
11743
|
-
})
|
|
11744
|
-
] }) }), /* @__PURE__ */ jsx("tbody", { children: rows.map((row, index) => {
|
|
11742
|
+
/* @__PURE__ */ jsx("th", { children: "Description" })
|
|
11743
|
+
] }) }), /* @__PURE__ */ jsx("tbody", { children: rows.map((row) => {
|
|
11745
11744
|
const { name, type, required, deprecated, children: description } = row.props;
|
|
11746
11745
|
const defaultValue = displayValue(row.props.default);
|
|
11747
|
-
const borderClass = index === rows.length - 1 ? "border-b-0" : "border-b";
|
|
11748
11746
|
return /* @__PURE__ */ jsxs("tr", { children: [
|
|
11749
|
-
/* @__PURE__ */ jsx("td", {
|
|
11750
|
-
className:
|
|
11751
|
-
children:
|
|
11752
|
-
|
|
11753
|
-
|
|
11754
|
-
|
|
11755
|
-
|
|
11756
|
-
|
|
11757
|
-
|
|
11758
|
-
|
|
11759
|
-
|
|
11760
|
-
deprecated
|
|
11761
|
-
|
|
11762
|
-
|
|
11763
|
-
|
|
11764
|
-
|
|
11765
|
-
})
|
|
11766
|
-
}),
|
|
11767
|
-
/* @__PURE__ */ jsx("td", {
|
|
11768
|
-
className: `${borderClass} border-x-0 border-t-0 border-border px-0 py-2 pr-6 align-top text-sm text-foreground`,
|
|
11769
|
-
children: displayValue(type)
|
|
11770
|
-
}),
|
|
11747
|
+
/* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsxs("span", {
|
|
11748
|
+
className: "inline-flex flex-wrap items-center gap-2",
|
|
11749
|
+
children: [
|
|
11750
|
+
name,
|
|
11751
|
+
required ? /* @__PURE__ */ jsx(Badge, {
|
|
11752
|
+
size: "xs",
|
|
11753
|
+
tone: "primary",
|
|
11754
|
+
children: "required"
|
|
11755
|
+
}) : null,
|
|
11756
|
+
deprecated ? /* @__PURE__ */ jsx(Badge, {
|
|
11757
|
+
size: "xs",
|
|
11758
|
+
children: "deprecated"
|
|
11759
|
+
}) : null
|
|
11760
|
+
]
|
|
11761
|
+
}) }),
|
|
11762
|
+
/* @__PURE__ */ jsx("td", { children: displayValue(type) }),
|
|
11771
11763
|
/* @__PURE__ */ jsxs("td", {
|
|
11772
|
-
className:
|
|
11764
|
+
className: "[&_p]:m-0",
|
|
11773
11765
|
children: [description, defaultValue ? /* @__PURE__ */ jsxs("span", {
|
|
11774
|
-
className: "mt-1 block text-
|
|
11766
|
+
className: "mt-1 block text-muted-foreground",
|
|
11775
11767
|
children: ["Default: ", defaultValue]
|
|
11776
11768
|
}) : null]
|
|
11777
11769
|
})
|
package/dist/entry-client.js
CHANGED
package/dist/entry-server.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { hr as ABSOLUTE_URL_REGEX, lr as Router, mr as parsePath, pr as createPath } from "./chunks/docs.js";
|
|
2
|
-
import { a as docsSite, c as getSeo, d as
|
|
2
|
+
import { a as docsSite, c as getSeo, d as standalonePages, f as getDocModule, g as toAbsoluteUrl, h as BASE_URL, i as docsHomeUrl, l as siteConfig, m as getScopeForPage, n as buildHead, o as getLocaleByPathname, p as getLastModified, r as renderHeadToString, s as getRedirects, t as App, u as siteName } from "./chunks/App.js";
|
|
3
3
|
import * as React$1 from "react";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
import { renderToString } from "react-dom/server";
|
|
@@ -107,6 +107,33 @@ function getMarkdownPages() {
|
|
|
107
107
|
filePath: page.filePath
|
|
108
108
|
}))];
|
|
109
109
|
}
|
|
110
|
+
/** Navigable Markdown pages used to generate llms.txt and llms-full.txt. */
|
|
111
|
+
function getLlmsPages() {
|
|
112
|
+
const { indexing } = getSeo();
|
|
113
|
+
const pages = [];
|
|
114
|
+
for (const page of docsSite.pages) {
|
|
115
|
+
const doc = getDocModule(page.filePath);
|
|
116
|
+
if (doc?.frontmatter?.noindex === true || (page.hidden || getScopeForPage(docsSite, page).hidden) && indexing !== "all") continue;
|
|
117
|
+
pages.push({
|
|
118
|
+
route: page.url,
|
|
119
|
+
filePath: page.filePath,
|
|
120
|
+
title: doc?.frontmatter?.title || page.label,
|
|
121
|
+
description: doc?.frontmatter?.description
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
for (const page of standalonePages) {
|
|
125
|
+
if (page.filePath.endsWith(".tsx")) continue;
|
|
126
|
+
const doc = getDocModule(page.filePath);
|
|
127
|
+
if (doc?.frontmatter?.noindex === true) continue;
|
|
128
|
+
pages.push({
|
|
129
|
+
route: page.path,
|
|
130
|
+
filePath: page.filePath,
|
|
131
|
+
title: doc?.frontmatter?.title || page.title || page.path,
|
|
132
|
+
description: doc?.frontmatter?.description
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return pages;
|
|
136
|
+
}
|
|
110
137
|
/**
|
|
111
138
|
* Absolute URLs for the sitemap, honoring `seo.indexing` and per-page
|
|
112
139
|
* noindex. Empty when the shiso.config `siteUrl` is not configured, since a sitemap
|
|
@@ -145,6 +172,7 @@ function render(url) {
|
|
|
145
172
|
htmlAttrs: getLocaleByPathname(url)
|
|
146
173
|
};
|
|
147
174
|
}
|
|
175
|
+
const siteDescription = siteConfig.description;
|
|
148
176
|
|
|
149
177
|
//#endregion
|
|
150
|
-
export { docsHomeUrl, getMarkdownPages, getRedirects, getRoutes, getSitemapEntries, render, siteName };
|
|
178
|
+
export { docsHomeUrl, getLlmsPages, getMarkdownPages, getRedirects, getRoutes, getSitemapEntries, render, siteDescription, siteName };
|
package/docs.schema.json
CHANGED
|
@@ -172,6 +172,37 @@
|
|
|
172
172
|
],
|
|
173
173
|
"description": "Page eyebrow style: the section name (default) or the full navigation path.",
|
|
174
174
|
"default": "section"
|
|
175
|
+
},
|
|
176
|
+
"codeBlocks": {
|
|
177
|
+
"type": "object",
|
|
178
|
+
"description": "Fenced code block defaults: line numbers and the Shiki light/dark themes.",
|
|
179
|
+
"additionalProperties": false,
|
|
180
|
+
"properties": {
|
|
181
|
+
"$ref": { "$ref": "#/definitions/configRef" },
|
|
182
|
+
"lineNumbers": {
|
|
183
|
+
"allOf": [{ "$ref": "#/definitions/booleanValue" }],
|
|
184
|
+
"description": "Show line numbers on every block. Override per block with showLineNumbers or hideLineNumbers in the fence meta.",
|
|
185
|
+
"default": false
|
|
186
|
+
},
|
|
187
|
+
"theme": {
|
|
188
|
+
"type": "object",
|
|
189
|
+
"description": "Bundled Shiki theme names for each color mode (https://shiki.style/themes).",
|
|
190
|
+
"additionalProperties": false,
|
|
191
|
+
"properties": {
|
|
192
|
+
"$ref": { "$ref": "#/definitions/configRef" },
|
|
193
|
+
"light": {
|
|
194
|
+
"allOf": [{ "$ref": "#/definitions/nonEmptyStringValue" }],
|
|
195
|
+
"description": "Theme used in light mode.",
|
|
196
|
+
"default": "github-light"
|
|
197
|
+
},
|
|
198
|
+
"dark": {
|
|
199
|
+
"allOf": [{ "$ref": "#/definitions/nonEmptyStringValue" }],
|
|
200
|
+
"description": "Theme used in dark mode.",
|
|
201
|
+
"default": "github-dark"
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
175
206
|
}
|
|
176
207
|
}
|
|
177
208
|
},
|
|
@@ -567,6 +598,24 @@
|
|
|
567
598
|
}
|
|
568
599
|
}
|
|
569
600
|
},
|
|
601
|
+
"api": {
|
|
602
|
+
"type": "object",
|
|
603
|
+
"description": "API reference settings: the OpenAPI spec powering openapi frontmatter pages.",
|
|
604
|
+
"anyOf": [{ "required": ["$ref"] }, { "required": ["spec"] }],
|
|
605
|
+
"additionalProperties": false,
|
|
606
|
+
"properties": {
|
|
607
|
+
"$ref": { "$ref": "#/definitions/configRef" },
|
|
608
|
+
"spec": {
|
|
609
|
+
"allOf": [{ "$ref": "#/definitions/nonEmptyStringValue" }],
|
|
610
|
+
"description": "Path to a local OpenAPI 3.0 or 3.1 spec (JSON or YAML), relative to the project root."
|
|
611
|
+
},
|
|
612
|
+
"directory": {
|
|
613
|
+
"allOf": [{ "$ref": "#/definitions/nonEmptyStringValue" }],
|
|
614
|
+
"description": "Folder inside the content directory for generated endpoint pages.",
|
|
615
|
+
"default": "api-reference"
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
},
|
|
570
619
|
"errors": {
|
|
571
620
|
"type": "object",
|
|
572
621
|
"description": "Error handling settings.",
|
|
@@ -712,6 +761,8 @@
|
|
|
712
761
|
"description": "Page reference relative to the content directory, without extension (e.g. \"components/tabs\")."
|
|
713
762
|
},
|
|
714
763
|
{ "$ref": "#/definitions/pageObject" },
|
|
764
|
+
{ "$ref": "#/definitions/globItem" },
|
|
765
|
+
{ "$ref": "#/definitions/openapiItem" },
|
|
715
766
|
{ "$ref": "#/definitions/linkItem" },
|
|
716
767
|
{ "$ref": "#/definitions/group" }
|
|
717
768
|
]
|
|
@@ -736,12 +787,51 @@
|
|
|
736
787
|
},
|
|
737
788
|
"icon": { "allOf": [{ "$ref": "#/definitions/stringValue" }], "description": "Icon name shown beside the label." },
|
|
738
789
|
"tag": { "allOf": [{ "$ref": "#/definitions/stringValue" }], "description": "Short label shown after the page name." },
|
|
790
|
+
"method": {
|
|
791
|
+
"anyOf": [
|
|
792
|
+
{ "enum": ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS", "TRACE"] },
|
|
793
|
+
{ "$ref": "#/definitions/configRefValue" }
|
|
794
|
+
],
|
|
795
|
+
"description": "HTTP method badge shown after the page name on API reference pages."
|
|
796
|
+
},
|
|
739
797
|
"hidden": {
|
|
740
798
|
"allOf": [{ "$ref": "#/definitions/booleanValue" }],
|
|
741
799
|
"description": "Hide from the sidebar and search. The page is still built and reachable by URL."
|
|
742
800
|
}
|
|
743
801
|
}
|
|
744
802
|
},
|
|
803
|
+
"globItem": {
|
|
804
|
+
"type": "object",
|
|
805
|
+
"required": ["glob"],
|
|
806
|
+
"additionalProperties": false,
|
|
807
|
+
"properties": {
|
|
808
|
+
"glob": {
|
|
809
|
+
"allOf": [{ "$ref": "#/definitions/nonEmptyStringValue" }],
|
|
810
|
+
"description": "Glob relative to contentDir. Matching Markdown and MDX files are expanded into page entries."
|
|
811
|
+
},
|
|
812
|
+
"exclude": {
|
|
813
|
+
"anyOf": [
|
|
814
|
+
{
|
|
815
|
+
"type": "array",
|
|
816
|
+
"items": { "$ref": "#/definitions/nonEmptyStringValue" }
|
|
817
|
+
},
|
|
818
|
+
{ "$ref": "#/definitions/configRefValue" }
|
|
819
|
+
],
|
|
820
|
+
"description": "Optional glob patterns to omit from the matches."
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
},
|
|
824
|
+
"openapiItem": {
|
|
825
|
+
"type": "object",
|
|
826
|
+
"required": ["openapi"],
|
|
827
|
+
"additionalProperties": false,
|
|
828
|
+
"properties": {
|
|
829
|
+
"openapi": {
|
|
830
|
+
"anyOf": [{ "type": "boolean" }, { "$ref": "#/definitions/nonEmptyStringValue" }],
|
|
831
|
+
"description": "Expand API endpoints into pages: true for every tag (grouped), or a tag name for that tag's operations. Requires the api.spec setting."
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
},
|
|
745
835
|
"linkItem": {
|
|
746
836
|
"type": "object",
|
|
747
837
|
"description": "An external link in the navigation tree.",
|
package/mdx.config.ts
CHANGED
|
@@ -1,104 +1,19 @@
|
|
|
1
1
|
import mdx from '@mdx-js/rollup';
|
|
2
2
|
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
|
|
3
|
-
import rehypeHighlight from 'rehype-highlight';
|
|
4
3
|
import rehypeSlug from 'rehype-slug';
|
|
5
4
|
import remarkFrontmatter from 'remark-frontmatter';
|
|
6
5
|
import remarkGfm from 'remark-gfm';
|
|
7
6
|
import remarkMdxFrontmatter from 'remark-mdx-frontmatter';
|
|
8
7
|
import type { Plugin } from 'vite';
|
|
9
|
-
import {
|
|
8
|
+
import { resolveCodeBlockConfig } from './src/lib/code-blocks.ts';
|
|
9
|
+
import { type MdNode, toText } from './src/lib/mdast.ts';
|
|
10
|
+
import { rehypeShiki } from './src/lib/rehype-shiki.ts';
|
|
10
11
|
import { remarkToc } from './src/lib/remark-toc.ts';
|
|
12
|
+
import type { MdxConfig, ResolvedCodeBlockConfig } from './src/lib/types.ts';
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return (tree: MdNode) => {
|
|
16
|
-
const visit = (node: MdNode) => {
|
|
17
|
-
if (node.type === 'code' && node.meta?.trim()) {
|
|
18
|
-
const meta = node.meta.trim();
|
|
19
|
-
const titleMatch = meta.match(/(?:^|\s)title=(?:"([^"]+)"|'([^']+)'|([^\s]+))/);
|
|
20
|
-
const title = titleMatch ? titleMatch[1] || titleMatch[2] || titleMatch[3] : meta;
|
|
21
|
-
const hProperties = (node.data?.hProperties || {}) as Record<string, unknown>;
|
|
22
|
-
node.data = {
|
|
23
|
-
...node.data,
|
|
24
|
-
hProperties: { ...hProperties, 'data-title': title },
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
node.children?.forEach(visit);
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
visit(tree);
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function rehypeWrapJsxForHighlighting() {
|
|
36
|
-
return (tree: MdNode) => {
|
|
37
|
-
walkTree(tree, node => {
|
|
38
|
-
if (node.tagName !== 'code') {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const properties = (node.properties || {}) as Record<string, unknown>;
|
|
43
|
-
const className = properties.className;
|
|
44
|
-
const classes = Array.isArray(className) ? className.map(String) : [String(className || '')];
|
|
45
|
-
const source = toText(node);
|
|
46
|
-
|
|
47
|
-
if (!classes.some(value => /\blanguage-(?:jsx|tsx)\b/.test(value))) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (!/^\s*<[A-Z][\w.]*(?:\s|>|\/)/.test(source)) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
properties[SYNTHETIC_FRAGMENT] = true;
|
|
56
|
-
node.properties = properties;
|
|
57
|
-
node.children = [{ type: 'text', value: `<>\n${source}\n</>` }];
|
|
58
|
-
});
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function boundaryText(node: MdNode, fromEnd = false): MdNode | undefined {
|
|
63
|
-
if (node.type === 'text' && typeof node.value === 'string') {
|
|
64
|
-
return node;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const children = fromEnd ? [...(node.children || [])].reverse() : node.children || [];
|
|
68
|
-
for (const child of children) {
|
|
69
|
-
const match = boundaryText(child, fromEnd);
|
|
70
|
-
if (match) {
|
|
71
|
-
return match;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return undefined;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function rehypeRemoveHighlightingFragments() {
|
|
79
|
-
return (tree: MdNode) => {
|
|
80
|
-
walkTree(tree, node => {
|
|
81
|
-
if (node.tagName !== 'code') {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const properties = (node.properties || {}) as Record<string, unknown>;
|
|
86
|
-
if (!properties[SYNTHETIC_FRAGMENT]) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const first = boundaryText(node);
|
|
91
|
-
const last = boundaryText(node, true);
|
|
92
|
-
if (first?.value) {
|
|
93
|
-
first.value = first.value.replace(/^<>\r?\n/, '');
|
|
94
|
-
}
|
|
95
|
-
if (last?.value) {
|
|
96
|
-
last.value = last.value.replace(/\r?\n<\/>$/, '');
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
delete properties[SYNTHETIC_FRAGMENT];
|
|
100
|
-
});
|
|
101
|
-
};
|
|
14
|
+
export interface ShisoMdxOptions extends MdxConfig {
|
|
15
|
+
/** Resolved docs.json `styling.codeBlocks`; defaults apply when omitted. */
|
|
16
|
+
codeBlocks?: ResolvedCodeBlockConfig;
|
|
102
17
|
}
|
|
103
18
|
|
|
104
19
|
function rehypeZoomableImages() {
|
|
@@ -142,7 +57,9 @@ function rehypeZoomableImages() {
|
|
|
142
57
|
* The MDX compilation pipeline, shared by the app build and the test runner so
|
|
143
58
|
* tests exercise the same transforms the site ships with.
|
|
144
59
|
*/
|
|
145
|
-
export function shisoMdx(): Plugin {
|
|
60
|
+
export function shisoMdx(options: ShisoMdxOptions = {}): Plugin {
|
|
61
|
+
const codeBlocks = options.codeBlocks || resolveCodeBlockConfig();
|
|
62
|
+
|
|
146
63
|
return {
|
|
147
64
|
// Must run before vite:react-babel so MDX is compiled to JSX first.
|
|
148
65
|
enforce: 'pre',
|
|
@@ -152,13 +69,12 @@ export function shisoMdx(): Plugin {
|
|
|
152
69
|
remarkFrontmatter,
|
|
153
70
|
remarkMdxFrontmatter,
|
|
154
71
|
remarkGfm,
|
|
155
|
-
|
|
72
|
+
...(options.remarkPlugins || []),
|
|
156
73
|
remarkToc,
|
|
157
74
|
],
|
|
158
75
|
rehypePlugins: [
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
rehypeRemoveHighlightingFragments,
|
|
76
|
+
...(options.rehypePlugins || []),
|
|
77
|
+
[rehypeShiki, codeBlocks],
|
|
162
78
|
rehypeZoomableImages,
|
|
163
79
|
rehypeSlug,
|
|
164
80
|
[
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umami/shiso",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "Open-source documentation framework for Markdown and MDX sites.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
"@fontsource/jetbrains-mono": "^5.2.5",
|
|
73
73
|
"@mdx-js/react": "^3.1.1",
|
|
74
74
|
"@mdx-js/rollup": "^3.1.1",
|
|
75
|
+
"@shikijs/transformers": "^4.4.3",
|
|
75
76
|
"@tailwindcss/vite": "^4.3.3",
|
|
76
77
|
"@vitejs/plugin-react": "^6.0.5",
|
|
77
78
|
"ajv": "^8.20.0",
|
|
@@ -80,24 +81,24 @@
|
|
|
80
81
|
"cmdk": "^1.1.1",
|
|
81
82
|
"estree-util-value-to-estree": "^3.5.0",
|
|
82
83
|
"github-slugger": "^2.0.0",
|
|
83
|
-
"highlight.js": "^11.11.1",
|
|
84
84
|
"jiti": "^2.4.0",
|
|
85
85
|
"lucide-react": "^1.28.0",
|
|
86
86
|
"react-router": "^8.3.0",
|
|
87
87
|
"rehype-autolink-headings": "^7.1.0",
|
|
88
|
-
"rehype-highlight": "^7.0.1",
|
|
89
88
|
"rehype-slug": "^6.0.0",
|
|
90
89
|
"remark-frontmatter": "^5.0.0",
|
|
91
90
|
"remark-gfm": "^4.0.0",
|
|
92
91
|
"remark-mdx": "^3.1.1",
|
|
93
92
|
"remark-mdx-frontmatter": "^5.2.0",
|
|
94
93
|
"remark-parse": "^11.0.0",
|
|
94
|
+
"shiki": "^4.4.3",
|
|
95
95
|
"simple-icons": "^16.28.0",
|
|
96
96
|
"tailwind-merge": "^3.6.0",
|
|
97
97
|
"tailwindcss": "^4.3.3",
|
|
98
98
|
"tw-animate-css": "^1.4.0",
|
|
99
99
|
"unified": "^11.0.5",
|
|
100
|
-
"vite": "^8.2.0"
|
|
100
|
+
"vite": "^8.2.0",
|
|
101
|
+
"yaml": "^2.9.0"
|
|
101
102
|
},
|
|
102
103
|
"optionalDependencies": {
|
|
103
104
|
"pagefind": "^1.4.0"
|
|
@@ -10,6 +10,7 @@ const outputRoot = path.join(packageRoot, 'dist');
|
|
|
10
10
|
const projectModules = new Set([
|
|
11
11
|
'@/generated/last-modified',
|
|
12
12
|
'@/lib/icon-registry.generated',
|
|
13
|
+
'@/lib/openapi.generated',
|
|
13
14
|
'@/lib/search-index.generated',
|
|
14
15
|
'virtual:shiso-docs-config',
|
|
15
16
|
'virtual:shiso-config',
|