specra 0.1.13 → 0.2.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/LICENSE.MD +25 -4
- package/README.md +67 -58
- package/config/specra.config.schema.json +16 -0
- package/config/svelte-config.js +63 -0
- package/dist/api-parser.types.d.ts +59 -0
- package/dist/api-parser.types.js +5 -0
- package/dist/api.types.d.ts +137 -0
- package/dist/api.types.js +5 -0
- package/dist/category.d.ts +21 -0
- package/dist/category.js +48 -0
- package/dist/components/ConfigProvider.svelte +13 -0
- package/dist/components/ConfigProvider.svelte.d.ts +31 -0
- package/dist/components/docs/Accordion.svelte +18 -0
- package/dist/components/docs/Accordion.svelte.d.ts +10 -0
- package/dist/components/docs/AccordionItem.svelte +41 -0
- package/dist/components/docs/AccordionItem.svelte.d.ts +10 -0
- package/dist/components/docs/Badge.svelte +28 -0
- package/dist/components/docs/Badge.svelte.d.ts +9 -0
- package/dist/components/docs/Breadcrumb.svelte +80 -0
- package/dist/components/docs/Breadcrumb.svelte.d.ts +8 -0
- package/dist/components/docs/Callout.svelte +96 -0
- package/dist/components/docs/Callout.svelte.d.ts +10 -0
- package/dist/components/docs/Card.svelte +63 -0
- package/dist/components/docs/Card.svelte.d.ts +12 -0
- package/dist/components/docs/CardGrid.svelte +24 -0
- package/dist/components/docs/CardGrid.svelte.d.ts +8 -0
- package/dist/components/docs/CategoryIndex.svelte +110 -0
- package/dist/components/docs/CategoryIndex.svelte.d.ts +29 -0
- package/dist/components/docs/CodeBlock.svelte +172 -0
- package/dist/components/docs/CodeBlock.svelte.d.ts +8 -0
- package/dist/components/docs/Column.svelte +25 -0
- package/dist/components/docs/Column.svelte.d.ts +8 -0
- package/dist/components/docs/Columns.svelte +38 -0
- package/dist/components/docs/Columns.svelte.d.ts +13 -0
- package/dist/components/docs/DevModeBadge.svelte +15 -0
- package/dist/components/docs/DevModeBadge.svelte.d.ts +18 -0
- package/dist/components/docs/DocBadge.svelte +28 -0
- package/dist/components/docs/DocBadge.svelte.d.ts +9 -0
- package/dist/components/docs/DocLayout.svelte +107 -0
- package/dist/components/docs/DocLayout.svelte.d.ts +32 -0
- package/dist/components/docs/DocLoading.svelte +53 -0
- package/dist/components/docs/DocLoading.svelte.d.ts +18 -0
- package/dist/components/docs/DocMetadata.svelte +106 -0
- package/dist/components/docs/DocMetadata.svelte.d.ts +18 -0
- package/dist/components/docs/DocNavigation.svelte +56 -0
- package/dist/components/docs/DocNavigation.svelte.d.ts +12 -0
- package/dist/components/docs/DocTags.svelte +22 -0
- package/dist/components/docs/DocTags.svelte.d.ts +6 -0
- package/dist/components/docs/DraftBadge.svelte +10 -0
- package/dist/components/docs/DraftBadge.svelte.d.ts +18 -0
- package/dist/components/docs/Footer.svelte +72 -0
- package/dist/components/docs/Footer.svelte.d.ts +7 -0
- package/dist/components/docs/Frame.svelte +27 -0
- package/dist/components/docs/Frame.svelte.d.ts +9 -0
- package/dist/components/docs/Header.svelte +123 -0
- package/dist/components/docs/Header.svelte.d.ts +9 -0
- package/dist/components/docs/HeaderWithMenu.svelte +34 -0
- package/dist/components/docs/HeaderWithMenu.svelte.d.ts +17 -0
- package/dist/components/docs/HotReloadIndicator.svelte +44 -0
- package/dist/components/docs/HotReloadIndicator.svelte.d.ts +3 -0
- package/dist/components/docs/Icon.svelte +103 -0
- package/dist/components/docs/Icon.svelte.d.ts +11 -0
- package/dist/components/docs/Image.svelte +88 -0
- package/dist/components/docs/Image.svelte.d.ts +11 -0
- package/dist/components/docs/ImageCard.svelte +91 -0
- package/dist/components/docs/ImageCard.svelte.d.ts +12 -0
- package/dist/components/docs/ImageCardGrid.svelte +25 -0
- package/dist/components/docs/ImageCardGrid.svelte.d.ts +8 -0
- package/dist/components/docs/LayoutProviders.svelte +57 -0
- package/dist/components/docs/LayoutProviders.svelte.d.ts +9 -0
- package/dist/components/docs/Logo.svelte +25 -0
- package/dist/components/docs/Logo.svelte.d.ts +11 -0
- package/dist/components/docs/Math.svelte +54 -0
- package/dist/components/docs/Math.svelte.d.ts +7 -0
- package/dist/components/docs/MdxContent.svelte +41 -0
- package/dist/components/docs/MdxHotReload.svelte +78 -0
- package/dist/components/docs/MdxHotReload.svelte.d.ts +9 -0
- package/dist/components/docs/MdxLayout.svelte +16 -0
- package/dist/components/docs/MdxLayout.svelte.d.ts +6 -0
- package/dist/components/docs/Mermaid.svelte +88 -0
- package/dist/components/docs/Mermaid.svelte.d.ts +7 -0
- package/dist/components/docs/MobileDocLayout.svelte +211 -0
- package/dist/components/docs/MobileDocLayout.svelte.d.ts +35 -0
- package/dist/components/docs/MobileSidebar.svelte +122 -0
- package/dist/components/docs/MobileSidebar.svelte.d.ts +31 -0
- package/dist/components/docs/MobileSidebarWrapper.svelte +122 -0
- package/dist/components/docs/MobileSidebarWrapper.svelte.d.ts +32 -0
- package/dist/components/docs/NotFoundContent.svelte +40 -0
- package/dist/components/docs/NotFoundContent.svelte.d.ts +6 -0
- package/dist/components/docs/SearchHighlight.svelte +116 -0
- package/dist/components/docs/SearchHighlight.svelte.d.ts +3 -0
- package/dist/components/docs/SearchModal.svelte +239 -0
- package/dist/components/docs/SearchModal.svelte.d.ts +9 -0
- package/dist/components/docs/Sidebar.svelte +69 -0
- package/dist/components/docs/Sidebar.svelte.d.ts +31 -0
- package/dist/components/docs/SidebarMenuItems.svelte +344 -0
- package/dist/components/docs/SidebarMenuItems.svelte.d.ts +33 -0
- package/dist/components/docs/SidebarSkeleton.svelte +50 -0
- package/dist/components/docs/SidebarSkeleton.svelte.d.ts +18 -0
- package/dist/components/docs/SiteBanner.svelte +92 -0
- package/dist/components/docs/SiteBanner.svelte.d.ts +7 -0
- package/dist/components/docs/Step.svelte +44 -0
- package/dist/components/docs/Step.svelte.d.ts +8 -0
- package/dist/components/docs/Steps.svelte +15 -0
- package/dist/components/docs/Steps.svelte.d.ts +7 -0
- package/dist/components/docs/Tab.svelte +40 -0
- package/dist/components/docs/Tab.svelte.d.ts +8 -0
- package/dist/components/docs/TabGroups.svelte +183 -0
- package/dist/components/docs/TabGroups.svelte.d.ts +25 -0
- package/dist/components/docs/TableOfContents.svelte +100 -0
- package/dist/components/docs/TableOfContents.svelte.d.ts +9 -0
- package/dist/components/docs/Tabs.svelte +69 -0
- package/dist/components/docs/Tabs.svelte.d.ts +8 -0
- package/dist/components/docs/ThemeToggle.svelte +16 -0
- package/dist/components/docs/ThemeToggle.svelte.d.ts +18 -0
- package/dist/components/docs/Tooltip.svelte +44 -0
- package/dist/components/docs/Tooltip.svelte.d.ts +10 -0
- package/dist/components/docs/VersionSwitcher.svelte +95 -0
- package/dist/components/docs/VersionSwitcher.svelte.d.ts +7 -0
- package/dist/components/docs/Video.svelte +84 -0
- package/dist/components/docs/Video.svelte.d.ts +12 -0
- package/dist/components/docs/api/ApiEndpoint.svelte +61 -0
- package/dist/components/docs/api/ApiEndpoint.svelte.d.ts +11 -0
- package/dist/components/docs/api/ApiParams.svelte +80 -0
- package/dist/components/docs/api/ApiParams.svelte.d.ts +14 -0
- package/dist/components/docs/api/ApiPlayground.svelte +259 -0
- package/dist/components/docs/api/ApiPlayground.svelte.d.ts +16 -0
- package/dist/components/docs/api/ApiReference.svelte +278 -0
- package/dist/components/docs/api/ApiReference.svelte.d.ts +23 -0
- package/dist/components/docs/api/ApiResponse.svelte +66 -0
- package/dist/components/docs/api/ApiResponse.svelte.d.ts +9 -0
- package/dist/components/docs/api/index.d.ts +5 -0
- package/dist/components/docs/api/index.js +5 -0
- package/dist/components/docs/componentTextProps.d.ts +3 -0
- package/dist/components/docs/componentTextProps.js +61 -0
- package/dist/components/docs/index.d.ts +54 -0
- package/dist/components/docs/index.js +56 -0
- package/dist/components/global/VersionNotFound.svelte +48 -0
- package/dist/components/global/VersionNotFound.svelte.d.ts +7 -0
- package/dist/components/global/index.d.ts +1 -0
- package/dist/components/global/index.js +1 -0
- package/dist/components/index.d.ts +6 -822
- package/dist/components/index.js +11 -3854
- package/dist/components/ui/Badge.svelte +48 -0
- package/dist/components/ui/Badge.svelte.d.ts +15 -0
- package/dist/components/ui/Button.svelte +58 -0
- package/dist/components/ui/Button.svelte.d.ts +17 -0
- package/dist/components/ui/Dialog.svelte +16 -0
- package/dist/components/ui/Dialog.svelte.d.ts +9 -0
- package/dist/components/ui/DialogClose.svelte +16 -0
- package/dist/components/ui/DialogClose.svelte.d.ts +9 -0
- package/dist/components/ui/DialogContent.svelte +43 -0
- package/dist/components/ui/DialogContent.svelte.d.ts +10 -0
- package/dist/components/ui/DialogDescription.svelte +21 -0
- package/dist/components/ui/DialogDescription.svelte.d.ts +9 -0
- package/dist/components/ui/DialogFooter.svelte +20 -0
- package/dist/components/ui/DialogFooter.svelte.d.ts +9 -0
- package/dist/components/ui/DialogHeader.svelte +20 -0
- package/dist/components/ui/DialogHeader.svelte.d.ts +9 -0
- package/dist/components/ui/DialogTitle.svelte +21 -0
- package/dist/components/ui/DialogTitle.svelte.d.ts +9 -0
- package/dist/components/ui/Input.svelte +23 -0
- package/dist/components/ui/Input.svelte.d.ts +8 -0
- package/dist/components/ui/Textarea.svelte +19 -0
- package/dist/components/ui/Textarea.svelte.d.ts +7 -0
- package/dist/components/ui/index.d.ts +11 -0
- package/dist/components/ui/index.js +11 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.js +9 -0
- package/dist/config.schema.json +471 -0
- package/dist/config.server.d.ts +46 -0
- package/dist/config.server.js +149 -0
- package/dist/{mdx-ColN3Cyg.d.mts → config.types.d.ts} +22 -75
- package/dist/config.types.js +39 -0
- package/dist/dev-utils.d.ts +29 -0
- package/dist/dev-utils.js +63 -0
- package/dist/index.d.ts +19 -4
- package/dist/index.js +25 -4861
- package/dist/mdx-cache.d.ts +41 -0
- package/dist/mdx-cache.js +160 -0
- package/dist/mdx-components.js +50 -1931
- package/dist/mdx-security.d.ts +76 -0
- package/dist/mdx-security.js +217 -0
- package/dist/mdx.d.ts +73 -0
- package/dist/mdx.js +1099 -0
- package/dist/middleware/index.d.ts +1 -0
- package/dist/middleware/index.js +2 -0
- package/dist/middleware/security.d.ts +22 -47
- package/dist/middleware/security.js +111 -137
- package/dist/parsers/base-parser.d.ts +14 -0
- package/dist/parsers/base-parser.js +1 -0
- package/dist/parsers/index.d.ts +16 -0
- package/dist/parsers/index.js +51 -0
- package/dist/parsers/openapi-parser.d.ts +18 -0
- package/dist/parsers/openapi-parser.js +209 -0
- package/dist/parsers/postman-parser.d.ts +20 -0
- package/dist/parsers/postman-parser.js +260 -0
- package/dist/parsers/specra-parser.d.ts +10 -0
- package/dist/parsers/specra-parser.js +18 -0
- package/dist/redirects.d.ts +12 -0
- package/dist/redirects.js +30 -0
- package/dist/remark-code-meta.d.ts +6 -0
- package/dist/remark-code-meta.js +21 -0
- package/dist/sidebar-utils.d.ts +59 -0
- package/dist/sidebar-utils.js +144 -0
- package/dist/stores/config.d.ts +20 -0
- package/dist/stores/config.js +45 -0
- package/dist/stores/index.d.ts +4 -0
- package/dist/stores/index.js +4 -0
- package/dist/stores/sidebar.d.ts +7 -0
- package/dist/stores/sidebar.js +12 -0
- package/dist/stores/tabs.d.ts +6 -0
- package/dist/stores/tabs.js +41 -0
- package/dist/stores/theme.d.ts +7 -0
- package/dist/stores/theme.js +75 -0
- package/dist/{styles.css → styles/globals.css} +136 -6
- package/dist/toc.d.ts +9 -0
- package/dist/toc.js +15 -0
- package/dist/utils.d.ts +13 -0
- package/dist/utils.js +30 -0
- package/package.json +47 -90
- package/dist/app/api/mdx-watch/route.d.mts +0 -10
- package/dist/app/api/mdx-watch/route.d.ts +0 -10
- package/dist/app/api/mdx-watch/route.js +0 -118
- package/dist/app/api/mdx-watch/route.js.map +0 -1
- package/dist/app/api/mdx-watch/route.mjs +0 -91
- package/dist/app/api/mdx-watch/route.mjs.map +0 -1
- package/dist/chunk-6S3EJVEO.mjs +0 -259
- package/dist/chunk-6S3EJVEO.mjs.map +0 -1
- package/dist/chunk-BE7EROIW.mjs +0 -212
- package/dist/chunk-BE7EROIW.mjs.map +0 -1
- package/dist/chunk-CWHRZHZO.mjs +0 -168
- package/dist/chunk-CWHRZHZO.mjs.map +0 -1
- package/dist/chunk-D5VDVYFY.mjs +0 -1325
- package/dist/chunk-D5VDVYFY.mjs.map +0 -1
- package/dist/chunk-WMCO2UX5.mjs +0 -585
- package/dist/chunk-WMCO2UX5.mjs.map +0 -1
- package/dist/chunk-XEMGCPZZ.mjs +0 -475
- package/dist/chunk-XEMGCPZZ.mjs.map +0 -1
- package/dist/components/index.d.mts +0 -822
- package/dist/components/index.js.map +0 -1
- package/dist/components/index.mjs +0 -3741
- package/dist/components/index.mjs.map +0 -1
- package/dist/index.d.mts +0 -4
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -1897
- package/dist/index.mjs.map +0 -1
- package/dist/layouts/index.d.mts +0 -34
- package/dist/layouts/index.d.ts +0 -34
- package/dist/layouts/index.js +0 -453
- package/dist/layouts/index.js.map +0 -1
- package/dist/layouts/index.mjs +0 -173
- package/dist/layouts/index.mjs.map +0 -1
- package/dist/lib/index.d.mts +0 -583
- package/dist/lib/index.d.ts +0 -583
- package/dist/lib/index.js +0 -1595
- package/dist/lib/index.js.map +0 -1
- package/dist/lib/index.mjs +0 -111
- package/dist/lib/index.mjs.map +0 -1
- package/dist/mdx-ColN3Cyg.d.ts +0 -352
- package/dist/mdx-components.d.mts +0 -86
- package/dist/mdx-components.d.ts +0 -86
- package/dist/mdx-components.js.map +0 -1
- package/dist/mdx-components.mjs +0 -206
- package/dist/mdx-components.mjs.map +0 -1
- package/dist/middleware/security.d.mts +0 -82
- package/dist/middleware/security.js.map +0 -1
- package/dist/middleware/security.mjs +0 -84
- package/dist/middleware/security.mjs.map +0 -1
- package/dist/styles.css.map +0 -1
- package/dist/styles.d.mts +0 -2
- package/dist/styles.d.ts +0 -2
- package/dist/styles.js +0 -2
- package/dist/styles.js.map +0 -1
- package/dist/styles.mjs +0 -1
- package/dist/styles.mjs.map +0 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
children?: Snippet;
|
|
6
|
+
type?: 'single' | 'multiple';
|
|
7
|
+
collapsible?: boolean;
|
|
8
|
+
class?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let { children, type = 'multiple', collapsible, class: className }: Props = $props();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<div class={className || 'my-6 space-y-2'}>
|
|
15
|
+
{#if children}
|
|
16
|
+
{@render children()}
|
|
17
|
+
{/if}
|
|
18
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
children?: Snippet;
|
|
4
|
+
type?: 'single' | 'multiple';
|
|
5
|
+
collapsible?: boolean;
|
|
6
|
+
class?: string;
|
|
7
|
+
}
|
|
8
|
+
declare const Accordion: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type Accordion = ReturnType<typeof Accordion>;
|
|
10
|
+
export default Accordion;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { ChevronDown } from 'lucide-svelte';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
title: string;
|
|
7
|
+
defaultOpen?: boolean;
|
|
8
|
+
value?: string;
|
|
9
|
+
children?: Snippet;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let { title, defaultOpen = false, value, children }: Props = $props();
|
|
13
|
+
|
|
14
|
+
let isOpen = $state(defaultOpen);
|
|
15
|
+
|
|
16
|
+
function toggle() {
|
|
17
|
+
isOpen = !isOpen;
|
|
18
|
+
}
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<div class="border border-border rounded-xl overflow-hidden mb-2">
|
|
22
|
+
<button
|
|
23
|
+
onclick={toggle}
|
|
24
|
+
class="w-full flex items-center justify-between p-4 text-left bg-muted/30 hover:bg-muted/50 transition-colors"
|
|
25
|
+
aria-expanded={isOpen}
|
|
26
|
+
>
|
|
27
|
+
<span class="font-medium text-foreground">{title}</span>
|
|
28
|
+
<ChevronDown
|
|
29
|
+
class="h-5 w-5 text-muted-foreground transition-transform {isOpen ? 'rotate-180' : ''}"
|
|
30
|
+
/>
|
|
31
|
+
</button>
|
|
32
|
+
{#if isOpen}
|
|
33
|
+
<div class="p-4 border-t border-border bg-background">
|
|
34
|
+
<div class="prose prose-sm dark:prose-invert max-w-none [&>*:last-child]:mb-0">
|
|
35
|
+
{#if children}
|
|
36
|
+
{@render children()}
|
|
37
|
+
{/if}
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
{/if}
|
|
41
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
title: string;
|
|
4
|
+
defaultOpen?: boolean;
|
|
5
|
+
value?: string;
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
}
|
|
8
|
+
declare const AccordionItem: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type AccordionItem = ReturnType<typeof AccordionItem>;
|
|
10
|
+
export default AccordionItem;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
type BadgeVariant = 'default' | 'success' | 'warning' | 'error' | 'info';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
variant?: BadgeVariant;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let { variant = 'default', children }: Props = $props();
|
|
12
|
+
|
|
13
|
+
const variants: Record<BadgeVariant, string> = {
|
|
14
|
+
default: 'bg-muted text-foreground border-border',
|
|
15
|
+
success: 'bg-green-500/10 text-green-600 dark:text-green-400 border-green-500/20',
|
|
16
|
+
warning: 'bg-yellow-500/10 text-yellow-600 dark:text-yellow-400 border-yellow-500/20',
|
|
17
|
+
error: 'bg-red-500/10 text-red-600 dark:text-red-400 border-red-500/20',
|
|
18
|
+
info: 'bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/20',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
let classes = $derived(variants[variant] || variants.default);
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<span class="inline-flex items-center px-2 py-0.5 rounded-md text-xs font-medium border {classes}">
|
|
25
|
+
{#if children}
|
|
26
|
+
{@render children()}
|
|
27
|
+
{/if}
|
|
28
|
+
</span>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type BadgeVariant = 'default' | 'success' | 'warning' | 'error' | 'info';
|
|
3
|
+
interface Props {
|
|
4
|
+
variant?: BadgeVariant;
|
|
5
|
+
children?: Snippet;
|
|
6
|
+
}
|
|
7
|
+
declare const Badge: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type Badge = ReturnType<typeof Badge>;
|
|
9
|
+
export default Badge;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { ChevronRight } from 'lucide-svelte';
|
|
3
|
+
import { getConfigContext } from '../../stores/config.js';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
version: string;
|
|
7
|
+
slug: string;
|
|
8
|
+
title: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let { version, slug, title }: Props = $props();
|
|
12
|
+
|
|
13
|
+
const configStore = getConfigContext();
|
|
14
|
+
let config = $derived($configStore);
|
|
15
|
+
|
|
16
|
+
let breadcrumbs = $derived.by(() => {
|
|
17
|
+
const i18n = config.features?.i18n;
|
|
18
|
+
const locales = typeof i18n === 'object' ? i18n.locales : i18n ? ['en'] : [];
|
|
19
|
+
const defaultLocale = typeof i18n === 'object' ? i18n.defaultLocale : 'en';
|
|
20
|
+
|
|
21
|
+
const parts = slug.split('/');
|
|
22
|
+
|
|
23
|
+
// Check if first part is a locale
|
|
24
|
+
const potentialLocale = parts[0];
|
|
25
|
+
const isLc = locales.includes(potentialLocale);
|
|
26
|
+
|
|
27
|
+
const homeHref = isLc ? `/docs/${version}/${potentialLocale}` : `/docs/${version}`;
|
|
28
|
+
|
|
29
|
+
const crumbs: Array<{ label: string; href: string }> = [
|
|
30
|
+
{ label: 'Docs', href: homeHref }
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
// Build breadcrumb path
|
|
34
|
+
let currentPath = '';
|
|
35
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
36
|
+
const part = parts[i];
|
|
37
|
+
currentPath += (currentPath ? '/' : '') + part;
|
|
38
|
+
|
|
39
|
+
// Skip the locale part in the breadcrumb visual trail if it's the first part
|
|
40
|
+
if (i === 0 && isLc) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
crumbs.push({
|
|
45
|
+
label: part
|
|
46
|
+
.replace(/-/g, ' ')
|
|
47
|
+
.replace(/\b\w/g, (l) => l.toUpperCase()),
|
|
48
|
+
href: `/docs/${version}/${currentPath}`
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Add current page
|
|
53
|
+
crumbs.push({
|
|
54
|
+
label: title,
|
|
55
|
+
href: `/docs/${version}/${slug}`
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
return crumbs;
|
|
59
|
+
});
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<nav class="flex items-center gap-2 text-sm text-muted-foreground mb-4" aria-label="Breadcrumb">
|
|
63
|
+
{#each breadcrumbs as crumb, index (crumb.href)}
|
|
64
|
+
<div class="flex items-center gap-2">
|
|
65
|
+
{#if index > 0}
|
|
66
|
+
<ChevronRight class="h-4 w-4" />
|
|
67
|
+
{/if}
|
|
68
|
+
{#if index === breadcrumbs.length - 1}
|
|
69
|
+
<span class="text-foreground font-medium">{crumb.label}</span>
|
|
70
|
+
{:else}
|
|
71
|
+
<a
|
|
72
|
+
href={crumb.href}
|
|
73
|
+
class="hover:text-foreground transition-colors"
|
|
74
|
+
>
|
|
75
|
+
{crumb.label}
|
|
76
|
+
</a>
|
|
77
|
+
{/if}
|
|
78
|
+
</div>
|
|
79
|
+
{/each}
|
|
80
|
+
</nav>
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
Info,
|
|
4
|
+
AlertTriangle,
|
|
5
|
+
CheckCircle2,
|
|
6
|
+
XCircle,
|
|
7
|
+
Lightbulb,
|
|
8
|
+
} from 'lucide-svelte';
|
|
9
|
+
import type { Snippet } from 'svelte';
|
|
10
|
+
|
|
11
|
+
type CalloutType = 'info' | 'warning' | 'success' | 'error' | 'tip' | 'note' | 'danger';
|
|
12
|
+
|
|
13
|
+
interface Props {
|
|
14
|
+
type?: CalloutType;
|
|
15
|
+
title?: string;
|
|
16
|
+
children?: Snippet;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let { type = 'info', title, children }: Props = $props();
|
|
20
|
+
|
|
21
|
+
const configs: Record<CalloutType, {
|
|
22
|
+
icon: typeof Info;
|
|
23
|
+
className: string;
|
|
24
|
+
iconClassName: string;
|
|
25
|
+
titleClassName: string;
|
|
26
|
+
defaultTitle: string;
|
|
27
|
+
}> = {
|
|
28
|
+
info: {
|
|
29
|
+
icon: Info,
|
|
30
|
+
className: 'bg-blue-500/10 border-blue-500/30 text-blue-900 dark:bg-blue-400/5 dark:border-blue-500/20 dark:text-blue-400',
|
|
31
|
+
iconClassName: 'text-blue-600 dark:text-blue-400',
|
|
32
|
+
titleClassName: 'text-blue-700 dark:text-blue-300',
|
|
33
|
+
defaultTitle: 'Info',
|
|
34
|
+
},
|
|
35
|
+
note: {
|
|
36
|
+
icon: Info,
|
|
37
|
+
className: 'bg-blue-500/10 border-blue-500/30 text-blue-900 dark:bg-blue-400/5 dark:border-blue-500/20 dark:text-blue-400',
|
|
38
|
+
iconClassName: 'text-blue-600 dark:text-blue-400',
|
|
39
|
+
titleClassName: 'text-blue-700 dark:text-blue-300',
|
|
40
|
+
defaultTitle: 'Note',
|
|
41
|
+
},
|
|
42
|
+
warning: {
|
|
43
|
+
icon: AlertTriangle,
|
|
44
|
+
className: 'bg-yellow-500/10 border-yellow-500/30 text-yellow-900 dark:bg-yellow-400/5 dark:border-yellow-500/20 dark:text-yellow-400',
|
|
45
|
+
iconClassName: 'text-yellow-600 dark:text-yellow-400',
|
|
46
|
+
titleClassName: 'text-yellow-700 dark:text-yellow-300',
|
|
47
|
+
defaultTitle: 'Warning',
|
|
48
|
+
},
|
|
49
|
+
success: {
|
|
50
|
+
icon: CheckCircle2,
|
|
51
|
+
className: 'bg-green-500/10 border-green-500/30 text-green-900 dark:bg-green-400/5 dark:border-green-500/20 dark:text-green-400',
|
|
52
|
+
iconClassName: 'text-green-600 dark:text-green-400',
|
|
53
|
+
titleClassName: 'text-green-700 dark:text-green-300',
|
|
54
|
+
defaultTitle: 'Success',
|
|
55
|
+
},
|
|
56
|
+
error: {
|
|
57
|
+
icon: XCircle,
|
|
58
|
+
className: 'bg-red-500/10 border-red-500/30 text-red-900 dark:bg-red-400/5 dark:border-red-500/20 dark:text-red-400',
|
|
59
|
+
iconClassName: 'text-red-600 dark:text-red-400',
|
|
60
|
+
titleClassName: 'text-red-700 dark:text-red-300',
|
|
61
|
+
defaultTitle: 'Error',
|
|
62
|
+
},
|
|
63
|
+
danger: {
|
|
64
|
+
icon: XCircle,
|
|
65
|
+
className: 'bg-red-500/10 border-red-500/30 text-red-900 dark:bg-red-400/5 dark:border-red-500/20 dark:text-red-400',
|
|
66
|
+
iconClassName: 'text-red-600 dark:text-red-400',
|
|
67
|
+
titleClassName: 'text-red-700 dark:text-red-300',
|
|
68
|
+
defaultTitle: 'Danger',
|
|
69
|
+
},
|
|
70
|
+
tip: {
|
|
71
|
+
icon: Lightbulb,
|
|
72
|
+
className: 'bg-purple-500/10 border-purple-500/30 text-purple-900 dark:bg-purple-400/5 dark:border-purple-500/20 dark:text-purple-400',
|
|
73
|
+
iconClassName: 'text-purple-600 dark:text-purple-400',
|
|
74
|
+
titleClassName: 'text-purple-700 dark:text-purple-300',
|
|
75
|
+
defaultTitle: 'Tip',
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
let config = $derived(configs[type] || configs.info);
|
|
80
|
+
let displayTitle = $derived(title || config.defaultTitle);
|
|
81
|
+
let IconComponent = $derived(config.icon);
|
|
82
|
+
</script>
|
|
83
|
+
|
|
84
|
+
<div class="flex gap-3 p-4 rounded-xl border my-2 {config.className}">
|
|
85
|
+
<div class="flex-shrink-0 mt-0.5">
|
|
86
|
+
<IconComponent class="h-5 w-5 {config.iconClassName}" />
|
|
87
|
+
</div>
|
|
88
|
+
<div class="flex-1 space-y-0">
|
|
89
|
+
<div class="font-semibold text-sm {config.titleClassName}">{displayTitle}</div>
|
|
90
|
+
<div class="text-sm leading-relaxed [&>p]:mb-0 [&>p]:text-current">
|
|
91
|
+
{#if children}
|
|
92
|
+
{@render children()}
|
|
93
|
+
{/if}
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type CalloutType = 'info' | 'warning' | 'success' | 'error' | 'tip' | 'note' | 'danger';
|
|
3
|
+
interface Props {
|
|
4
|
+
type?: CalloutType;
|
|
5
|
+
title?: string;
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
}
|
|
8
|
+
declare const Callout: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type Callout = ReturnType<typeof Callout>;
|
|
10
|
+
export default Callout;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { ArrowRight, ExternalLink } from 'lucide-svelte';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import Icon from './Icon.svelte';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
title: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
href?: string;
|
|
10
|
+
icon?: string;
|
|
11
|
+
external?: boolean;
|
|
12
|
+
children?: Snippet;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let { title, description, href, icon, external = false, children }: Props = $props();
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
{#snippet cardContent(isLink: boolean)}
|
|
19
|
+
<div class="flex items-center gap-3">
|
|
20
|
+
{#if icon}
|
|
21
|
+
<div class="shrink-0 w-10 h-10 rounded-xl bg-primary/10 flex items-center justify-center text-primary">
|
|
22
|
+
<Icon {icon} size={20} />
|
|
23
|
+
</div>
|
|
24
|
+
{/if}
|
|
25
|
+
<div class="flex-1 min-w-0">
|
|
26
|
+
<h3 class="font-semibold text-foreground mb-1 no-underline {isLink ? 'group-hover:text-primary transition-colors' : ''}">
|
|
27
|
+
{title}
|
|
28
|
+
</h3>
|
|
29
|
+
{#if description}
|
|
30
|
+
<p class="text-sm text-muted-foreground line-clamp-2 no-underline">{description}</p>
|
|
31
|
+
{/if}
|
|
32
|
+
{#if children}
|
|
33
|
+
<div class="mt-2 text-sm text-muted-foreground no-underline">
|
|
34
|
+
{@render children()}
|
|
35
|
+
</div>
|
|
36
|
+
{/if}
|
|
37
|
+
</div>
|
|
38
|
+
{#if href}
|
|
39
|
+
<div class="shrink-0 self-start mt-1">
|
|
40
|
+
{#if external}
|
|
41
|
+
<ExternalLink class="h-4 w-4 text-muted-foreground group-hover:text-primary transition-colors" />
|
|
42
|
+
{:else}
|
|
43
|
+
<ArrowRight class="h-4 w-4 text-muted-foreground group-hover:text-primary group-hover:translate-x-1 transition-all" />
|
|
44
|
+
{/if}
|
|
45
|
+
</div>
|
|
46
|
+
{/if}
|
|
47
|
+
</div>
|
|
48
|
+
{/snippet}
|
|
49
|
+
|
|
50
|
+
{#if href}
|
|
51
|
+
<a
|
|
52
|
+
{href}
|
|
53
|
+
class="card-link group block p-4 rounded-xl border border-border hover:border-primary/50 hover:bg-muted/50 transition-all"
|
|
54
|
+
target={external ? '_blank' : undefined}
|
|
55
|
+
rel={external ? 'noopener noreferrer' : undefined}
|
|
56
|
+
>
|
|
57
|
+
{@render cardContent(true)}
|
|
58
|
+
</a>
|
|
59
|
+
{:else}
|
|
60
|
+
<div class="p-4 rounded-xl border border-border bg-muted/30 no-underline">
|
|
61
|
+
{@render cardContent(false)}
|
|
62
|
+
</div>
|
|
63
|
+
{/if}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
title: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
href?: string;
|
|
6
|
+
icon?: string;
|
|
7
|
+
external?: boolean;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
}
|
|
10
|
+
declare const Card: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type Card = ReturnType<typeof Card>;
|
|
12
|
+
export default Card;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
cols?: 1 | 2 | 3;
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let { cols = 2, children }: Props = $props();
|
|
10
|
+
|
|
11
|
+
const gridCols: Record<number, string> = {
|
|
12
|
+
1: 'grid-cols-1',
|
|
13
|
+
2: 'grid-cols-1 md:grid-cols-2',
|
|
14
|
+
3: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
let gridClass = $derived(gridCols[cols] || gridCols[2]);
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<div class="grid {gridClass} gap-4 my-6">
|
|
21
|
+
{#if children}
|
|
22
|
+
{@render children()}
|
|
23
|
+
{/if}
|
|
24
|
+
</div>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { FileText, ArrowRight } from 'lucide-svelte';
|
|
3
|
+
import type { SpecraConfig } from '../../config.types.js';
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
|
|
6
|
+
interface DocItem {
|
|
7
|
+
slug: string;
|
|
8
|
+
filePath: string;
|
|
9
|
+
version?: string;
|
|
10
|
+
meta?: {
|
|
11
|
+
title?: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
sidebar_position?: number;
|
|
14
|
+
icon?: string;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
};
|
|
17
|
+
title?: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
[key: string]: unknown;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface Props {
|
|
23
|
+
categoryPath: string;
|
|
24
|
+
version: string;
|
|
25
|
+
allDocs: DocItem[];
|
|
26
|
+
title?: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
content?: Snippet;
|
|
29
|
+
config: SpecraConfig;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let { categoryPath, version, allDocs, title, description, content, config }: Props = $props();
|
|
33
|
+
|
|
34
|
+
// Filter docs that belong to this category (direct children)
|
|
35
|
+
const childDocs = $derived(() => {
|
|
36
|
+
if (!allDocs || allDocs.length === 0) return [];
|
|
37
|
+
|
|
38
|
+
return allDocs
|
|
39
|
+
.filter((doc) => {
|
|
40
|
+
const docPath = doc.filePath || doc.slug;
|
|
41
|
+
// Match direct children of this category path
|
|
42
|
+
if (!docPath.startsWith(categoryPath + '/')) return false;
|
|
43
|
+
const remaining = docPath.slice(categoryPath.length + 1);
|
|
44
|
+
// Only direct children (no further slashes, or is an index)
|
|
45
|
+
return !remaining.includes('/') && remaining !== 'index';
|
|
46
|
+
})
|
|
47
|
+
.sort((a, b) => {
|
|
48
|
+
const posA = a.meta?.sidebar_position ?? 999;
|
|
49
|
+
const posB = b.meta?.sidebar_position ?? 999;
|
|
50
|
+
return posA - posB;
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const baseUrl = $derived(config.site?.baseUrl?.replace(/\/$/, '') || '');
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<div class="space-y-8">
|
|
58
|
+
<!-- Category Header -->
|
|
59
|
+
{#if title}
|
|
60
|
+
<div class="space-y-2">
|
|
61
|
+
<h1 class="text-3xl font-bold tracking-tight text-foreground">{title}</h1>
|
|
62
|
+
{#if description}
|
|
63
|
+
<p class="text-lg text-muted-foreground">{description}</p>
|
|
64
|
+
{/if}
|
|
65
|
+
</div>
|
|
66
|
+
{/if}
|
|
67
|
+
|
|
68
|
+
<!-- Rendered mdsvex content via slot -->
|
|
69
|
+
{#if content}
|
|
70
|
+
<div class="prose dark:prose-invert max-w-none">
|
|
71
|
+
{@render content()}
|
|
72
|
+
</div>
|
|
73
|
+
{/if}
|
|
74
|
+
|
|
75
|
+
<!-- Child Documents Grid -->
|
|
76
|
+
{#if childDocs().length > 0}
|
|
77
|
+
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 mt-8">
|
|
78
|
+
{#each childDocs() as doc}
|
|
79
|
+
{@const docTitle = doc.meta?.title || doc.title || doc.slug.split('/').pop() || 'Untitled'}
|
|
80
|
+
{@const docDescription = doc.meta?.description || doc.description || ''}
|
|
81
|
+
{@const docSlug = doc.slug}
|
|
82
|
+
|
|
83
|
+
<a
|
|
84
|
+
href="{baseUrl}/{version}/{docSlug}"
|
|
85
|
+
class="group flex flex-col gap-2 p-5 rounded-lg border border-border bg-card hover:bg-accent/50 hover:border-accent-foreground/20 transition-all duration-200"
|
|
86
|
+
>
|
|
87
|
+
<div class="flex items-start justify-between gap-2">
|
|
88
|
+
<div class="flex items-center gap-2">
|
|
89
|
+
<FileText class="h-4 w-4 text-muted-foreground shrink-0 mt-0.5" />
|
|
90
|
+
<h3 class="text-sm font-semibold text-foreground group-hover:text-primary transition-colors">
|
|
91
|
+
{docTitle}
|
|
92
|
+
</h3>
|
|
93
|
+
</div>
|
|
94
|
+
<ArrowRight class="h-4 w-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity shrink-0 mt-0.5" />
|
|
95
|
+
</div>
|
|
96
|
+
{#if docDescription}
|
|
97
|
+
<p class="text-sm text-muted-foreground line-clamp-2 pl-6">
|
|
98
|
+
{docDescription}
|
|
99
|
+
</p>
|
|
100
|
+
{/if}
|
|
101
|
+
</a>
|
|
102
|
+
{/each}
|
|
103
|
+
</div>
|
|
104
|
+
{:else if !content}
|
|
105
|
+
<div class="flex flex-col items-center justify-center py-12 text-center">
|
|
106
|
+
<FileText class="h-10 w-10 text-muted-foreground mb-4" />
|
|
107
|
+
<p class="text-muted-foreground">No documents found in this category.</p>
|
|
108
|
+
</div>
|
|
109
|
+
{/if}
|
|
110
|
+
</div>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SpecraConfig } from '../../config.types.js';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
interface DocItem {
|
|
4
|
+
slug: string;
|
|
5
|
+
filePath: string;
|
|
6
|
+
version?: string;
|
|
7
|
+
meta?: {
|
|
8
|
+
title?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
sidebar_position?: number;
|
|
11
|
+
icon?: string;
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
};
|
|
14
|
+
title?: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
interface Props {
|
|
19
|
+
categoryPath: string;
|
|
20
|
+
version: string;
|
|
21
|
+
allDocs: DocItem[];
|
|
22
|
+
title?: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
content?: Snippet;
|
|
25
|
+
config: SpecraConfig;
|
|
26
|
+
}
|
|
27
|
+
declare const CategoryIndex: import("svelte").Component<Props, {}, "">;
|
|
28
|
+
type CategoryIndex = ReturnType<typeof CategoryIndex>;
|
|
29
|
+
export default CategoryIndex;
|