@brainfish-ai/devdoc 0.1.44 → 0.1.45
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
CHANGED
|
@@ -8,6 +8,7 @@ import rehypeSlug from 'rehype-slug';
|
|
|
8
8
|
// Note: rehype-pretty-code is dynamically imported to handle serverless environments
|
|
9
9
|
// where shiki may not be fully available
|
|
10
10
|
import { getProjectFile } from '@/lib/storage/blob';
|
|
11
|
+
import { remarkMermaid } from '@/lib/docs/mdx/remark-mermaid';
|
|
11
12
|
const STARTER_PATH = process.env.STARTER_PATH || 'devdoc-docs';
|
|
12
13
|
// Helper to get content root - supports both relative and absolute paths
|
|
13
14
|
function getContentRoot() {
|
|
@@ -68,7 +69,8 @@ export async function GET(request) {
|
|
|
68
69
|
mdxSource = await serialize(content, {
|
|
69
70
|
mdxOptions: {
|
|
70
71
|
remarkPlugins: [
|
|
71
|
-
remarkGfm
|
|
72
|
+
remarkGfm,
|
|
73
|
+
remarkMermaid
|
|
72
74
|
],
|
|
73
75
|
rehypePlugins: [
|
|
74
76
|
rehypeSlug,
|
|
@@ -86,7 +88,8 @@ export async function GET(request) {
|
|
|
86
88
|
mdxSource = await serialize(content, {
|
|
87
89
|
mdxOptions: {
|
|
88
90
|
remarkPlugins: [
|
|
89
|
-
remarkGfm
|
|
91
|
+
remarkGfm,
|
|
92
|
+
remarkMermaid
|
|
90
93
|
],
|
|
91
94
|
rehypePlugins: [
|
|
92
95
|
rehypeSlug
|
|
@@ -149,7 +152,8 @@ export async function GET(request) {
|
|
|
149
152
|
mdxSource = await serialize(content, {
|
|
150
153
|
mdxOptions: {
|
|
151
154
|
remarkPlugins: [
|
|
152
|
-
remarkGfm
|
|
155
|
+
remarkGfm,
|
|
156
|
+
remarkMermaid
|
|
153
157
|
],
|
|
154
158
|
rehypePlugins: [
|
|
155
159
|
rehypeSlug,
|
|
@@ -167,7 +171,8 @@ export async function GET(request) {
|
|
|
167
171
|
mdxSource = await serialize(content, {
|
|
168
172
|
mdxOptions: {
|
|
169
173
|
remarkPlugins: [
|
|
170
|
-
remarkGfm
|
|
174
|
+
remarkGfm,
|
|
175
|
+
remarkMermaid
|
|
171
176
|
],
|
|
172
177
|
rehypePlugins: [
|
|
173
178
|
rehypeSlug
|
|
@@ -6,6 +6,7 @@ import { MDXRemote } from 'next-mdx-remote';
|
|
|
6
6
|
import { useDocsNavigation } from '@/lib/docs-navigation-context';
|
|
7
7
|
import { useCodeCopy } from '@/hooks/use-code-copy';
|
|
8
8
|
import { NotFoundPage } from './not-found-page';
|
|
9
|
+
import { MDXErrorBoundary } from './mdx-error-boundary';
|
|
9
10
|
// Custom Link component for MDX - uses docs navigation context
|
|
10
11
|
function MdxLink({ href, children, ...props }) {
|
|
11
12
|
const docsNav = useDocsNavigation();
|
|
@@ -213,29 +214,65 @@ export function DocPage({ slug, onSearch }) {
|
|
|
213
214
|
const showHeader = !hideHeader && !isCustomMode;
|
|
214
215
|
// Custom mode: Full-width layout for landing pages
|
|
215
216
|
if (isCustomMode) {
|
|
216
|
-
return /*#__PURE__*/ _jsx(
|
|
217
|
-
|
|
218
|
-
className: "docs-page docs-page-custom docs-content w-full min-h-full",
|
|
219
|
-
style: {
|
|
220
|
-
background: background || 'var(--background)',
|
|
221
|
-
// Ensure the content fills the entire viewport width within the content area
|
|
222
|
-
marginLeft: 0,
|
|
223
|
-
marginRight: 0
|
|
224
|
-
},
|
|
217
|
+
return /*#__PURE__*/ _jsx(MDXErrorBoundary, {
|
|
218
|
+
slug: slug,
|
|
225
219
|
children: /*#__PURE__*/ _jsx("div", {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
220
|
+
ref: contentRef,
|
|
221
|
+
className: "docs-page docs-page-custom docs-content w-full min-h-full",
|
|
222
|
+
style: {
|
|
223
|
+
background: background || 'var(--background)',
|
|
224
|
+
// Ensure the content fills the entire viewport width within the content area
|
|
225
|
+
marginLeft: 0,
|
|
226
|
+
marginRight: 0
|
|
227
|
+
},
|
|
228
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
229
|
+
className: "docs-custom-content [&>*]:w-full",
|
|
230
|
+
children: /*#__PURE__*/ _jsx(MDXRemote, {
|
|
231
|
+
...pageData.mdxSource,
|
|
232
|
+
components: mdxComponents
|
|
233
|
+
})
|
|
230
234
|
})
|
|
231
235
|
})
|
|
232
236
|
});
|
|
233
237
|
}
|
|
234
238
|
// Wide mode: No prose wrapper (for landing pages with custom components)
|
|
235
239
|
if (isWideMode) {
|
|
236
|
-
return /*#__PURE__*/
|
|
240
|
+
return /*#__PURE__*/ _jsx(MDXErrorBoundary, {
|
|
241
|
+
slug: slug,
|
|
242
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
243
|
+
ref: contentRef,
|
|
244
|
+
className: "docs-page docs-content max-w-6xl mx-auto px-4 py-6 sm:px-8 sm:py-8",
|
|
245
|
+
children: [
|
|
246
|
+
showHeader && /*#__PURE__*/ _jsxs("div", {
|
|
247
|
+
className: "docs-page-header mb-6",
|
|
248
|
+
children: [
|
|
249
|
+
/*#__PURE__*/ _jsx("h1", {
|
|
250
|
+
className: "docs-content-title text-2xl sm:text-3xl font-bold mb-2 text-foreground",
|
|
251
|
+
children: pageData.frontmatter.title
|
|
252
|
+
}),
|
|
253
|
+
pageData.frontmatter.description && /*#__PURE__*/ _jsx("p", {
|
|
254
|
+
className: "docs-content-description text-lg text-muted-foreground",
|
|
255
|
+
children: pageData.frontmatter.description
|
|
256
|
+
})
|
|
257
|
+
]
|
|
258
|
+
}),
|
|
259
|
+
/*#__PURE__*/ _jsx("div", {
|
|
260
|
+
className: "docs-wide-content",
|
|
261
|
+
children: /*#__PURE__*/ _jsx(MDXRemote, {
|
|
262
|
+
...pageData.mdxSource,
|
|
263
|
+
components: mdxComponents
|
|
264
|
+
})
|
|
265
|
+
})
|
|
266
|
+
]
|
|
267
|
+
})
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
// Default mode: Standard documentation layout with prose
|
|
271
|
+
return /*#__PURE__*/ _jsx(MDXErrorBoundary, {
|
|
272
|
+
slug: slug,
|
|
273
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
237
274
|
ref: contentRef,
|
|
238
|
-
className: "docs-page docs-content max-w-
|
|
275
|
+
className: "docs-page docs-content max-w-4xl mx-auto px-4 py-6 sm:px-8 sm:py-8",
|
|
239
276
|
children: [
|
|
240
277
|
showHeader && /*#__PURE__*/ _jsxs("div", {
|
|
241
278
|
className: "docs-page-header mb-6",
|
|
@@ -251,40 +288,13 @@ export function DocPage({ slug, onSearch }) {
|
|
|
251
288
|
]
|
|
252
289
|
}),
|
|
253
290
|
/*#__PURE__*/ _jsx("div", {
|
|
254
|
-
className: "docs-
|
|
291
|
+
className: "docs-prose prose prose-sm max-w-none prose-headings:text-foreground prose-p:text-muted-foreground prose-strong:text-foreground prose-code:text-foreground prose-pre:bg-muted prose-code:bg-muted prose-code:px-1 prose-code:py-0.5 prose-code:rounded prose-pre:overflow-x-auto prose-table:w-full prose-th:text-left prose-th:p-3 prose-th:bg-muted prose-td:p-3 prose-td:border-b prose-td:border-border",
|
|
255
292
|
children: /*#__PURE__*/ _jsx(MDXRemote, {
|
|
256
293
|
...pageData.mdxSource,
|
|
257
294
|
components: mdxComponents
|
|
258
295
|
})
|
|
259
296
|
})
|
|
260
297
|
]
|
|
261
|
-
})
|
|
262
|
-
}
|
|
263
|
-
// Default mode: Standard documentation layout with prose
|
|
264
|
-
return /*#__PURE__*/ _jsxs("div", {
|
|
265
|
-
ref: contentRef,
|
|
266
|
-
className: "docs-page docs-content max-w-4xl mx-auto px-4 py-6 sm:px-8 sm:py-8",
|
|
267
|
-
children: [
|
|
268
|
-
showHeader && /*#__PURE__*/ _jsxs("div", {
|
|
269
|
-
className: "docs-page-header mb-6",
|
|
270
|
-
children: [
|
|
271
|
-
/*#__PURE__*/ _jsx("h1", {
|
|
272
|
-
className: "docs-content-title text-2xl sm:text-3xl font-bold mb-2 text-foreground",
|
|
273
|
-
children: pageData.frontmatter.title
|
|
274
|
-
}),
|
|
275
|
-
pageData.frontmatter.description && /*#__PURE__*/ _jsx("p", {
|
|
276
|
-
className: "docs-content-description text-lg text-muted-foreground",
|
|
277
|
-
children: pageData.frontmatter.description
|
|
278
|
-
})
|
|
279
|
-
]
|
|
280
|
-
}),
|
|
281
|
-
/*#__PURE__*/ _jsx("div", {
|
|
282
|
-
className: "docs-prose prose prose-sm max-w-none prose-headings:text-foreground prose-p:text-muted-foreground prose-strong:text-foreground prose-code:text-foreground prose-pre:bg-muted prose-code:bg-muted prose-code:px-1 prose-code:py-0.5 prose-code:rounded prose-pre:overflow-x-auto prose-table:w-full prose-th:text-left prose-th:p-3 prose-th:bg-muted prose-td:p-3 prose-td:border-b prose-td:border-border",
|
|
283
|
-
children: /*#__PURE__*/ _jsx(MDXRemote, {
|
|
284
|
-
...pageData.mdxSource,
|
|
285
|
-
components: mdxComponents
|
|
286
|
-
})
|
|
287
|
-
})
|
|
288
|
-
]
|
|
298
|
+
})
|
|
289
299
|
});
|
|
290
300
|
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
function _define_property(obj, key, value) {
|
|
3
|
+
if (key in obj) {
|
|
4
|
+
Object.defineProperty(obj, key, {
|
|
5
|
+
value: value,
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true
|
|
9
|
+
});
|
|
10
|
+
} else {
|
|
11
|
+
obj[key] = value;
|
|
12
|
+
}
|
|
13
|
+
return obj;
|
|
14
|
+
}
|
|
15
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
16
|
+
import { Component } from 'react';
|
|
17
|
+
import { Warning, ArrowClockwise, Code, FileText } from '@phosphor-icons/react';
|
|
18
|
+
/**
|
|
19
|
+
* Error boundary for MDX content rendering.
|
|
20
|
+
* Catches rendering errors and displays helpful guidance.
|
|
21
|
+
*/ export class MDXErrorBoundary extends Component {
|
|
22
|
+
static getDerivedStateFromError(error) {
|
|
23
|
+
return {
|
|
24
|
+
hasError: true,
|
|
25
|
+
error
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
componentDidCatch(error, errorInfo) {
|
|
29
|
+
console.error('[MDX Rendering Error]', error, errorInfo);
|
|
30
|
+
}
|
|
31
|
+
render() {
|
|
32
|
+
if (this.state.hasError) {
|
|
33
|
+
const errorMessage = this.state.error?.message || 'Unknown error';
|
|
34
|
+
const suggestions = getErrorSuggestions(errorMessage);
|
|
35
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
36
|
+
className: "docs-page docs-page-error w-full min-h-[200px] max-w-4xl mx-auto px-4 py-6 sm:px-8 sm:py-8",
|
|
37
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
38
|
+
className: "rounded-lg border border-amber-200 dark:border-amber-800 bg-amber-50 dark:bg-amber-950/50 p-6",
|
|
39
|
+
children: [
|
|
40
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
41
|
+
className: "flex items-start gap-3 mb-4",
|
|
42
|
+
children: [
|
|
43
|
+
/*#__PURE__*/ _jsx(Warning, {
|
|
44
|
+
className: "h-6 w-6 text-amber-600 dark:text-amber-400 flex-shrink-0 mt-0.5",
|
|
45
|
+
weight: "fill"
|
|
46
|
+
}),
|
|
47
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
48
|
+
children: [
|
|
49
|
+
/*#__PURE__*/ _jsx("h2", {
|
|
50
|
+
className: "text-lg font-semibold text-amber-900 dark:text-amber-100",
|
|
51
|
+
children: "Unable to render this page"
|
|
52
|
+
}),
|
|
53
|
+
/*#__PURE__*/ _jsx("p", {
|
|
54
|
+
className: "text-sm text-amber-700 dark:text-amber-300 mt-1",
|
|
55
|
+
children: "There's a syntax error in the MDX content that prevented rendering."
|
|
56
|
+
})
|
|
57
|
+
]
|
|
58
|
+
})
|
|
59
|
+
]
|
|
60
|
+
}),
|
|
61
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
62
|
+
className: "bg-amber-100 dark:bg-amber-900/50 rounded-md p-3 mb-4",
|
|
63
|
+
children: [
|
|
64
|
+
/*#__PURE__*/ _jsx("p", {
|
|
65
|
+
className: "text-xs font-medium text-amber-800 dark:text-amber-200 mb-1",
|
|
66
|
+
children: "Error message:"
|
|
67
|
+
}),
|
|
68
|
+
/*#__PURE__*/ _jsx("code", {
|
|
69
|
+
className: "text-sm text-amber-900 dark:text-amber-100 break-all",
|
|
70
|
+
children: errorMessage
|
|
71
|
+
})
|
|
72
|
+
]
|
|
73
|
+
}),
|
|
74
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
75
|
+
className: "space-y-3",
|
|
76
|
+
children: [
|
|
77
|
+
/*#__PURE__*/ _jsx("p", {
|
|
78
|
+
className: "text-sm font-medium text-amber-800 dark:text-amber-200",
|
|
79
|
+
children: "Common causes and fixes:"
|
|
80
|
+
}),
|
|
81
|
+
/*#__PURE__*/ _jsx("ul", {
|
|
82
|
+
className: "space-y-2",
|
|
83
|
+
children: suggestions.map((suggestion, index)=>/*#__PURE__*/ _jsxs("li", {
|
|
84
|
+
className: "flex items-start gap-2 text-sm text-amber-700 dark:text-amber-300",
|
|
85
|
+
children: [
|
|
86
|
+
/*#__PURE__*/ _jsx(suggestion.icon, {
|
|
87
|
+
className: "h-4 w-4 flex-shrink-0 mt-0.5",
|
|
88
|
+
weight: "bold"
|
|
89
|
+
}),
|
|
90
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
91
|
+
children: [
|
|
92
|
+
/*#__PURE__*/ _jsxs("span", {
|
|
93
|
+
className: "font-medium",
|
|
94
|
+
children: [
|
|
95
|
+
suggestion.title,
|
|
96
|
+
":"
|
|
97
|
+
]
|
|
98
|
+
}),
|
|
99
|
+
' ',
|
|
100
|
+
suggestion.description
|
|
101
|
+
]
|
|
102
|
+
})
|
|
103
|
+
]
|
|
104
|
+
}, index))
|
|
105
|
+
})
|
|
106
|
+
]
|
|
107
|
+
}),
|
|
108
|
+
/*#__PURE__*/ _jsxs("button", {
|
|
109
|
+
onClick: this.handleRetry,
|
|
110
|
+
className: "mt-6 inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-md bg-amber-200 dark:bg-amber-800 text-amber-900 dark:text-amber-100 hover:bg-amber-300 dark:hover:bg-amber-700 transition-colors",
|
|
111
|
+
children: [
|
|
112
|
+
/*#__PURE__*/ _jsx(ArrowClockwise, {
|
|
113
|
+
className: "h-4 w-4",
|
|
114
|
+
weight: "bold"
|
|
115
|
+
}),
|
|
116
|
+
"Try again"
|
|
117
|
+
]
|
|
118
|
+
})
|
|
119
|
+
]
|
|
120
|
+
})
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return this.props.children;
|
|
124
|
+
}
|
|
125
|
+
constructor(props){
|
|
126
|
+
super(props), _define_property(this, "handleRetry", ()=>{
|
|
127
|
+
this.setState({
|
|
128
|
+
hasError: false,
|
|
129
|
+
error: null
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
this.state = {
|
|
133
|
+
hasError: false,
|
|
134
|
+
error: null
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get context-aware error suggestions based on the error message
|
|
140
|
+
*/ function getErrorSuggestions(errorMessage) {
|
|
141
|
+
const suggestions = [];
|
|
142
|
+
// Check for common MDX errors
|
|
143
|
+
if (errorMessage.includes('Unexpected') || errorMessage.includes('Expected')) {
|
|
144
|
+
suggestions.push({
|
|
145
|
+
icon: Code,
|
|
146
|
+
title: 'JSX Syntax',
|
|
147
|
+
description: 'Check for unclosed tags, missing quotes in attributes, or invalid JSX expressions. All tags must be properly closed (e.g., <Image /> not <Image>).'
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
if (errorMessage.includes('is not defined') || errorMessage.includes('is not a function')) {
|
|
151
|
+
suggestions.push({
|
|
152
|
+
icon: Code,
|
|
153
|
+
title: 'Unknown Component',
|
|
154
|
+
description: 'A component used in this page may not be available. Check that all component names are spelled correctly and are supported.'
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
if (errorMessage.includes('mermaid') || errorMessage.includes('Mermaid')) {
|
|
158
|
+
suggestions.push({
|
|
159
|
+
icon: Code,
|
|
160
|
+
title: 'Mermaid Syntax',
|
|
161
|
+
description: 'Check your Mermaid diagram syntax. Ensure proper indentation and valid diagram type (flowchart, sequenceDiagram, etc.).'
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
if (errorMessage.includes('frontmatter') || errorMessage.includes('yaml')) {
|
|
165
|
+
suggestions.push({
|
|
166
|
+
icon: FileText,
|
|
167
|
+
title: 'Frontmatter Format',
|
|
168
|
+
description: 'Ensure frontmatter is valid YAML between --- markers at the top of the file.'
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
// Always add generic suggestions
|
|
172
|
+
suggestions.push({
|
|
173
|
+
icon: Code,
|
|
174
|
+
title: 'Curly Braces',
|
|
175
|
+
description: 'In MDX, curly braces {} are for JavaScript expressions. Use {"{"} and {"}"} to display literal braces.'
|
|
176
|
+
});
|
|
177
|
+
suggestions.push({
|
|
178
|
+
icon: FileText,
|
|
179
|
+
title: 'Special Characters',
|
|
180
|
+
description: 'Characters like <, >, and & may need to be escaped or wrapped in JSX expressions.'
|
|
181
|
+
});
|
|
182
|
+
return suggestions.slice(0, 4) // Limit to 4 suggestions
|
|
183
|
+
;
|
|
184
|
+
}
|