livemark 0.23.0 → 0.24.1
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/.agents/skills/change-review/SKILL.md +47 -0
- package/{skills/configuration → .agents/skills/livemark-configuration}/SKILL.md +2 -4
- package/build/actions/changelog/build.d.ts +21 -9
- package/build/actions/changelog/build.js +31 -23
- package/build/actions/changelog/build.unit.js +156 -2
- package/build/actions/config/load.js +1 -1
- package/build/actions/config/load.unit.js +1 -1
- package/build/actions/target/build.js +2 -5
- package/build/commands/build.js +1 -1
- package/build/commands/escape.js +1 -1
- package/build/commands/preview.js +1 -1
- package/build/commands/start.js +1 -1
- package/build/components/Abbr.js +2 -2
- package/build/components/Article.js +2 -2
- package/build/components/BlogIndex.js +2 -4
- package/build/components/Callout.js +2 -2
- package/build/components/ChangelogIndex.js +1 -1
- package/build/components/CodeBlock.js +3 -5
- package/build/components/CodeTabs.js +1 -1
- package/build/components/Columns.js +2 -4
- package/build/components/Content.js +2 -2
- package/build/components/ContentTab.js +1 -1
- package/build/components/ContentTabs.js +1 -1
- package/build/components/DefinitionList.js +1 -1
- package/build/components/FileTree.js +1 -1
- package/build/components/FootnoteRef.js +2 -2
- package/build/components/InlineToc.js +1 -1
- package/build/components/Layout.js +1 -1
- package/build/components/LinkButton.js +2 -2
- package/build/components/Mermaid.js +1 -1
- package/build/components/PackageTabs.js +2 -2
- package/build/components/PageToolbar.js +2 -2
- package/build/components/PrevNext.js +3 -7
- package/build/components/SearchDialog.js +1 -1
- package/build/components/Section.js +2 -2
- package/build/components/SectionHeader.js +2 -2
- package/build/components/Sidebar.js +2 -2
- package/build/components/SidebarArticles.js +2 -2
- package/build/components/SidebarLinks.js +2 -2
- package/build/components/TagIndex.js +2 -4
- package/build/components/Toc.js +1 -1
- package/build/content/article.js +1 -1
- package/build/content-collections.js +6 -7
- package/build/elements/accordion.js +2 -2
- package/build/elements/alert-dialog.js +5 -5
- package/build/elements/alert.js +2 -2
- package/build/elements/aspect-ratio.js +2 -2
- package/build/elements/avatar.d.ts +1 -1
- package/build/elements/avatar.js +3 -3
- package/build/elements/badge.js +2 -2
- package/build/elements/breadcrumb.js +2 -2
- package/build/elements/button-group.d.ts +1 -1
- package/build/elements/button-group.js +3 -3
- package/build/elements/button.js +2 -2
- package/build/elements/calendar.js +5 -5
- package/build/elements/card.js +2 -2
- package/build/elements/carousel.js +2 -2
- package/build/elements/chart.js +5 -15
- package/build/elements/checkbox.js +2 -2
- package/build/elements/collapsible.js +3 -3
- package/build/elements/command.js +2 -2
- package/build/elements/context-menu.js +5 -5
- package/build/elements/dialog.js +2 -2
- package/build/elements/direction.d.ts +1 -1
- package/build/elements/direction.js +2 -2
- package/build/elements/drawer.js +2 -2
- package/build/elements/dropdown-menu.js +3 -3
- package/build/elements/empty.d.ts +1 -1
- package/build/elements/empty.js +3 -3
- package/build/elements/field.js +2 -2
- package/build/elements/hover-card.js +3 -3
- package/build/elements/input-group.js +2 -2
- package/build/elements/input-otp.js +2 -2
- package/build/elements/input.js +2 -2
- package/build/elements/item.js +2 -2
- package/build/elements/kbd.js +2 -2
- package/build/elements/label.js +2 -2
- package/build/elements/menubar.js +2 -2
- package/build/elements/native-select.js +2 -2
- package/build/elements/navigation-menu.js +2 -2
- package/build/elements/pagination.js +3 -3
- package/build/elements/popover.js +2 -2
- package/build/elements/progress.d.ts +1 -1
- package/build/elements/progress.js +3 -3
- package/build/elements/radio-group.js +2 -2
- package/build/elements/resizable.js +3 -3
- package/build/elements/scroll-area.js +2 -2
- package/build/elements/select.js +2 -2
- package/build/elements/separator.js +2 -2
- package/build/elements/sheet.js +2 -2
- package/build/elements/sidebar.js +3 -4
- package/build/elements/skeleton.js +2 -2
- package/build/elements/slider.js +2 -2
- package/build/elements/spinner.js +2 -2
- package/build/elements/switch.js +2 -2
- package/build/elements/table.js +2 -2
- package/build/elements/tabs.js +2 -2
- package/build/elements/textarea.js +2 -2
- package/build/elements/toggle-group.js +2 -2
- package/build/elements/toggle.js +2 -2
- package/build/elements/tooltip.js +2 -2
- package/build/helpers/changelog-source.js +1 -1
- package/build/helpers/dynamic-icon-resolver.js +1 -1
- package/build/helpers/resolve-asset-path.unit.js +1 -1
- package/build/helpers/resolve-base.unit.js +2 -2
- package/build/helpers/resolve-includes.js +2 -2
- package/build/helpers/resolve-includes.unit.js +1 -1
- package/build/helpers/rss.js +2 -4
- package/build/helpers/rss.unit.js +1 -1
- package/build/helpers/section.js +2 -3
- package/build/helpers/section.unit.js +4 -13
- package/build/helpers/toc.unit.js +2 -4
- package/build/plugins/rehype-inline-code.js +2 -2
- package/build/plugins/rehype-task-list-a11y.js +1 -1
- package/build/plugins/remark-abbr.js +2 -4
- package/build/plugins/remark-ansi.js +2 -4
- package/build/plugins/remark-ansi.unit.js +1 -1
- package/build/plugins/remark-badge.js +2 -4
- package/build/plugins/remark-button.unit.js +1 -1
- package/build/plugins/remark-callout.js +1 -1
- package/build/plugins/remark-card.js +1 -1
- package/build/plugins/remark-code-tabs.js +4 -8
- package/build/plugins/remark-columns.js +1 -1
- package/build/plugins/remark-custom-heading-id.unit.js +1 -1
- package/build/plugins/remark-deflist.js +1 -1
- package/build/plugins/remark-details.js +2 -4
- package/build/plugins/remark-filetree.js +1 -1
- package/build/plugins/remark-filetree.unit.js +1 -1
- package/build/plugins/remark-media.js +3 -7
- package/build/plugins/remark-media.unit.js +1 -1
- package/build/plugins/remark-steps.unit.js +1 -1
- package/build/plugins/remark-tab.js +4 -2
- package/build/plugins/remark-tab.unit.js +3 -7
- package/build/plugins/remark-toc.unit.js +1 -1
- package/build/plugins/shiki-icon.js +1 -1
- package/build/plugins/shiki-line-highlight.js +1 -1
- package/build/plugins/vite-livemark.js +1 -1
- package/build/plugins/vite-robots.js +1 -1
- package/build/plugins/vite-robots.unit.js +1 -1
- package/build/routes/$.js +1 -1
- package/build/vite.config.js +3 -8
- package/package.json +17 -19
- package/source/actions/changelog/build.ts +32 -35
- package/source/actions/changelog/build.unit.ts +191 -1
- package/source/actions/config/load.ts +1 -3
- package/source/actions/config/load.unit.ts +2 -7
- package/source/actions/target/build.ts +1 -4
- package/source/commands/build.ts +1 -7
- package/source/commands/escape.ts +3 -8
- package/source/commands/preview.ts +1 -7
- package/source/commands/start.ts +1 -7
- package/source/components/Abbr.tsx +1 -5
- package/source/components/Article.tsx +1 -5
- package/source/components/BlogIndex.tsx +3 -9
- package/source/components/Callout.tsx +2 -7
- package/source/components/ChangelogIndex.tsx +1 -3
- package/source/components/CodeBlock.tsx +4 -14
- package/source/components/CodeTabs.tsx +1 -3
- package/source/components/Columns.tsx +1 -3
- package/source/components/Content.tsx +1 -5
- package/source/components/ContentTab.tsx +1 -4
- package/source/components/ContentTabs.tsx +3 -10
- package/source/components/DefinitionList.tsx +1 -4
- package/source/components/FileTree.tsx +1 -5
- package/source/components/FootnoteRef.tsx +1 -5
- package/source/components/InlineToc.tsx +1 -4
- package/source/components/Layout.tsx +3 -10
- package/source/components/LinkButton.tsx +2 -8
- package/source/components/Mermaid.tsx +1 -3
- package/source/components/PackageTabs.tsx +1 -5
- package/source/components/PageToolbar.tsx +1 -5
- package/source/components/PrevNext.tsx +2 -6
- package/source/components/SearchDialog.tsx +2 -6
- package/source/components/Section.tsx +1 -1
- package/source/components/SectionHeader.tsx +2 -8
- package/source/components/Sidebar.tsx +2 -7
- package/source/components/SidebarArticles.tsx +4 -20
- package/source/components/SidebarLinks.tsx +2 -6
- package/source/components/TagIndex.tsx +3 -9
- package/source/components/Toc.tsx +2 -7
- package/source/content/article.ts +1 -2
- package/source/content-collections.ts +6 -8
- package/source/elements/accordion.tsx +1 -1
- package/source/elements/alert-dialog.tsx +8 -30
- package/source/elements/alert.tsx +2 -5
- package/source/elements/aspect-ratio.tsx +1 -1
- package/source/elements/avatar.tsx +5 -21
- package/source/elements/badge.tsx +3 -5
- package/source/elements/breadcrumb.tsx +4 -14
- package/source/elements/button-group.tsx +2 -7
- package/source/elements/button.tsx +1 -1
- package/source/elements/calendar.tsx +7 -24
- package/source/elements/card.tsx +1 -1
- package/source/elements/carousel.tsx +4 -11
- package/source/elements/chart.tsx +9 -34
- package/source/elements/checkbox.tsx +1 -1
- package/source/elements/collapsible.tsx +2 -6
- package/source/elements/command.tsx +4 -13
- package/source/elements/context-menu.tsx +8 -25
- package/source/elements/dialog.tsx +4 -14
- package/source/elements/direction.tsx +1 -4
- package/source/elements/drawer.tsx +4 -10
- package/source/elements/dropdown-menu.tsx +5 -19
- package/source/elements/empty.tsx +3 -13
- package/source/elements/field.tsx +3 -7
- package/source/elements/hover-card.tsx +2 -4
- package/source/elements/input-group.tsx +15 -28
- package/source/elements/input-otp.tsx +1 -1
- package/source/elements/input.tsx +1 -1
- package/source/elements/item.tsx +4 -13
- package/source/elements/kbd.tsx +1 -1
- package/source/elements/label.tsx +1 -1
- package/source/elements/menubar.tsx +5 -14
- package/source/elements/native-select.tsx +4 -15
- package/source/elements/navigation-menu.tsx +2 -5
- package/source/elements/pagination.tsx +4 -14
- package/source/elements/popover.tsx +2 -5
- package/source/elements/progress.tsx +4 -16
- package/source/elements/radio-group.tsx +1 -1
- package/source/elements/resizable.tsx +4 -12
- package/source/elements/scroll-area.tsx +2 -6
- package/source/elements/select.tsx +4 -14
- package/source/elements/separator.tsx +1 -1
- package/source/elements/sheet.tsx +3 -10
- package/source/elements/sidebar.tsx +7 -25
- package/source/elements/skeleton.tsx +1 -1
- package/source/elements/slider.tsx +1 -1
- package/source/elements/spinner.tsx +1 -1
- package/source/elements/switch.tsx +1 -1
- package/source/elements/table.tsx +4 -13
- package/source/elements/tabs.tsx +1 -1
- package/source/elements/textarea.tsx +1 -1
- package/source/elements/toggle-group.tsx +2 -4
- package/source/elements/toggle.tsx +1 -1
- package/source/elements/tooltip.tsx +3 -10
- package/source/helpers/changelog-source.ts +1 -3
- package/source/helpers/dynamic-icon-resolver.tsx +1 -4
- package/source/helpers/resolve-asset-path.unit.ts +6 -12
- package/source/helpers/resolve-base.unit.ts +1 -2
- package/source/helpers/resolve-includes.ts +2 -8
- package/source/helpers/resolve-includes.unit.ts +9 -36
- package/source/helpers/rss.ts +3 -9
- package/source/helpers/rss.unit.ts +1 -3
- package/source/helpers/section.ts +1 -4
- package/source/helpers/section.unit.ts +5 -18
- package/source/helpers/toc.unit.ts +1 -3
- package/source/plugins/rehype-inline-code.ts +5 -21
- package/source/plugins/rehype-task-list-a11y.ts +1 -2
- package/source/plugins/remark-abbr.ts +1 -3
- package/source/plugins/remark-ansi.ts +2 -5
- package/source/plugins/remark-ansi.unit.ts +6 -18
- package/source/plugins/remark-badge.ts +1 -3
- package/source/plugins/remark-button.unit.ts +3 -9
- package/source/plugins/remark-callout.ts +35 -40
- package/source/plugins/remark-card.ts +25 -29
- package/source/plugins/remark-code-tabs.ts +3 -7
- package/source/plugins/remark-columns.ts +13 -17
- package/source/plugins/remark-custom-heading-id.unit.ts +2 -6
- package/source/plugins/remark-deflist.ts +1 -2
- package/source/plugins/remark-details.ts +28 -34
- package/source/plugins/remark-filetree.ts +28 -34
- package/source/plugins/remark-filetree.unit.ts +1 -4
- package/source/plugins/remark-media.ts +2 -6
- package/source/plugins/remark-media.unit.ts +2 -6
- package/source/plugins/remark-steps.unit.ts +2 -7
- package/source/plugins/remark-tab.ts +26 -30
- package/source/plugins/remark-tab.unit.ts +2 -6
- package/source/plugins/remark-toc.unit.ts +1 -3
- package/source/plugins/shiki-icon.ts +1 -4
- package/source/plugins/shiki-line-highlight.ts +4 -11
- package/source/plugins/vite-livemark.ts +3 -10
- package/source/plugins/vite-robots.ts +1 -6
- package/source/plugins/vite-robots.unit.ts +1 -3
- package/source/routes/$.tsx +1 -3
- package/source/styles/general.css +1 -5
- package/source/vite.config.ts +2 -7
- package/build/utils/style.d.ts +0 -2
- package/build/utils/style.js +0 -6
- package/source/utils/style.ts +0 -6
- /package/{skills/authoring → .agents/skills/livemark-authoring}/SKILL.md +0 -0
- /package/{skills/customization → .agents/skills/livemark-customization}/SKILL.md +0 -0
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import { cn } from "
|
|
1
|
+
import { cn } from "cn"
|
|
2
2
|
|
|
3
3
|
function Table({ className, ...props }: React.ComponentProps<"table">) {
|
|
4
4
|
return (
|
|
5
|
-
<div
|
|
6
|
-
data-slot="table-container"
|
|
7
|
-
className="relative w-full overflow-x-auto"
|
|
8
|
-
>
|
|
5
|
+
<div data-slot="table-container" className="relative w-full overflow-x-auto">
|
|
9
6
|
<table
|
|
10
7
|
data-slot="table"
|
|
11
8
|
className={cn("w-full caption-bottom text-sm", className)}
|
|
@@ -39,10 +36,7 @@ function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
|
|
|
39
36
|
return (
|
|
40
37
|
<tfoot
|
|
41
38
|
data-slot="table-footer"
|
|
42
|
-
className={cn(
|
|
43
|
-
"bg-muted/50 border-t font-medium [&>tr]:last:border-b-0",
|
|
44
|
-
className,
|
|
45
|
-
)}
|
|
39
|
+
className={cn("bg-muted/50 border-t font-medium [&>tr]:last:border-b-0", className)}
|
|
46
40
|
{...props}
|
|
47
41
|
/>
|
|
48
42
|
)
|
|
@@ -87,10 +81,7 @@ function TableCell({ className, ...props }: React.ComponentProps<"td">) {
|
|
|
87
81
|
)
|
|
88
82
|
}
|
|
89
83
|
|
|
90
|
-
function TableCaption({
|
|
91
|
-
className,
|
|
92
|
-
...props
|
|
93
|
-
}: React.ComponentProps<"caption">) {
|
|
84
|
+
function TableCaption({ className, ...props }: React.ComponentProps<"caption">) {
|
|
94
85
|
return (
|
|
95
86
|
<caption
|
|
96
87
|
data-slot="table-caption"
|
package/source/elements/tabs.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import { Toggle as TogglePrimitive } from "@base-ui/react/toggle"
|
|
|
3
3
|
import { ToggleGroup as ToggleGroupPrimitive } from "@base-ui/react/toggle-group"
|
|
4
4
|
import { type VariantProps } from "class-variance-authority"
|
|
5
5
|
|
|
6
|
-
import { cn } from "
|
|
6
|
+
import { cn } from "cn"
|
|
7
7
|
import { toggleVariants } from "./toggle.tsx"
|
|
8
8
|
|
|
9
9
|
const ToggleGroupContext = React.createContext<
|
|
@@ -45,9 +45,7 @@ function ToggleGroup({
|
|
|
45
45
|
)}
|
|
46
46
|
{...props}
|
|
47
47
|
>
|
|
48
|
-
<ToggleGroupContext.Provider
|
|
49
|
-
value={{ variant, size, spacing, orientation }}
|
|
50
|
-
>
|
|
48
|
+
<ToggleGroupContext.Provider value={{ variant, size, spacing, orientation }}>
|
|
51
49
|
{children}
|
|
52
50
|
</ToggleGroupContext.Provider>
|
|
53
51
|
</ToggleGroupPrimitive>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Toggle as TogglePrimitive } from "@base-ui/react/toggle"
|
|
2
2
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
3
3
|
|
|
4
|
-
import { cn } from "
|
|
4
|
+
import { cn } from "cn"
|
|
5
5
|
|
|
6
6
|
const toggleVariants = cva(
|
|
7
7
|
"group/toggle inline-flex items-center justify-center gap-1 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-pressed:bg-muted dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip"
|
|
2
|
-
import { cn } from "
|
|
2
|
+
import { cn } from "cn"
|
|
3
3
|
|
|
4
|
-
function TooltipProvider({
|
|
5
|
-
delay = 0,
|
|
6
|
-
...props
|
|
7
|
-
}: TooltipPrimitive.Provider.Props) {
|
|
4
|
+
function TooltipProvider({ delay = 0, ...props }: TooltipPrimitive.Provider.Props) {
|
|
8
5
|
return (
|
|
9
|
-
<TooltipPrimitive.Provider
|
|
10
|
-
data-slot="tooltip-provider"
|
|
11
|
-
delay={delay}
|
|
12
|
-
{...props}
|
|
13
|
-
/>
|
|
6
|
+
<TooltipPrimitive.Provider data-slot="tooltip-provider" delay={delay} {...props} />
|
|
14
7
|
)
|
|
15
8
|
}
|
|
16
9
|
|
|
@@ -5,9 +5,7 @@ export function isGitHubUrl(source: string) {
|
|
|
5
5
|
|
|
6
6
|
/** Extract `{ owner, repo }` from a GitHub URL. Returns undefined if unparseable */
|
|
7
7
|
export function parseGitHubRepo(source: string) {
|
|
8
|
-
const match = source.match(
|
|
9
|
-
/^(?:https?:\/\/)?(?:www\.)?github\.com\/([^/]+)\/([^/#?]+)/,
|
|
10
|
-
)
|
|
8
|
+
const match = source.match(/^(?:https?:\/\/)?(?:www\.)?github\.com\/([^/]+)\/([^/#?]+)/)
|
|
11
9
|
if (!match) return undefined
|
|
12
10
|
const owner = match[1]
|
|
13
11
|
const repo = match[2]?.replace(/\.git$/, "")
|
|
@@ -8,10 +8,7 @@ function toPascalCase(name: string) {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
/** Resolves a Lucide icon by kebab-case name from the full registry */
|
|
11
|
-
export default function DynamicIconResolver(props: {
|
|
12
|
-
name: string
|
|
13
|
-
className?: string
|
|
14
|
-
}) {
|
|
11
|
+
export default function DynamicIconResolver(props: { name: string; className?: string }) {
|
|
15
12
|
const key = toPascalCase(props.name)
|
|
16
13
|
if (!(key in icons)) return null
|
|
17
14
|
const Icon = icons[key as keyof typeof icons]
|
|
@@ -6,15 +6,11 @@ describe("resolveAssetPath", () => {
|
|
|
6
6
|
const filePath = "/site/docs/page.md"
|
|
7
7
|
|
|
8
8
|
it("should resolve a sibling relative path", () => {
|
|
9
|
-
expect(resolveAssetPath("./logo.png", filePath, root)).toBe(
|
|
10
|
-
"/docs/logo.png",
|
|
11
|
-
)
|
|
9
|
+
expect(resolveAssetPath("./logo.png", filePath, root)).toBe("/docs/logo.png")
|
|
12
10
|
})
|
|
13
11
|
|
|
14
12
|
it("should resolve a parent relative path", () => {
|
|
15
|
-
expect(resolveAssetPath("../assets/x.png", filePath, root)).toBe(
|
|
16
|
-
"/assets/x.png",
|
|
17
|
-
)
|
|
13
|
+
expect(resolveAssetPath("../assets/x.png", filePath, root)).toBe("/assets/x.png")
|
|
18
14
|
})
|
|
19
15
|
|
|
20
16
|
it("should pass through a root-relative url", () => {
|
|
@@ -40,9 +36,7 @@ describe("resolveAssetPath", () => {
|
|
|
40
36
|
})
|
|
41
37
|
|
|
42
38
|
it("should prefix a root-relative url with base", () => {
|
|
43
|
-
expect(resolveAssetPath("/foo.png", filePath, root, "/repo")).toBe(
|
|
44
|
-
"/repo/foo.png",
|
|
45
|
-
)
|
|
39
|
+
expect(resolveAssetPath("/foo.png", filePath, root, "/repo")).toBe("/repo/foo.png")
|
|
46
40
|
})
|
|
47
41
|
|
|
48
42
|
it("should not double-prefix an already-prefixed url", () => {
|
|
@@ -52,8 +46,8 @@ describe("resolveAssetPath", () => {
|
|
|
52
46
|
})
|
|
53
47
|
|
|
54
48
|
it("should not prefix external urls when base is set", () => {
|
|
55
|
-
expect(
|
|
56
|
-
|
|
57
|
-
)
|
|
49
|
+
expect(resolveAssetPath("https://x.com/y.png", filePath, root, "/repo")).toBe(
|
|
50
|
+
"https://x.com/y.png",
|
|
51
|
+
)
|
|
58
52
|
})
|
|
59
53
|
})
|
|
@@ -43,8 +43,7 @@ describe("resolveBase", () => {
|
|
|
43
43
|
})
|
|
44
44
|
|
|
45
45
|
it("should handle a function returning undefined", () => {
|
|
46
|
-
const fn = (cmd: "build" | "serve") =>
|
|
47
|
-
cmd === "serve" ? undefined : "prod"
|
|
46
|
+
const fn = (cmd: "build" | "serve") => (cmd === "serve" ? undefined : "prod")
|
|
48
47
|
expect(resolveBase(fn, "serve")).toBeUndefined()
|
|
49
48
|
expect(resolveBase(fn, "build")).toBe("/prod")
|
|
50
49
|
})
|
|
@@ -76,9 +76,7 @@ function resolveDirective(
|
|
|
76
76
|
const filename = file.split("/").pop()!
|
|
77
77
|
const title = `title="${filename}"`
|
|
78
78
|
const meta = attrs.meta ? ` ${attrs.meta}` : ""
|
|
79
|
-
return (
|
|
80
|
-
"```" + lang + " " + title + meta + "\n" + included.trimEnd() + "\n```"
|
|
81
|
-
)
|
|
79
|
+
return "```" + lang + " " + title + meta + "\n" + included.trimEnd() + "\n```"
|
|
82
80
|
}
|
|
83
81
|
|
|
84
82
|
included = included.replace(FRONTMATTER_RE, "")
|
|
@@ -89,11 +87,7 @@ function resolveDirective(
|
|
|
89
87
|
}
|
|
90
88
|
|
|
91
89
|
/** Resolves ::include{file="..."} directives by replacing them with referenced file contents */
|
|
92
|
-
export function resolveIncludes(
|
|
93
|
-
content: string,
|
|
94
|
-
filePath: string,
|
|
95
|
-
depth = 0,
|
|
96
|
-
): string {
|
|
90
|
+
export function resolveIncludes(content: string, filePath: string, depth = 0): string {
|
|
97
91
|
if (depth > 5) return content
|
|
98
92
|
|
|
99
93
|
const fileDir = dirname(filePath)
|
|
@@ -8,23 +8,14 @@ describe("resolveIncludes", () => {
|
|
|
8
8
|
it("should replace include directive with file content", () => {
|
|
9
9
|
const dir = temporaryDirectory()
|
|
10
10
|
writeFileSync(join(dir, "snippet.md"), "Hello from snippet")
|
|
11
|
-
const result = resolveIncludes(
|
|
12
|
-
'::include{file="snippet.md"}',
|
|
13
|
-
join(dir, "main.md"),
|
|
14
|
-
)
|
|
11
|
+
const result = resolveIncludes('::include{file="snippet.md"}', join(dir, "main.md"))
|
|
15
12
|
expect(result).toBe("Hello from snippet")
|
|
16
13
|
})
|
|
17
14
|
|
|
18
15
|
it("should strip frontmatter from included files", () => {
|
|
19
16
|
const dir = temporaryDirectory()
|
|
20
|
-
writeFileSync(
|
|
21
|
-
|
|
22
|
-
"---\ntitle: Test\n---\nContent here",
|
|
23
|
-
)
|
|
24
|
-
const result = resolveIncludes(
|
|
25
|
-
'::include{file="snippet.md"}',
|
|
26
|
-
join(dir, "main.md"),
|
|
27
|
-
)
|
|
17
|
+
writeFileSync(join(dir, "snippet.md"), "---\ntitle: Test\n---\nContent here")
|
|
18
|
+
const result = resolveIncludes('::include{file="snippet.md"}', join(dir, "main.md"))
|
|
28
19
|
expect(result).toBe("Content here")
|
|
29
20
|
})
|
|
30
21
|
|
|
@@ -39,10 +30,7 @@ describe("resolveIncludes", () => {
|
|
|
39
30
|
})
|
|
40
31
|
|
|
41
32
|
it("should keep directive when file is missing", () => {
|
|
42
|
-
const result = resolveIncludes(
|
|
43
|
-
'::include{file="nonexistent.md"}',
|
|
44
|
-
"/tmp/main.md",
|
|
45
|
-
)
|
|
33
|
+
const result = resolveIncludes('::include{file="nonexistent.md"}', "/tmp/main.md")
|
|
46
34
|
expect(result).toBe('::include{file="nonexistent.md"}')
|
|
47
35
|
})
|
|
48
36
|
|
|
@@ -50,20 +38,14 @@ describe("resolveIncludes", () => {
|
|
|
50
38
|
const dir = temporaryDirectory()
|
|
51
39
|
writeFileSync(join(dir, "inner.md"), "Inner content")
|
|
52
40
|
writeFileSync(join(dir, "outer.md"), '::include{file="inner.md"}')
|
|
53
|
-
const result = resolveIncludes(
|
|
54
|
-
'::include{file="outer.md"}',
|
|
55
|
-
join(dir, "main.md"),
|
|
56
|
-
)
|
|
41
|
+
const result = resolveIncludes('::include{file="outer.md"}', join(dir, "main.md"))
|
|
57
42
|
expect(result).toBe("Inner content")
|
|
58
43
|
})
|
|
59
44
|
|
|
60
45
|
it("should limit recursion depth", () => {
|
|
61
46
|
const dir = temporaryDirectory()
|
|
62
47
|
writeFileSync(join(dir, "recursive.md"), '::include{file="recursive.md"}')
|
|
63
|
-
const result = resolveIncludes(
|
|
64
|
-
'::include{file="recursive.md"}',
|
|
65
|
-
join(dir, "main.md"),
|
|
66
|
-
)
|
|
48
|
+
const result = resolveIncludes('::include{file="recursive.md"}', join(dir, "main.md"))
|
|
67
49
|
expect(result).toBe('::include{file="recursive.md"}')
|
|
68
50
|
})
|
|
69
51
|
|
|
@@ -72,10 +54,7 @@ describe("resolveIncludes", () => {
|
|
|
72
54
|
mkdirSync(join(dir, "sub"))
|
|
73
55
|
writeFileSync(join(dir, "sub", "child.md"), "Child content")
|
|
74
56
|
writeFileSync(join(dir, "parent.md"), '::include{file="sub/child.md"}')
|
|
75
|
-
const result = resolveIncludes(
|
|
76
|
-
'::include{file="parent.md"}',
|
|
77
|
-
join(dir, "main.md"),
|
|
78
|
-
)
|
|
57
|
+
const result = resolveIncludes('::include{file="parent.md"}', join(dir, "main.md"))
|
|
79
58
|
expect(result).toBe("Child content")
|
|
80
59
|
})
|
|
81
60
|
|
|
@@ -93,10 +72,7 @@ describe("resolveIncludes", () => {
|
|
|
93
72
|
it("should wrap code files in fenced blocks", () => {
|
|
94
73
|
const dir = temporaryDirectory()
|
|
95
74
|
writeFileSync(join(dir, "example.ts"), 'const x = 1\nconst y = "hello"')
|
|
96
|
-
const result = resolveIncludes(
|
|
97
|
-
'::include{file="example.ts"}',
|
|
98
|
-
join(dir, "main.md"),
|
|
99
|
-
)
|
|
75
|
+
const result = resolveIncludes('::include{file="example.ts"}', join(dir, "main.md"))
|
|
100
76
|
expect(result).toBe(
|
|
101
77
|
'```typescript title="example.ts"\nconst x = 1\nconst y = "hello"\n```',
|
|
102
78
|
)
|
|
@@ -117,10 +93,7 @@ describe("resolveIncludes", () => {
|
|
|
117
93
|
it("should treat unknown extensions as markdown", () => {
|
|
118
94
|
const dir = temporaryDirectory()
|
|
119
95
|
writeFileSync(join(dir, "notes.txt"), "Plain text")
|
|
120
|
-
const result = resolveIncludes(
|
|
121
|
-
'::include{file="notes.txt"}',
|
|
122
|
-
join(dir, "main.md"),
|
|
123
|
-
)
|
|
96
|
+
const result = resolveIncludes('::include{file="notes.txt"}', join(dir, "main.md"))
|
|
124
97
|
expect(result).toBe("Plain text")
|
|
125
98
|
})
|
|
126
99
|
})
|
package/source/helpers/rss.ts
CHANGED
|
@@ -37,19 +37,13 @@ export function renderRssFeed(feed: RssFeed) {
|
|
|
37
37
|
lines.push(` <link>${escapeXml(item.link)}</link>`)
|
|
38
38
|
lines.push(` <guid isPermaLink="true">${escapeXml(item.guid)}</guid>`)
|
|
39
39
|
if (item.description) {
|
|
40
|
-
lines.push(
|
|
41
|
-
` <description>${escapeXml(item.description)}</description>`,
|
|
42
|
-
)
|
|
40
|
+
lines.push(` <description>${escapeXml(item.description)}</description>`)
|
|
43
41
|
}
|
|
44
42
|
if (item.pubDate) {
|
|
45
|
-
lines.push(
|
|
46
|
-
` <pubDate>${escapeXml(toRfc822(item.pubDate))}</pubDate>`,
|
|
47
|
-
)
|
|
43
|
+
lines.push(` <pubDate>${escapeXml(toRfc822(item.pubDate))}</pubDate>`)
|
|
48
44
|
}
|
|
49
45
|
if (item.author) {
|
|
50
|
-
const author = Array.isArray(item.author)
|
|
51
|
-
? item.author.join(", ")
|
|
52
|
-
: item.author
|
|
46
|
+
const author = Array.isArray(item.author) ? item.author.join(", ") : item.author
|
|
53
47
|
lines.push(` <author>${escapeXml(author)}</author>`)
|
|
54
48
|
}
|
|
55
49
|
if (item.categories) {
|
|
@@ -106,9 +106,7 @@ describe("renderRssFeed", () => {
|
|
|
106
106
|
},
|
|
107
107
|
],
|
|
108
108
|
})
|
|
109
|
-
expect(xml).toContain(
|
|
110
|
-
"<title>Title & "quoted" <tag></title>",
|
|
111
|
-
)
|
|
109
|
+
expect(xml).toContain("<title>Title & "quoted" <tag></title>")
|
|
112
110
|
expect(xml).toContain("<description>A & B</description>")
|
|
113
111
|
expect(xml).toContain("<title>1 < 2 & 3 > 0</title>")
|
|
114
112
|
expect(xml).toContain("<description>It's fine</description>")
|
|
@@ -63,10 +63,7 @@ export function matchSection<S extends { prefix: string }>(
|
|
|
63
63
|
let best: S | undefined
|
|
64
64
|
let bestLen = 0
|
|
65
65
|
for (const section of sections) {
|
|
66
|
-
if (
|
|
67
|
-
articlePath.startsWith(section.prefix) &&
|
|
68
|
-
section.prefix.length > bestLen
|
|
69
|
-
) {
|
|
66
|
+
if (articlePath.startsWith(section.prefix) && section.prefix.length > bestLen) {
|
|
70
67
|
best = section
|
|
71
68
|
bestLen = section.prefix.length
|
|
72
69
|
}
|
|
@@ -53,14 +53,8 @@ describe("partitionBySection", () => {
|
|
|
53
53
|
|
|
54
54
|
it("should split articles into section buckets", () => {
|
|
55
55
|
const result = partitionBySection(articles, sections)
|
|
56
|
-
expect(result.get("/")?.map(a => a.path)).toEqual([
|
|
57
|
-
|
|
58
|
-
"/guide/",
|
|
59
|
-
])
|
|
60
|
-
expect(result.get("/api/")?.map(a => a.path)).toEqual([
|
|
61
|
-
"/api/users/",
|
|
62
|
-
"/api/auth/",
|
|
63
|
-
])
|
|
56
|
+
expect(result.get("/")?.map(a => a.path)).toEqual(["/getting-started/", "/guide/"])
|
|
57
|
+
expect(result.get("/api/")?.map(a => a.path)).toEqual(["/api/users/", "/api/auth/"])
|
|
64
58
|
})
|
|
65
59
|
|
|
66
60
|
it("should put unmatched articles in __default__ bucket", () => {
|
|
@@ -70,10 +64,7 @@ describe("partitionBySection", () => {
|
|
|
70
64
|
"/getting-started/",
|
|
71
65
|
"/guide/",
|
|
72
66
|
])
|
|
73
|
-
expect(result.get("/api/")?.map(a => a.path)).toEqual([
|
|
74
|
-
"/api/users/",
|
|
75
|
-
"/api/auth/",
|
|
76
|
-
])
|
|
67
|
+
expect(result.get("/api/")?.map(a => a.path)).toEqual(["/api/users/", "/api/auth/"])
|
|
77
68
|
})
|
|
78
69
|
})
|
|
79
70
|
|
|
@@ -152,16 +143,12 @@ describe("activeSiteSection", () => {
|
|
|
152
143
|
})
|
|
153
144
|
|
|
154
145
|
it("should return the custom section matching by internal url", () => {
|
|
155
|
-
expect(activeSiteSection("/api/v2/users/", [docs, apiCustom])?.title).toBe(
|
|
156
|
-
"API",
|
|
157
|
-
)
|
|
146
|
+
expect(activeSiteSection("/api/v2/users/", [docs, apiCustom])?.title).toBe("API")
|
|
158
147
|
})
|
|
159
148
|
|
|
160
149
|
it("should pick the longest match among overlapping prefixes", () => {
|
|
161
150
|
expect(activeSiteSection("/blog/post/", [docs, blog])?.title).toBe("Blog")
|
|
162
|
-
expect(activeSiteSection("/api/v2/foo/", [docs, apiCustom])?.title).toBe(
|
|
163
|
-
"API",
|
|
164
|
-
)
|
|
151
|
+
expect(activeSiteSection("/api/v2/foo/", [docs, apiCustom])?.title).toBe("API")
|
|
165
152
|
})
|
|
166
153
|
|
|
167
154
|
it("should ignore custom sections with absolute URLs", () => {
|
|
@@ -35,9 +35,7 @@ describe("extractToc", () => {
|
|
|
35
35
|
it("should handle code formatting with custom ids", () => {
|
|
36
36
|
const content = "## `config` Options [#config-opts]"
|
|
37
37
|
const toc = extractToc(content)
|
|
38
|
-
expect(toc).toEqual([
|
|
39
|
-
{ url: "#config-opts", title: "config Options", depth: 2 },
|
|
40
|
-
])
|
|
38
|
+
expect(toc).toEqual([{ url: "#config-opts", title: "config Options", depth: 2 }])
|
|
41
39
|
})
|
|
42
40
|
|
|
43
41
|
it("should skip h1 headings", () => {
|
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
import type { Plugin } from "unified"
|
|
2
2
|
import { visit } from "unist-util-visit"
|
|
3
|
-
import {
|
|
4
|
-
type BundledLanguage,
|
|
5
|
-
bundledLanguages,
|
|
6
|
-
getSingletonHighlighter,
|
|
7
|
-
} from "shiki"
|
|
3
|
+
import { type BundledLanguage, bundledLanguages, getSingletonHighlighter } from "shiki"
|
|
8
4
|
|
|
9
5
|
interface HastText {
|
|
10
6
|
type: "text"
|
|
11
7
|
value: string
|
|
12
8
|
}
|
|
13
9
|
|
|
14
|
-
type PropertyValue =
|
|
15
|
-
| boolean
|
|
16
|
-
| number
|
|
17
|
-
| string
|
|
18
|
-
| null
|
|
19
|
-
| undefined
|
|
20
|
-
| Array<string | number>
|
|
10
|
+
type PropertyValue = boolean | number | string | null | undefined | Array<string | number>
|
|
21
11
|
|
|
22
12
|
interface HastElement {
|
|
23
13
|
type: "element"
|
|
@@ -56,15 +46,10 @@ export const rehypeInlineCode: Plugin<[], HastRoot> = () => {
|
|
|
56
46
|
visit(
|
|
57
47
|
tree,
|
|
58
48
|
"element",
|
|
59
|
-
(
|
|
60
|
-
node: HastNode,
|
|
61
|
-
_index: number | undefined,
|
|
62
|
-
parent: HastNode | undefined,
|
|
63
|
-
) => {
|
|
49
|
+
(node: HastNode, _index: number | undefined, parent: HastNode | undefined) => {
|
|
64
50
|
if (node.type !== "element") return
|
|
65
51
|
if (node.tagName !== "code") return
|
|
66
|
-
if (parent && parent.type === "element" && parent.tagName === "pre")
|
|
67
|
-
return
|
|
52
|
+
if (parent && parent.type === "element" && parent.tagName === "pre") return
|
|
68
53
|
|
|
69
54
|
const textChild = node.children[0]
|
|
70
55
|
if (!textChild || textChild.type !== "text") return
|
|
@@ -92,8 +77,7 @@ export const rehypeInlineCode: Plugin<[], HastRoot> = () => {
|
|
|
92
77
|
const codeEl = pre.children[0]
|
|
93
78
|
if (codeEl && codeEl.type === "element" && "children" in codeEl) {
|
|
94
79
|
node.children = codeEl.children.filter(
|
|
95
|
-
(c): c is HastElement | HastText =>
|
|
96
|
-
c.type === "element" || c.type === "text",
|
|
80
|
+
(c): c is HastElement | HastText => c.type === "element" || c.type === "text",
|
|
97
81
|
)
|
|
98
82
|
node.properties = {
|
|
99
83
|
...node.properties,
|
|
@@ -14,8 +14,7 @@ export function rehypeTaskListA11y() {
|
|
|
14
14
|
visit(tree, "element", (node: HastNode) => {
|
|
15
15
|
if (node.tagName !== "li") return
|
|
16
16
|
const classes = node.properties?.className
|
|
17
|
-
const hasTaskClass =
|
|
18
|
-
Array.isArray(classes) && classes.includes("task-list-item")
|
|
17
|
+
const hasTaskClass = Array.isArray(classes) && classes.includes("task-list-item")
|
|
19
18
|
if (!hasTaskClass) return
|
|
20
19
|
|
|
21
20
|
for (const child of node.children ?? []) {
|
|
@@ -8,9 +8,7 @@ export function transformAbbrDirectives(tree: Root) {
|
|
|
8
8
|
visit(tree, "textDirective", (node: TextDirective, index, parent) => {
|
|
9
9
|
if (node.name !== "abbr" || index === undefined || !parent) return
|
|
10
10
|
|
|
11
|
-
const text = node.children
|
|
12
|
-
.map(c => ("value" in c ? String(c.value) : ""))
|
|
13
|
-
.join("")
|
|
11
|
+
const text = node.children.map(c => ("value" in c ? String(c.value) : "")).join("")
|
|
14
12
|
|
|
15
13
|
const title = node.attributes?.title ?? ""
|
|
16
14
|
|
|
@@ -41,8 +41,7 @@ function color256(n: number): string | undefined {
|
|
|
41
41
|
const r = Math.floor(idx / 36)
|
|
42
42
|
const g = Math.floor((idx % 36) / 6)
|
|
43
43
|
const b = idx % 6
|
|
44
|
-
const toHex = (v: number) =>
|
|
45
|
-
(v === 0 ? 0 : 55 + v * 40).toString(16).padStart(2, "0")
|
|
44
|
+
const toHex = (v: number) => (v === 0 ? 0 : 55 + v * 40).toString(16).padStart(2, "0")
|
|
46
45
|
return `#${toHex(r)}${toHex(g)}${toHex(b)}`
|
|
47
46
|
}
|
|
48
47
|
if (n < 256) {
|
|
@@ -192,9 +191,7 @@ export function ansiToHtml(input: string): string {
|
|
|
192
191
|
|
|
193
192
|
const rawParams = match[1]!
|
|
194
193
|
const params =
|
|
195
|
-
rawParams === ""
|
|
196
|
-
? [0]
|
|
197
|
-
: rawParams.split(";").map(s => Number.parseInt(s, 10))
|
|
194
|
+
rawParams === "" ? [0] : rawParams.split(";").map(s => Number.parseInt(s, 10))
|
|
198
195
|
applyParams(state, params)
|
|
199
196
|
lastIndex = match.index + match[0].length
|
|
200
197
|
match = sgr.exec(input)
|
|
@@ -17,9 +17,7 @@ describe("ansiToHtml", () => {
|
|
|
17
17
|
|
|
18
18
|
it("should render standard foreground colors", () => {
|
|
19
19
|
const input = "\x1b[31mred text\x1b[0m"
|
|
20
|
-
expect(ansiToHtml(input)).toBe(
|
|
21
|
-
'<span style="color:#bf616a">red text</span>',
|
|
22
|
-
)
|
|
20
|
+
expect(ansiToHtml(input)).toBe('<span style="color:#bf616a">red text</span>')
|
|
23
21
|
})
|
|
24
22
|
|
|
25
23
|
it("should render bold text", () => {
|
|
@@ -29,9 +27,7 @@ describe("ansiToHtml", () => {
|
|
|
29
27
|
|
|
30
28
|
it("should render italic text", () => {
|
|
31
29
|
const input = "\x1b[3mitalic\x1b[0m"
|
|
32
|
-
expect(ansiToHtml(input)).toBe(
|
|
33
|
-
'<span style="font-style:italic">italic</span>',
|
|
34
|
-
)
|
|
30
|
+
expect(ansiToHtml(input)).toBe('<span style="font-style:italic">italic</span>')
|
|
35
31
|
})
|
|
36
32
|
|
|
37
33
|
it("should render underline text", () => {
|
|
@@ -69,9 +65,7 @@ describe("ansiToHtml", () => {
|
|
|
69
65
|
|
|
70
66
|
it("should handle bright foreground colors", () => {
|
|
71
67
|
const input = "\x1b[91mbright red\x1b[0m"
|
|
72
|
-
expect(ansiToHtml(input)).toBe(
|
|
73
|
-
'<span style="color:#bf616a">bright red</span>',
|
|
74
|
-
)
|
|
68
|
+
expect(ansiToHtml(input)).toBe('<span style="color:#bf616a">bright red</span>')
|
|
75
69
|
})
|
|
76
70
|
|
|
77
71
|
it("should handle bright background colors", () => {
|
|
@@ -88,9 +82,7 @@ describe("ansiToHtml", () => {
|
|
|
88
82
|
|
|
89
83
|
it("should handle 256-color background", () => {
|
|
90
84
|
const input = "\x1b[48;5;21mbg\x1b[0m"
|
|
91
|
-
expect(ansiToHtml(input)).toBe(
|
|
92
|
-
'<span style="background-color:#0000ff">bg</span>',
|
|
93
|
-
)
|
|
85
|
+
expect(ansiToHtml(input)).toBe('<span style="background-color:#0000ff">bg</span>')
|
|
94
86
|
})
|
|
95
87
|
|
|
96
88
|
it("should handle 24-bit RGB foreground", () => {
|
|
@@ -100,16 +92,12 @@ describe("ansiToHtml", () => {
|
|
|
100
92
|
|
|
101
93
|
it("should handle 24-bit RGB background", () => {
|
|
102
94
|
const input = "\x1b[48;2;0;128;255mbg\x1b[0m"
|
|
103
|
-
expect(ansiToHtml(input)).toBe(
|
|
104
|
-
'<span style="background-color:#0080ff">bg</span>',
|
|
105
|
-
)
|
|
95
|
+
expect(ansiToHtml(input)).toBe('<span style="background-color:#0080ff">bg</span>')
|
|
106
96
|
})
|
|
107
97
|
|
|
108
98
|
it("should handle reset via empty escape", () => {
|
|
109
99
|
const input = "\x1b[31mred\x1b[mnormal"
|
|
110
|
-
expect(ansiToHtml(input)).toBe(
|
|
111
|
-
'<span style="color:#bf616a">red</span>normal',
|
|
112
|
-
)
|
|
100
|
+
expect(ansiToHtml(input)).toBe('<span style="color:#bf616a">red</span>normal')
|
|
113
101
|
})
|
|
114
102
|
|
|
115
103
|
it("should handle multiple segments", () => {
|
|
@@ -8,9 +8,7 @@ export function transformBadgeDirectives(tree: Root) {
|
|
|
8
8
|
visit(tree, "textDirective", (node: TextDirective, index, parent) => {
|
|
9
9
|
if (node.name !== "badge" || index === undefined || !parent) return
|
|
10
10
|
|
|
11
|
-
const label = node.children
|
|
12
|
-
.map(c => ("value" in c ? String(c.value) : ""))
|
|
13
|
-
.join("")
|
|
11
|
+
const label = node.children.map(c => ("value" in c ? String(c.value) : "")).join("")
|
|
14
12
|
|
|
15
13
|
const variant = node.attributes?.variant
|
|
16
14
|
|
|
@@ -47,9 +47,7 @@ describe("transformButtonDirectives", () => {
|
|
|
47
47
|
|
|
48
48
|
it("should convert ::button with label attribute to LinkButton JSX element", () => {
|
|
49
49
|
const tree = process(
|
|
50
|
-
makeTree(
|
|
51
|
-
makeLeafDirective("button", { href: "/docs", label: "Read Docs" }),
|
|
52
|
-
),
|
|
50
|
+
makeTree(makeLeafDirective("button", { href: "/docs", label: "Read Docs" })),
|
|
53
51
|
)
|
|
54
52
|
const node = tree.children[0]
|
|
55
53
|
expect(node).toMatchObject({
|
|
@@ -122,17 +120,13 @@ describe("transformButtonDirectives", () => {
|
|
|
122
120
|
})
|
|
123
121
|
|
|
124
122
|
it("should skip button directive without href", () => {
|
|
125
|
-
const tree = process(
|
|
126
|
-
makeTree(makeLeafDirective("button", { label: "No Link" })),
|
|
127
|
-
)
|
|
123
|
+
const tree = process(makeTree(makeLeafDirective("button", { label: "No Link" })))
|
|
128
124
|
const node = tree.children[0]
|
|
129
125
|
expect(node).toMatchObject({ type: "leafDirective", name: "button" })
|
|
130
126
|
})
|
|
131
127
|
|
|
132
128
|
it("should skip button directive without label or bracket text", () => {
|
|
133
|
-
const tree = process(
|
|
134
|
-
makeTree(makeLeafDirective("button", { href: "/no-label" })),
|
|
135
|
-
)
|
|
129
|
+
const tree = process(makeTree(makeLeafDirective("button", { href: "/no-label" })))
|
|
136
130
|
const node = tree.children[0]
|
|
137
131
|
expect(node).toMatchObject({ type: "leafDirective", name: "button" })
|
|
138
132
|
})
|