@clidey/dory 0.38.0 → 0.40.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@clidey/dory",
3
3
  "private": false,
4
- "version": "0.38.0",
4
+ "version": "0.40.0",
5
5
  "type": "module",
6
6
  "description": "A CLI tool for building and previewing documentation sites",
7
7
  "keywords": [
@@ -20,10 +20,7 @@
20
20
  "index.html",
21
21
  "vite.config.ts",
22
22
  "vite.config.embed-loader.ts",
23
- "vite.config.embed-widget.ts",
24
- "tsconfig.json",
25
- "tsconfig.app.json",
26
- "tsconfig.node.json"
23
+ "vite.config.embed-widget.ts"
27
24
  ],
28
25
  "repository": {
29
26
  "type": "git",
@@ -39,7 +36,7 @@
39
36
  "dev": "vite",
40
37
  "build": "npm run build:cli && tsc -b && vite build",
41
38
  "build:cli": "tsc -p tsconfig.bin.json",
42
- "build:docs": "tsc -b && vite build",
39
+ "build:docs": "vite build",
43
40
  "build:embed": "npm run build:embed:loader && npm run build:embed:widget",
44
41
  "build:embed:loader": "vite build -c vite.config.embed-loader.ts",
45
42
  "build:embed:widget": "vite build -c vite.config.embed-widget.ts",
@@ -47,21 +47,27 @@ export default function Routes() {
47
47
  useEffect(() => {
48
48
  setLoading(true);
49
49
  const loadRoutes = async () => {
50
- // For root path, load the first navigation page
51
- const targetPath = pathname === '/' ? ALL_NAVIGATION[0].groups[0].pages[0].href : pathname;
52
-
53
- const entries = await Promise.all(
54
- Object.entries(ALL_PAGES).filter(([path]) => path === targetPath).map(async ([path, loader]) => {
55
- const module = await loader();
56
- const routePath = pathname === '/' ? '/' : pathFromFilename(path);
57
- return {
58
- path: routePath,
59
- component: module.default,
60
- };
61
- })
62
- );
63
- setRoutes(entries);
64
- setLoading(false);
50
+ try {
51
+ // For root path, load the first navigation page
52
+ const targetPath = pathname === '/' ? ALL_NAVIGATION[0].groups[0].pages[0].href : pathname;
53
+
54
+ const entries = await Promise.all(
55
+ Object.entries(ALL_PAGES).filter(([path]) => path === targetPath).map(async ([path, loader]) => {
56
+ const module = await loader();
57
+ const routePath = pathname === '/' ? '/' : pathFromFilename(path);
58
+ return {
59
+ path: routePath,
60
+ component: module.default,
61
+ };
62
+ })
63
+ );
64
+ setRoutes(entries);
65
+ } catch (error) {
66
+ console.error('Failed to load route:', error);
67
+ setRoutes([]);
68
+ } finally {
69
+ setLoading(false);
70
+ }
65
71
  };
66
72
 
67
73
  loadRoutes();
@@ -23,6 +23,8 @@ export function htmlMetadataInjector(): Plugin {
23
23
  const siteName = config.name || 'Documentation';
24
24
  const defaultTitle = config.title || siteName;
25
25
  const defaultDescription = config.description || `${siteName} - Technical Documentation`;
26
+ const siteUrl = config.url || '';
27
+ const siteImage = config.image || './docs/favicon.svg';
26
28
 
27
29
  // Replace title
28
30
  html = html.replace(
@@ -54,6 +56,20 @@ export function htmlMetadataInjector(): Plugin {
54
56
  `<meta property="og:site_name" content="${siteName}" />`
55
57
  );
56
58
 
59
+ // Replace Open Graph image
60
+ html = html.replace(
61
+ /<meta property="og:image" content=".*?" \/>/,
62
+ `<meta property="og:image" content="${siteImage}" />`
63
+ );
64
+
65
+ // Replace Open Graph URL
66
+ if (siteUrl) {
67
+ html = html.replace(
68
+ /<meta property="og:url" content=".*?" \/>/,
69
+ `<meta property="og:url" content="${siteUrl}" />`
70
+ );
71
+ }
72
+
57
73
  // Replace Twitter title
58
74
  html = html.replace(
59
75
  /<meta name="twitter:title" content=".*?" \/>/,
@@ -66,6 +82,12 @@ export function htmlMetadataInjector(): Plugin {
66
82
  `<meta name="twitter:description" content="${defaultDescription}" />`
67
83
  );
68
84
 
85
+ // Replace Twitter image
86
+ html = html.replace(
87
+ /<meta name="twitter:image" content=".*?" \/>/,
88
+ `<meta name="twitter:image" content="${siteImage}" />`
89
+ );
90
+
69
91
  return html;
70
92
  } catch (error) {
71
93
  console.error('❌ Failed to parse dory.json for metadata injection:', error);
@@ -87,8 +87,11 @@ export interface DoryAnalytics {
87
87
 
88
88
  export interface DoryConfig {
89
89
  name: string;
90
- favicon: string;
90
+ title?: string;
91
+ description?: string;
92
+ image?: string;
91
93
  url?: string;
94
+ favicon: string;
92
95
  colors?: DoryColors;
93
96
  fonts?: DoryFonts;
94
97
  navigation: DoryNavigation;
package/src/ui/header.tsx CHANGED
@@ -69,15 +69,20 @@ export function Header({ className }: { className?: string }) {
69
69
  </div>
70
70
  <nav className="hidden md:block">
71
71
  <ul role="list" className="flex items-center gap-8">
72
- {ALL_NAVIGATION.map((tab) => (
73
- <TopLevelNavItem
74
- key={tab.title}
75
- href={tab.groups[0].pages[0].href}
76
- isActive={pathname.startsWith(`/${tab.groups[0].pages[0].href.split('/')[1]}`)}
77
- >
78
- {tab.title}
79
- </TopLevelNavItem>
80
- ))}
72
+ {ALL_NAVIGATION.map((tab) => {
73
+ const isActive = tab.groups.some(group =>
74
+ group.pages.some(page => page.href === pathname)
75
+ );
76
+ return (
77
+ <TopLevelNavItem
78
+ key={tab.title}
79
+ href={tab.groups[0].pages[0].href}
80
+ isActive={isActive}
81
+ >
82
+ {tab.title}
83
+ </TopLevelNavItem>
84
+ );
85
+ })}
81
86
  </ul>
82
87
  </nav>
83
88
  <div className="hidden md:block md:h-5 md:w-px md:bg-zinc-900/10 md:dark:bg-white/15" />
package/tsconfig.app.json DELETED
@@ -1,33 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
4
- "target": "ES2020",
5
- "useDefineForClassFields": true,
6
- "module": "ESNext",
7
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
8
- "skipLibCheck": true,
9
- "paths": {
10
- "react": ["./node_modules/preact/compat/"],
11
- "react-dom": ["./node_modules/preact/compat/"]
12
- },
13
-
14
- /* Bundler mode */
15
- "moduleResolution": "bundler",
16
- "allowImportingTsExtensions": true,
17
- "verbatimModuleSyntax": true,
18
- "moduleDetection": "force",
19
- "noEmit": true,
20
- "jsx": "react-jsx",
21
- "jsxImportSource": "preact",
22
-
23
- /* Linting */
24
- "strict": true,
25
- "noUnusedLocals": true,
26
- "noUnusedParameters": true,
27
- "erasableSyntaxOnly": true,
28
- "noFallthroughCasesInSwitch": true,
29
- "noUncheckedSideEffectImports": true
30
- },
31
- "include": ["src"],
32
- "exclude": ["src/plugins"]
33
- }
package/tsconfig.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "files": [],
3
- "references": [
4
- { "path": "./tsconfig.app.json" },
5
- { "path": "./tsconfig.node.json" }
6
- ]
7
- }
@@ -1,26 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
- "target": "ES2022",
5
- "lib": ["ES2023"],
6
- "module": "ESNext",
7
- "skipLibCheck": true,
8
- "types": ["node"],
9
-
10
- /* Bundler mode */
11
- "moduleResolution": "bundler",
12
- "allowImportingTsExtensions": true,
13
- "verbatimModuleSyntax": true,
14
- "moduleDetection": "force",
15
- "noEmit": true,
16
-
17
- /* Linting */
18
- "strict": true,
19
- "noUnusedLocals": true,
20
- "noUnusedParameters": true,
21
- "erasableSyntaxOnly": true,
22
- "noFallthroughCasesInSwitch": true,
23
- "noUncheckedSideEffectImports": true
24
- },
25
- "include": ["vite.config.ts", "src/plugins/**/*.ts", "bin/**/*.ts"]
26
- }