@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.
Files changed (74) hide show
  1. package/package.json +1 -1
  2. package/src/build.ts +13 -0
  3. package/src/cli.ts +51 -9
  4. package/src/engine/app/(docs)/[...slug]/layout.tsx +21 -537
  5. package/src/engine/app/_preview/[sessionId]/[...slug]/layout.tsx +96 -0
  6. package/src/engine/app/_preview/[sessionId]/[...slug]/page.tsx +298 -0
  7. package/src/engine/app/_preview/[sessionId]/layout.tsx +56 -0
  8. package/src/{preview-engine/app → engine/app/_preview}/[sessionId]/page.tsx +7 -3
  9. package/src/engine/app/_preview/api/sessions/[sessionId]/assets/[...path]/route.ts +51 -0
  10. package/src/{preview-engine/app → engine/app/_preview}/api/sessions/[sessionId]/init/route.ts +2 -2
  11. package/src/{preview-engine/app → engine/app/_preview}/api/sessions/[sessionId]/route.ts +3 -3
  12. package/src/{preview-engine/app → engine/app/_preview}/api/sessions/[sessionId]/sync/route.ts +2 -2
  13. package/src/{preview-engine/app → engine/app/_preview}/layout.tsx +4 -1
  14. package/src/engine/app/global.css +0 -3623
  15. package/src/engine/app/layout.tsx +4 -3
  16. package/src/engine/components/sidebar-links.tsx +11 -5
  17. package/src/engine/lib/docs-layout.tsx +605 -0
  18. package/src/engine/lib/layout.shared.ts +7 -7
  19. package/src/engine/lib/preview-config.ts +129 -0
  20. package/src/{preview-engine/lib/content-generator.ts → engine/lib/preview-content.ts} +242 -42
  21. package/src/engine/lib/source.ts +80 -97
  22. package/src/engine/lib/velu.ts +79 -55
  23. package/src/engine/mdx-components.tsx +14 -650
  24. package/src/engine/source.config.ts +11 -89
  25. package/src/engine/tsconfig.json +1 -0
  26. package/src/engine-core/components/assistant.tsx +361 -0
  27. package/src/engine-core/components/banner.tsx +80 -0
  28. package/src/engine-core/components/changelog-filters.tsx +114 -0
  29. package/src/engine-core/components/code-group.tsx +383 -0
  30. package/src/engine-core/components/color.tsx +118 -0
  31. package/src/engine-core/components/copy-page.tsx +223 -0
  32. package/src/engine-core/components/dropdown-switcher.tsx +142 -0
  33. package/src/engine-core/components/expandable.tsx +77 -0
  34. package/src/engine-core/components/header-tab-link.tsx +43 -0
  35. package/src/engine-core/components/icon.tsx +136 -0
  36. package/src/engine-core/components/image-zoom-fallback.tsx +147 -0
  37. package/src/engine-core/components/image.tsx +111 -0
  38. package/src/engine-core/components/lang-switcher.tsx +101 -0
  39. package/src/engine-core/components/manual-api-playground.tsx +154 -0
  40. package/src/engine-core/components/mermaid.tsx +142 -0
  41. package/src/engine-core/components/openapi-toc-sync.tsx +59 -0
  42. package/src/engine-core/components/openapi.tsx +1682 -0
  43. package/src/engine-core/components/page-feedback-api.test.ts +83 -0
  44. package/src/engine-core/components/page-feedback-api.ts +89 -0
  45. package/src/engine-core/components/page-feedback.tsx +200 -0
  46. package/src/engine-core/components/product-switcher.tsx +107 -0
  47. package/src/engine-core/components/prompt.tsx +90 -0
  48. package/src/engine-core/components/providers.tsx +21 -0
  49. package/src/engine-core/components/search.tsx +318 -0
  50. package/src/engine-core/components/sidebar-links.tsx +54 -0
  51. package/src/engine-core/components/synced-tabs.tsx +57 -0
  52. package/src/engine-core/components/theme-toggle.tsx +39 -0
  53. package/src/engine-core/components/toc-examples.tsx +110 -0
  54. package/src/engine-core/components/version-switcher.tsx +95 -0
  55. package/src/engine-core/components/view.tsx +344 -0
  56. package/src/engine-core/css/assistant.css +326 -0
  57. package/src/engine-core/css/copy-page.css +206 -0
  58. package/src/engine-core/css/search.css +142 -0
  59. package/src/engine-core/css/shared.css +3628 -0
  60. package/src/engine-core/lib/remark-plugins.ts +102 -0
  61. package/src/engine-core/lib/source-plugins.ts +105 -0
  62. package/src/engine-core/mdx-components.tsx +654 -0
  63. package/src/engine-core/types.ts +49 -0
  64. package/src/preview-engine/app/[sessionId]/[...slug]/page.tsx +0 -41
  65. package/src/preview-engine/app/[sessionId]/layout.tsx +0 -23
  66. package/src/preview-engine/app/global.css +0 -3
  67. package/src/preview-engine/lib/session-config.ts +0 -86
  68. package/src/preview-engine/lib/source.ts +0 -60
  69. package/src/preview-engine/next.config.mjs +0 -20
  70. package/src/preview-engine/postcss.config.mjs +0 -8
  71. package/src/preview-engine/source.config.ts +0 -26
  72. package/src/preview-engine/tsconfig.json +0 -32
  73. /package/src/{preview-engine/app → engine/app/_preview}/page.tsx +0 -0
  74. /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,3 +0,0 @@
1
- @import 'tailwindcss';
2
- @import 'fumadocs-ui/css/neutral.css';
3
- @import 'fumadocs-ui/css/preset.css';
@@ -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,8 +0,0 @@
1
- import { createRequire } from 'node:module';
2
- const require = createRequire(import.meta.url);
3
-
4
- export default {
5
- plugins: {
6
- '@tailwindcss/postcss': {},
7
- },
8
- };
@@ -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
- }