@aravindc26/velu 0.12.7 → 0.12.9
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/package.json +1 -1
- package/src/build.ts +13 -0
- package/src/cli.ts +51 -9
- package/src/engine/app/(docs)/[...slug]/layout.tsx +21 -537
- package/src/engine/app/_preview/[sessionId]/[...slug]/layout.tsx +96 -0
- package/src/engine/app/_preview/[sessionId]/[...slug]/page.tsx +298 -0
- package/src/engine/app/_preview/[sessionId]/layout.tsx +56 -0
- package/src/{preview-engine/app → engine/app/_preview}/[sessionId]/page.tsx +7 -3
- package/src/engine/app/_preview/api/sessions/[sessionId]/assets/[...path]/route.ts +51 -0
- package/src/{preview-engine/app → engine/app/_preview}/api/sessions/[sessionId]/init/route.ts +2 -2
- package/src/{preview-engine/app → engine/app/_preview}/api/sessions/[sessionId]/route.ts +3 -3
- package/src/{preview-engine/app → engine/app/_preview}/api/sessions/[sessionId]/sync/route.ts +2 -2
- package/src/{preview-engine/app → engine/app/_preview}/layout.tsx +4 -1
- package/src/engine/app/global.css +0 -3623
- package/src/engine/app/layout.tsx +4 -3
- package/src/engine/components/sidebar-links.tsx +11 -5
- package/src/engine/lib/docs-layout.tsx +605 -0
- package/src/engine/lib/layout.shared.ts +7 -7
- package/src/engine/lib/preview-config.ts +129 -0
- package/src/{preview-engine/lib/content-generator.ts → engine/lib/preview-content.ts} +242 -42
- package/src/engine/lib/source.ts +80 -97
- package/src/engine/lib/velu.ts +79 -55
- package/src/engine/mdx-components.tsx +14 -650
- package/src/engine/source.config.ts +11 -89
- package/src/engine/tsconfig.json +1 -0
- package/src/engine-core/components/assistant.tsx +361 -0
- package/src/engine-core/components/banner.tsx +80 -0
- package/src/engine-core/components/changelog-filters.tsx +114 -0
- package/src/engine-core/components/code-group.tsx +383 -0
- package/src/engine-core/components/color.tsx +118 -0
- package/src/engine-core/components/copy-page.tsx +223 -0
- package/src/engine-core/components/dropdown-switcher.tsx +142 -0
- package/src/engine-core/components/expandable.tsx +77 -0
- package/src/engine-core/components/header-tab-link.tsx +43 -0
- package/src/engine-core/components/icon.tsx +136 -0
- package/src/engine-core/components/image-zoom-fallback.tsx +147 -0
- package/src/engine-core/components/image.tsx +111 -0
- package/src/engine-core/components/lang-switcher.tsx +101 -0
- package/src/engine-core/components/manual-api-playground.tsx +154 -0
- package/src/engine-core/components/mermaid.tsx +142 -0
- package/src/engine-core/components/openapi-toc-sync.tsx +59 -0
- package/src/engine-core/components/openapi.tsx +1682 -0
- package/src/engine-core/components/page-feedback-api.test.ts +83 -0
- package/src/engine-core/components/page-feedback-api.ts +89 -0
- package/src/engine-core/components/page-feedback.tsx +200 -0
- package/src/engine-core/components/product-switcher.tsx +107 -0
- package/src/engine-core/components/prompt.tsx +90 -0
- package/src/engine-core/components/providers.tsx +21 -0
- package/src/engine-core/components/search.tsx +318 -0
- package/src/engine-core/components/sidebar-links.tsx +54 -0
- package/src/engine-core/components/synced-tabs.tsx +57 -0
- package/src/engine-core/components/theme-toggle.tsx +39 -0
- package/src/engine-core/components/toc-examples.tsx +110 -0
- package/src/engine-core/components/version-switcher.tsx +95 -0
- package/src/engine-core/components/view.tsx +344 -0
- package/src/engine-core/css/assistant.css +326 -0
- package/src/engine-core/css/copy-page.css +206 -0
- package/src/engine-core/css/search.css +142 -0
- package/src/engine-core/css/shared.css +3628 -0
- package/src/engine-core/lib/remark-plugins.ts +102 -0
- package/src/engine-core/lib/source-plugins.ts +105 -0
- package/src/engine-core/mdx-components.tsx +654 -0
- package/src/engine-core/types.ts +49 -0
- package/src/preview-engine/app/[sessionId]/[...slug]/page.tsx +0 -41
- package/src/preview-engine/app/[sessionId]/layout.tsx +0 -23
- package/src/preview-engine/app/global.css +0 -3
- package/src/preview-engine/lib/session-config.ts +0 -86
- package/src/preview-engine/lib/source.ts +0 -60
- package/src/preview-engine/next.config.mjs +0 -20
- package/src/preview-engine/postcss.config.mjs +0 -8
- package/src/preview-engine/source.config.ts +0 -26
- package/src/preview-engine/tsconfig.json +0 -32
- /package/src/{preview-engine/app → engine/app/_preview}/page.tsx +0 -0
- /package/src/{preview-engine/lib/auth.ts → engine/lib/preview-auth.ts} +0 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export type VeluIconLibrary = 'fontawesome' | 'lucide' | 'tabler';
|
|
2
|
+
|
|
3
|
+
export interface VeluDropdownOption {
|
|
4
|
+
dropdown: string;
|
|
5
|
+
slug: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
icon?: string;
|
|
8
|
+
iconType?: string;
|
|
9
|
+
tabSlugs: string[];
|
|
10
|
+
defaultPath: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface VeluProductOption {
|
|
14
|
+
product: string;
|
|
15
|
+
slug: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
icon?: string;
|
|
18
|
+
iconType?: string;
|
|
19
|
+
tabSlugs: string[];
|
|
20
|
+
defaultPath: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface VeluVersionOption {
|
|
24
|
+
version: string;
|
|
25
|
+
slug: string;
|
|
26
|
+
isDefault: boolean;
|
|
27
|
+
tabSlugs: string[];
|
|
28
|
+
defaultPath: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface VeluContextualOption {
|
|
32
|
+
id: string;
|
|
33
|
+
title: string;
|
|
34
|
+
description: string;
|
|
35
|
+
href?: string;
|
|
36
|
+
type: 'builtin' | 'custom';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface VeluAnchor {
|
|
40
|
+
anchor: string;
|
|
41
|
+
href?: string;
|
|
42
|
+
icon?: string;
|
|
43
|
+
iconType?: string;
|
|
44
|
+
color?: {
|
|
45
|
+
light: string;
|
|
46
|
+
dark: string;
|
|
47
|
+
};
|
|
48
|
+
hidden?: boolean;
|
|
49
|
+
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { notFound } from 'next/navigation';
|
|
2
|
-
import {
|
|
3
|
-
DocsBody,
|
|
4
|
-
DocsDescription,
|
|
5
|
-
DocsPage,
|
|
6
|
-
DocsTitle,
|
|
7
|
-
} from 'fumadocs-ui/layouts/notebook/page';
|
|
8
|
-
import { source } from '@/lib/source';
|
|
9
|
-
|
|
10
|
-
interface PageProps {
|
|
11
|
-
params: Promise<{ sessionId: string; slug: string[] }>;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export default async function PreviewPage({ params }: PageProps) {
|
|
15
|
-
const { sessionId, slug } = await params;
|
|
16
|
-
|
|
17
|
-
// The full slug for fumadocs lookup includes the session ID prefix
|
|
18
|
-
const fullSlug = [sessionId, ...slug];
|
|
19
|
-
const page = source.getPage(fullSlug);
|
|
20
|
-
|
|
21
|
-
if (!page) notFound();
|
|
22
|
-
|
|
23
|
-
const pageDataRecord = page.data as unknown as Record<string, unknown>;
|
|
24
|
-
const MDX = pageDataRecord.body as any;
|
|
25
|
-
if (typeof MDX !== 'function') notFound();
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<DocsPage
|
|
29
|
-
toc={pageDataRecord.toc as any}
|
|
30
|
-
footer={{ enabled: false }}
|
|
31
|
-
>
|
|
32
|
-
<DocsTitle>{page.data.title}</DocsTitle>
|
|
33
|
-
{page.data.description ? (
|
|
34
|
-
<DocsDescription>{page.data.description}</DocsDescription>
|
|
35
|
-
) : null}
|
|
36
|
-
<DocsBody>
|
|
37
|
-
<MDX />
|
|
38
|
-
</DocsBody>
|
|
39
|
-
</DocsPage>
|
|
40
|
-
);
|
|
41
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
2
|
-
import { DocsLayout } from 'fumadocs-ui/layouts/notebook';
|
|
3
|
-
import { getSessionPageTree } from '@/lib/source';
|
|
4
|
-
|
|
5
|
-
interface LayoutProps {
|
|
6
|
-
children: ReactNode;
|
|
7
|
-
params: Promise<{ sessionId: string }>;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export default async function SessionLayout({ children, params }: LayoutProps) {
|
|
11
|
-
const { sessionId } = await params;
|
|
12
|
-
const tree = getSessionPageTree(sessionId);
|
|
13
|
-
|
|
14
|
-
return (
|
|
15
|
-
<DocsLayout
|
|
16
|
-
tree={tree}
|
|
17
|
-
sidebar={{ collapsible: true }}
|
|
18
|
-
themeSwitch={{ enabled: false }}
|
|
19
|
-
>
|
|
20
|
-
{children}
|
|
21
|
-
</DocsLayout>
|
|
22
|
-
);
|
|
23
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Per-session configuration cache.
|
|
3
|
-
* Reads docs.json from workspace directories and caches the parsed config.
|
|
4
|
-
*/
|
|
5
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
6
|
-
import { join } from 'node:path';
|
|
7
|
-
|
|
8
|
-
const WORKSPACE_DIR = process.env.WORKSPACE_DIR || '/mnt/nfs_share/editor_sessions';
|
|
9
|
-
const PRIMARY_CONFIG_NAME = 'docs.json';
|
|
10
|
-
const LEGACY_CONFIG_NAME = 'velu.json';
|
|
11
|
-
|
|
12
|
-
interface SessionConfig {
|
|
13
|
-
name?: string;
|
|
14
|
-
description?: string;
|
|
15
|
-
title?: string;
|
|
16
|
-
theme?: string;
|
|
17
|
-
colors?: { primary?: string; light?: string; dark?: string };
|
|
18
|
-
navigation: {
|
|
19
|
-
tabs?: any[];
|
|
20
|
-
languages?: any[];
|
|
21
|
-
anchors?: any[];
|
|
22
|
-
[key: string]: unknown;
|
|
23
|
-
};
|
|
24
|
-
languages?: string[];
|
|
25
|
-
openapi?: unknown;
|
|
26
|
-
[key: string]: unknown;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
interface CachedSession {
|
|
30
|
-
config: SessionConfig;
|
|
31
|
-
rawConfig: Record<string, unknown>;
|
|
32
|
-
loadedAt: number;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const sessionCache = new Map<string, CachedSession>();
|
|
36
|
-
const CACHE_TTL_MS = 60_000; // 1 minute
|
|
37
|
-
|
|
38
|
-
function resolveWorkspaceConfigPath(sessionId: string): string | null {
|
|
39
|
-
const wsDir = join(WORKSPACE_DIR, sessionId);
|
|
40
|
-
const primary = join(wsDir, PRIMARY_CONFIG_NAME);
|
|
41
|
-
if (existsSync(primary)) return primary;
|
|
42
|
-
const legacy = join(wsDir, LEGACY_CONFIG_NAME);
|
|
43
|
-
if (existsSync(legacy)) return legacy;
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function getSessionConfig(sessionId: string): SessionConfig | null {
|
|
48
|
-
const cached = sessionCache.get(sessionId);
|
|
49
|
-
if (cached && Date.now() - cached.loadedAt < CACHE_TTL_MS) {
|
|
50
|
-
return cached.config;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const configPath = resolveWorkspaceConfigPath(sessionId);
|
|
54
|
-
if (!configPath) return null;
|
|
55
|
-
|
|
56
|
-
try {
|
|
57
|
-
const raw = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
58
|
-
const config = raw as SessionConfig;
|
|
59
|
-
sessionCache.set(sessionId, {
|
|
60
|
-
config,
|
|
61
|
-
rawConfig: raw,
|
|
62
|
-
loadedAt: Date.now(),
|
|
63
|
-
});
|
|
64
|
-
return config;
|
|
65
|
-
} catch {
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function getSessionRawConfig(sessionId: string): Record<string, unknown> | null {
|
|
71
|
-
getSessionConfig(sessionId); // ensure loaded
|
|
72
|
-
return sessionCache.get(sessionId)?.rawConfig ?? null;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export function clearSessionCache(sessionId: string): void {
|
|
76
|
-
sessionCache.delete(sessionId);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function getWorkspaceDir(sessionId: string): string {
|
|
80
|
-
return join(WORKSPACE_DIR, sessionId);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export function getSiteName(sessionId: string): string {
|
|
84
|
-
const config = getSessionConfig(sessionId);
|
|
85
|
-
return config?.name || config?.title || 'Docs Preview';
|
|
86
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { loader } from 'fumadocs-core/source';
|
|
2
|
-
import * as mdxCollections from 'fumadocs-mdx:collections/server';
|
|
3
|
-
|
|
4
|
-
const docsCollection = (mdxCollections as { docs?: { toFumadocsSource?: () => unknown } }).docs;
|
|
5
|
-
|
|
6
|
-
if (!docsCollection?.toFumadocsSource) {
|
|
7
|
-
throw new Error('MDX collections are not ready yet. Please retry in a moment.');
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const source = loader({
|
|
11
|
-
baseUrl: '/',
|
|
12
|
-
source: docsCollection.toFumadocsSource() as any,
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Get the page tree filtered to a specific session's content.
|
|
17
|
-
* The content directory has files at {sessionId}/{slug}.mdx,
|
|
18
|
-
* so the page tree has top-level folders per session.
|
|
19
|
-
*/
|
|
20
|
-
export function getSessionPageTree(sessionId: string) {
|
|
21
|
-
const fullTree = source.getPageTree();
|
|
22
|
-
const children = Array.isArray(fullTree.children) ? fullTree.children : [];
|
|
23
|
-
|
|
24
|
-
// Find the root folder matching this session ID
|
|
25
|
-
const sessionFolder = children.find((child: any) => {
|
|
26
|
-
if (child?.type !== 'folder') return false;
|
|
27
|
-
// The folder's URL or name should match the session ID
|
|
28
|
-
const urls = collectUrls(child);
|
|
29
|
-
for (const url of urls) {
|
|
30
|
-
const firstSegment = url.replace(/^\/+/, '').split('/')[0];
|
|
31
|
-
if (firstSegment === sessionId) return true;
|
|
32
|
-
}
|
|
33
|
-
return false;
|
|
34
|
-
}) as any;
|
|
35
|
-
|
|
36
|
-
if (sessionFolder && Array.isArray(sessionFolder.children)) {
|
|
37
|
-
return { ...fullTree, children: sessionFolder.children };
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Fallback: filter children by URL prefix
|
|
41
|
-
const filtered = children.filter((child: any) => {
|
|
42
|
-
const urls = collectUrls(child);
|
|
43
|
-
return urls.some((url: string) => {
|
|
44
|
-
const segments = url.replace(/^\/+/, '').split('/');
|
|
45
|
-
return segments[0] === sessionId;
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
return { ...fullTree, children: filtered };
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function collectUrls(node: any, out: string[] = []): string[] {
|
|
53
|
-
if (!node || typeof node !== 'object') return out;
|
|
54
|
-
if (typeof node.url === 'string') out.push(node.url);
|
|
55
|
-
if (node.index && typeof node.index.url === 'string') out.push(node.index.url);
|
|
56
|
-
if (Array.isArray(node.children)) {
|
|
57
|
-
for (const child of node.children) collectUrls(child, out);
|
|
58
|
-
}
|
|
59
|
-
return out;
|
|
60
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'node:path';
|
|
2
|
-
import { createMDX } from 'fumadocs-mdx/next';
|
|
3
|
-
|
|
4
|
-
const withMDX = createMDX({
|
|
5
|
-
configPath: './source.config.ts',
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
/** @type {import('next').NextConfig} */
|
|
9
|
-
const config = {
|
|
10
|
-
reactStrictMode: false,
|
|
11
|
-
devIndicators: false,
|
|
12
|
-
turbopack: {
|
|
13
|
-
root: '/',
|
|
14
|
-
},
|
|
15
|
-
images: {
|
|
16
|
-
unoptimized: true,
|
|
17
|
-
},
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export default withMDX(config);
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { defineConfig, defineDocs } from 'fumadocs-mdx/config';
|
|
2
|
-
import { metaSchema, pageSchema } from 'fumadocs-core/source/schema';
|
|
3
|
-
|
|
4
|
-
// Content directory: NFS-backed preview_content root.
|
|
5
|
-
// Each session writes to {PREVIEW_CONTENT_DIR}/{sessionId}/.
|
|
6
|
-
// fumadocs scans the entire directory; routes filter by session.
|
|
7
|
-
const contentDir = process.env.PREVIEW_CONTENT_DIR || './content';
|
|
8
|
-
|
|
9
|
-
export const docs = defineDocs({
|
|
10
|
-
dir: contentDir,
|
|
11
|
-
docs: {
|
|
12
|
-
schema: pageSchema,
|
|
13
|
-
},
|
|
14
|
-
meta: {
|
|
15
|
-
schema: metaSchema,
|
|
16
|
-
},
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
export default defineConfig({
|
|
20
|
-
mdxOptions: {
|
|
21
|
-
rehypeCodeOptions: ({
|
|
22
|
-
lazy: false,
|
|
23
|
-
fallbackLanguage: 'bash',
|
|
24
|
-
} as any),
|
|
25
|
-
},
|
|
26
|
-
});
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"baseUrl": ".",
|
|
4
|
-
"target": "ESNext",
|
|
5
|
-
"lib": ["dom", "dom.iterable", "esnext"],
|
|
6
|
-
"allowJs": true,
|
|
7
|
-
"skipLibCheck": true,
|
|
8
|
-
"strict": true,
|
|
9
|
-
"forceConsistentCasingInFileNames": true,
|
|
10
|
-
"noEmit": true,
|
|
11
|
-
"esModuleInterop": true,
|
|
12
|
-
"module": "esnext",
|
|
13
|
-
"moduleResolution": "bundler",
|
|
14
|
-
"resolveJsonModule": true,
|
|
15
|
-
"isolatedModules": true,
|
|
16
|
-
"jsx": "react-jsx",
|
|
17
|
-
"incremental": true,
|
|
18
|
-
"paths": {
|
|
19
|
-
"@/*": ["./*"],
|
|
20
|
-
"fumadocs-mdx:collections/*": [".source/*"]
|
|
21
|
-
},
|
|
22
|
-
"plugins": [{ "name": "next" }]
|
|
23
|
-
},
|
|
24
|
-
"include": [
|
|
25
|
-
"next-env.d.ts",
|
|
26
|
-
"**/*.ts",
|
|
27
|
-
"**/*.tsx",
|
|
28
|
-
".next/types/**/*.ts",
|
|
29
|
-
".next/dev/types/**/*.ts"
|
|
30
|
-
],
|
|
31
|
-
"exclude": ["node_modules"]
|
|
32
|
-
}
|
|
File without changes
|
|
File without changes
|