@clidey/dory 0.2.0 โ†’ 0.4.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/bin/dory.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { execSync } from 'child_process';
4
- import { existsSync, rmSync, mkdirSync, cpSync, readFileSync } from 'fs';
4
+ import { existsSync, rmSync, mkdirSync, cpSync, readFileSync, readdirSync } from 'fs';
5
5
  import { resolve, dirname } from 'path';
6
6
  import { fileURLToPath } from 'url'
7
7
  import http from 'http';
@@ -12,40 +12,63 @@ const __dirname = dirname(__filename);
12
12
 
13
13
  const commands = {
14
14
  build: () => {
15
- console.log('๐Ÿ—๏ธ Starting Dory build...');
15
+ console.log('๐ŸŸ Dory is ready to build your docs!');
16
+
17
+ // Clear the docs folder if it exists
18
+ const docsDir = resolve(__dirname, '..', 'docs');
19
+ if (existsSync(docsDir)) {
20
+ console.log('๐Ÿงน Tidying up the workspace...');
21
+ rmSync(docsDir, { recursive: true, force: true });
22
+ }
16
23
 
17
24
  // Check if dory.json exists in current directory
18
25
  const currentDir = process.cwd();
19
26
  const doryConfigPath = resolve(currentDir, 'dory.json');
20
27
 
21
28
  if (!existsSync(doryConfigPath)) {
22
- console.error('โŒ dory.json not found in current directory');
29
+ console.error('โŒ Oops! dory.json is missing from your project');
23
30
  process.exit(1);
24
31
  }
25
32
 
26
33
  // Read and validate dory.json
27
34
  try {
28
35
  const config = JSON.parse(readFileSync(doryConfigPath, 'utf8'));
29
- console.log(`๐Ÿ“‹ Using config: ${config.name || 'Unnamed project'}`);
36
+ console.log(`๐Ÿ“‹ Building: ${config.name || 'Your awesome project'}`);
30
37
  } catch (error) {
31
- console.error('โŒ Invalid dory.json file:', error.message);
38
+ console.error('โŒ Your dory.json seems to have some issues:', error.message);
32
39
  process.exit(1);
33
40
  }
34
41
 
35
- // Clear and prepare docs folder
36
- const docsDir = resolve(currentDir, 'docs');
37
- if (existsSync(docsDir)) {
38
- console.log('๐Ÿงน Clearing docs folder...');
39
- rmSync(docsDir, { recursive: true, force: true });
40
- }
41
42
  mkdirSync(docsDir, { recursive: true });
42
43
 
43
- // Copy dory.json to docs folder
44
+ console.log('๐Ÿ“ Gathering your project files...');
44
45
  cpSync(doryConfigPath, resolve(docsDir, 'dory.json'));
45
- console.log('๐Ÿ“„ Copied dory.json to docs folder');
46
+
47
+ const copyFiles = (src, dest) => {
48
+ if (existsSync(src)) {
49
+ if (existsSync(dest)) {
50
+ rmSync(dest, { recursive: true, force: true });
51
+ }
52
+ cpSync(src, dest, { recursive: true });
53
+ }
54
+ };
55
+
56
+ // Copy all files and directories except node_modules, dist, and .git
57
+ const excludeDirs = ['node_modules', 'dist', '.git', 'docs', 'pnpm-lock.yaml'];
58
+
59
+ const items = readdirSync(currentDir);
60
+ for (const item of items) {
61
+ if (!excludeDirs.includes(item)) {
62
+ const srcPath = resolve(currentDir, item);
63
+ const destPath = resolve(docsDir, item);
64
+ copyFiles(srcPath, destPath);
65
+ }
66
+ }
67
+
68
+ console.log('โœ… All files gathered successfully!');
46
69
 
47
70
  // Run the build command
48
- console.log('โšก Running build command...');
71
+ console.log('โšก Magic is happening...');
49
72
  try {
50
73
  execSync('npm run build', { stdio: 'inherit', cwd: __dirname });
51
74
  } catch (error) {
@@ -56,19 +79,23 @@ const commands = {
56
79
  // Check if dist folder was created
57
80
  const distDir = resolve(__dirname, '..', 'dist');
58
81
  if (existsSync(distDir)) {
59
- console.log('โœ… Build completed successfully!');
60
- console.log(`๐Ÿ“ฆ Build output available in: ${distDir}`);
61
- console.log('๐Ÿ“‹ Moving build output to current directory...');
82
+ console.log('๐ŸŽ‰ Build completed successfully!');
83
+ console.log('๐Ÿ“ฆ Moving your docs to the right place...');
62
84
  cpSync(distDir, resolve(currentDir, 'dist'), { recursive: true });
63
- console.log(`๐Ÿ“ฆ Build output moved to: ${resolve(currentDir, 'dist')}`);
85
+ console.log('โœจ Your docs are ready in the dist folder!');
64
86
  } else {
65
- console.log('โš ๏ธ Build completed but no dist folder found');
87
+ console.log('โš ๏ธ Build completed but no output found');
66
88
  }
67
89
  rmSync(distDir, { recursive: true, force: true });
90
+
91
+ // Revert docs folder back to original state
92
+ console.log('๐Ÿงน Cleaning up...');
93
+ rmSync(docsDir, { recursive: true, force: true });
94
+ console.log('โœ… All done!');
68
95
  },
69
96
 
70
97
  preview: () => {
71
- console.log('๐Ÿ‘€ Starting Dory preview...');
98
+ console.log('๐Ÿ‘€ Starting your docs preview...');
72
99
  const currentDir = process.cwd();
73
100
  const distDir = resolve(currentDir, 'dist');
74
101
  const port = process.env.PORT || 3000;
@@ -86,33 +113,31 @@ const commands = {
86
113
  });
87
114
 
88
115
  server.listen(port, () => {
89
- console.log(`๐Ÿš€ Serving Dory at http://localhost:${port}`);
116
+ console.log(`๐Ÿš€ Your docs are live at http://localhost:${port}`);
90
117
  });
91
118
  },
92
119
 
93
120
  help: () => {
94
121
  console.log(`
95
- ๐ŸŸ Dory CLI - Documentation Build Tool
122
+ ๐ŸŸ Dory CLI - Your Friendly Documentation Builder
96
123
 
97
124
  Usage:
98
125
  dory <command>
99
126
 
100
127
  Commands:
101
- build Build the documentation site
102
- - Requires dory.json in current directory
103
- - Clears and copies to docs folder
104
- - Runs build command
105
- - Creates dist folder with build output
128
+ build Build your documentation site
129
+ - Needs dory.json in your project
130
+ - Creates a beautiful dist folder
106
131
 
107
- preview Preview the built documentation site
108
- - Requires dist folder (run build first)
109
- - Starts preview server
132
+ preview Preview your built documentation
133
+ - Shows your docs in the browser
134
+ - Run build first!
110
135
 
111
136
  help Show this help message
112
137
 
113
138
  Examples:
114
- dory build # Build the documentation
115
- dory preview # Preview the built site
139
+ dory build # Build your docs
140
+ dory preview # Preview your docs
116
141
  `);
117
142
  }
118
143
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@clidey/dory",
3
3
  "private": false,
4
- "version": "0.2.0",
4
+ "version": "0.4.0",
5
5
  "type": "module",
6
6
  "description": "A CLI tool for building and previewing documentation sites",
7
7
  "keywords": [
@@ -41,10 +41,13 @@
41
41
  "@heroicons/react": "^2.2.0",
42
42
  "@mdx-js/preact": "^3.1.0",
43
43
  "@mdx-js/rollup": "^3.1.0",
44
+ "@preact/preset-vite": "^2.10.1",
44
45
  "@tailwindcss/vite": "^4.1.8",
46
+ "@types/react-highlight-words": "^0.20.0",
45
47
  "classnames": "^2.5.1",
46
48
  "flexsearch": "^0.8.205",
47
49
  "gray-matter": "^4.0.3",
50
+ "gzip-size-cli": "^5.1.0",
48
51
  "katex": "^0.16.22",
49
52
  "lucide-react": "^0.513.0",
50
53
  "mermaid": "^11.6.0",
@@ -54,19 +57,14 @@
54
57
  "react-highlight-words": "^0.21.0",
55
58
  "remark-gfm": "^4.0.1",
56
59
  "saas": "^1.0.0",
60
+ "sass-embedded": "^1.89.2",
57
61
  "sirv": "^3.0.1",
58
62
  "tailwindcss": "^4.1.8",
63
+ "typescript": "~5.8.3",
59
64
  "unist-util-visit": "^5.0.0",
65
+ "vite": "^6.3.5",
60
66
  "vite-plugin-mdx": "^3.6.1",
61
67
  "wouter-preact": "^3.7.1"
62
68
  },
63
- "devDependencies": {
64
- "@preact/preset-vite": "^2.10.1",
65
- "@types/react-highlight-words": "^0.20.0",
66
- "gzip-size-cli": "^5.1.0",
67
- "sass-embedded": "^1.89.2",
68
- "typescript": "~5.8.3",
69
- "vite": "^6.3.5"
70
- },
71
69
  "packageManager": "pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39"
72
70
  }
package/src/mdx/fence.tsx CHANGED
@@ -4,6 +4,7 @@ import { Code, CodeGroup, CodeGroupContext, supportedLanguages } from './code'
4
4
  import { MermaidRenderer } from './mermaid'
5
5
  import { Loading } from '../components/loading'
6
6
  import { useDarkMode } from '../utils/hooks'
7
+ import classNames from 'classnames'
7
8
 
8
9
 
9
10
  export function Fence({
@@ -34,7 +35,7 @@ export function Fence({
34
35
  theme={isDark ? themes.vsDark : themes.vsLight}>
35
36
  {({ className, style, tokens, getTokenProps }) => (
36
37
  <pre>
37
- <Code className={className} style={style} title={supportedLanguage}>
38
+ <Code className={classNames(className, "whitespace-pre-wrap")} style={style} title={supportedLanguage}>
38
39
  {tokens.map((line, lineIndex) => (
39
40
  <Fragment key={lineIndex}>
40
41
  {line
@@ -1,3 +1,4 @@
1
+ import { ExclamationTriangleIcon } from '@heroicons/react/24/outline'
1
2
  import classNames from 'classnames'
2
3
  import { useEffect, useMemo, useRef, useState } from 'preact/compat'
3
4
 
@@ -6,6 +7,7 @@ export function MermaidRenderer({ content }: { content: string }) {
6
7
  const [isFullscreen, setIsFullscreen] = useState(false)
7
8
  const [isLoaded, setIsLoaded] = useState(false)
8
9
  const [error, setError] = useState<string | null>(null)
10
+ const [isValid, setIsValid] = useState<boolean | null>(null)
9
11
 
10
12
  const diagramId = useMemo(() => `mermaid-${btoa(content).replace(/[^a-zA-Z0-9]/g, '').substring(0, 10)}`, [content])
11
13
 
@@ -15,8 +17,7 @@ export function MermaidRenderer({ content }: { content: string }) {
15
17
  const renderMermaid = async () => {
16
18
  try {
17
19
  const mermaid = (await import('mermaid')).default
18
- mermaid.initialize({ startOnLoad: true });
19
-
20
+
20
21
  if (!mounted || !mermaidRef.current) return
21
22
 
22
23
  mermaid.initialize({
@@ -24,14 +25,14 @@ export function MermaidRenderer({ content }: { content: string }) {
24
25
  theme: 'base',
25
26
  themeVariables: {
26
27
  fontSize: '14px',
27
- nodePadding: 20, // More padding inside nodes
28
+ nodePadding: 20,
28
29
  notePadding: 15,
29
- padding: 10, // Diagram-wide padding
30
- nodeBorderRadius: 8, // Rounded corners for nodes
30
+ padding: 10,
31
+ nodeBorderRadius: 8,
31
32
  },
32
33
  flowchart: {
33
- nodeSpacing: 50, // horizontal spacing between nodes
34
- rankSpacing: 80, // vertical spacing between layers
34
+ nodeSpacing: 50,
35
+ rankSpacing: 80,
35
36
  padding: 20,
36
37
  useMaxWidth: true,
37
38
  },
@@ -45,9 +46,20 @@ export function MermaidRenderer({ content }: { content: string }) {
45
46
  .replace(/^\s*style .*$/gm, '')
46
47
  .replace(/^\s*classDef .*$/gm, '')
47
48
  .replace(/^\s*class .*$/gm, '');
49
+
50
+ // Validate the mermaid syntax first
51
+ try {
52
+ await mermaid.parse(contentWithoutStyle)
53
+ setIsValid(true)
54
+ } catch (parseError) {
55
+ setIsValid(false)
56
+ if (mounted) {
57
+ setError(parseError instanceof Error ? parseError.message : 'Invalid diagram syntax')
58
+ }
59
+ return
60
+ }
48
61
 
49
62
  const { svg } = await mermaid.render(diagramId, contentWithoutStyle);
50
-
51
63
 
52
64
  if (mounted && mermaidRef.current) {
53
65
  mermaidRef.current.innerHTML = svg
@@ -56,6 +68,7 @@ export function MermaidRenderer({ content }: { content: string }) {
56
68
  } catch (err) {
57
69
  console.error('Mermaid rendering error:', err)
58
70
  if (mounted) {
71
+ setIsValid(false)
59
72
  setError(err instanceof Error ? err.message : 'Failed to render diagram')
60
73
  }
61
74
  }
@@ -72,10 +85,25 @@ export function MermaidRenderer({ content }: { content: string }) {
72
85
  setIsFullscreen(!isFullscreen)
73
86
  }
74
87
 
75
- if (error) {
88
+ if (error || isValid === false) {
76
89
  return (
77
- <div className="flex items-center justify-center py-8 text-red-400 bg-red-900/20 border border-red-800 rounded">
78
- <span>Error rendering diagram: {error}</span>
90
+ <div className="mermaid-wrapper my-8">
91
+ <div className="flex flex-col items-center justify-center py-12 px-6 text-center bg-gradient-to-br from-red-50 to-red-100 dark:from-red-900/20 dark:to-red-800/20 border-2 border-dashed border-red-300 dark:border-red-700 rounded-lg">
92
+ <div className="w-16 h-16 mb-4 flex items-center justify-center bg-red-100 dark:bg-red-900/30 rounded-full">
93
+ <ExclamationTriangleIcon className="w-8 h-8 text-red-500" />
94
+ </div>
95
+ <h3 className="text-lg font-semibold text-red-700 dark:text-red-300 mb-2">
96
+ Diagram Syntax Error
97
+ </h3>
98
+ <p className="text-red-600 dark:text-red-400 mb-4 max-w-md">
99
+ The Mermaid diagram contains invalid syntax and cannot be rendered.
100
+ </p>
101
+ <div className="bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded-md p-3 max-w-md">
102
+ <p className="text-sm text-red-700 dark:text-red-300 font-mono break-all">
103
+ {error}
104
+ </p>
105
+ </div>
106
+ </div>
79
107
  </div>
80
108
  )
81
109
  }