@clidey/dory 0.21.1 → 0.21.4

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.
@@ -0,0 +1,12 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(pnpm add:*)",
5
+ "Bash(mv:*)",
6
+ "Bash(pnpm exec tsx:*)",
7
+ "Bash(npx tsx:*)"
8
+ ],
9
+ "deny": [],
10
+ "ask": []
11
+ }
12
+ }
package/CLAUDE.md CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
  This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
4
 
5
+ ## Communication Style
6
+ - Maintain a professional, neutral tone in all communications
7
+ - Use exclamation points sparingly and only when genuinely necessary
8
+ - Approach problems with the measured perspective of an experienced software engineer
9
+ - Keep a level head when discussing technical challenges and solutions
10
+ - Focus on clear, factual explanations without unnecessary enthusiasm
11
+
12
+ ## Development requirements
13
+ To develop Dory, follow the below requirements every time you do a task:
14
+ 1. Clean code is paramount—make sure it is easy to understand and follow
15
+ 2. Do not overengineer if you can help it—only add what is required.
16
+ 3. Do not remove or modify existing functionally UNLESS you have to and UNLESS you can justify it.
17
+ 4. Do not change existing variable names UNLESS absolutely necessary.
18
+ 5. Do not leave unused code lying around.
19
+ 6. Ask as many questions as you have to in order to understand your task.
20
+ 7. You MUST use multiple subagents wherever possible to help you accomplish your task faster.
21
+
5
22
  ## Project Overview
6
23
 
7
24
  Dory is a lightweight static site generator for technical documentation, published as `@clidey/dory` on npm. It uses Preact, Vite, TypeScript, and Tailwind CSS.
package/README.md CHANGED
@@ -10,7 +10,6 @@ Dory is a lightweight static site generator built for developers who want fast,
10
10
 
11
11
  Built with [Preact](https://preactjs.com/), [Vite](https://vitejs.dev/), [Tailwind CSS](https://tailwindcss.com/), [Mermaid](https://mermaid.js.org/), and [TypeScript](https://www.typescriptlang.org/).
12
12
 
13
- ---
14
13
 
15
14
  ## 🚀 Why Dory?
16
15
 
@@ -23,7 +22,10 @@ Dory is:
23
22
  - 🌐 **Portable** — No SSR, no lock-in, deploy anywhere.
24
23
  - 🧩 **Flexible** — Hackable theme, readable codebase, minimal magic.
25
24
 
26
- ---
25
+
26
+ ## 🎬 Quick Demo
27
+
28
+ https://github.com/user-attachments/assets/5a2840ce-a0b9-41fd-8d15-3ee1d2356f07
27
29
 
28
30
  ## ✨ Features
29
31
 
@@ -36,7 +38,6 @@ Dory is:
36
38
  - 🌍 Deploy to Netlify, Vercel, S3, GitHub Pages — your call
37
39
  - 🌐 HTTP client for testing API endpoints (automatic inference from openapi.json)
38
40
 
39
- ---
40
41
 
41
42
  ## 📦 CLI Installation
42
43
 
@@ -71,6 +72,24 @@ Previews the built documentation site:
71
72
  dory preview
72
73
  ```
73
74
 
75
+ #### `dory verify:content`
76
+ Verifies that MDX content compiles without errors:
77
+ - Silent on success (no output means no errors)
78
+ - Shows detailed error messages on failure
79
+ - Uses the same preprocessing as the main build
80
+ - Perfect for automated testing and debugging
81
+
82
+ ```bash
83
+ # Verify content directly
84
+ dory verify:content --content "# Hello World\n\nThis is a test."
85
+
86
+ # Verify content from file (recommended for complex content)
87
+ dory verify:content --file content.mdx
88
+
89
+ # Development repository usage:
90
+ pnpm exec tsx bin/dory.ts verify:content --file content.mdx
91
+ ```
92
+
74
93
  #### `dory help`
75
94
  Shows CLI usage information:
76
95
 
@@ -78,7 +97,6 @@ Shows CLI usage information:
78
97
  dory help
79
98
  ```
80
99
 
81
- ---
82
100
 
83
101
  ## 🧑‍💻 Development Setup
84
102
 
@@ -93,7 +111,6 @@ git clone https://github.com/clidey/dory.git
93
111
  cd dory
94
112
  ````
95
113
 
96
- ---
97
114
 
98
115
  ### 2️⃣ Install Dependencies
99
116
 
@@ -146,7 +163,6 @@ pnpm run build
146
163
 
147
164
  This will create a `dist` directory containing the fully built static site, ready to be served.
148
165
 
149
- ---
150
166
 
151
167
  ## 🐳 Docker Deployment (Optional)
152
168
 
@@ -176,8 +192,6 @@ docker run -it -p 8080:80 docs:1.0.0
176
192
 
177
193
  > The site will be available at `http://localhost:8080` inside your browser.
178
194
 
179
- ---
180
-
181
195
  ## 📂 Notes
182
196
 
183
197
  * `pnpm run build` creates the static site inside the `dist` folder, which can be served using any static file server.
@@ -192,4 +206,3 @@ We’re actively improving Dory. Here’s what’s on deck:
192
206
  * [ ] 🎨 **Themes** — full theming support with a flexible theme API
193
207
  * [ ] 🌐 **Multi-language Support** — internationalization (i18n) & localization (l10n)
194
208
  * [ ] 🚀 **GraphQL Client** — integrated GraphQL playground and client support
195
- * [ ] 🔄 **WebSocket Client** — built-in WebSocket utilities for real-time API demos
@@ -1,10 +1,11 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env -S npx tsx
2
2
 
3
+ // @ts-nocheck - gang
3
4
  import { execSync } from 'child_process';
4
5
  import { existsSync, rmSync, mkdirSync, cpSync, readFileSync, readdirSync } from 'fs';
5
6
  import { resolve, dirname } from 'path';
6
- import { fileURLToPath } from 'url'
7
- import http from 'http';
7
+ import { fileURLToPath } from 'url';
8
+ import { createServer } from 'http';
8
9
  import sirv from 'sirv';
9
10
 
10
11
  const __filename = fileURLToPath(import.meta.url);
@@ -108,7 +109,7 @@ const commands = {
108
109
  brotli: true,
109
110
  });
110
111
 
111
- const server = http.createServer((req, res) => {
112
+ const server = createServer((req, res) => {
112
113
  serve(req, res);
113
114
  });
114
115
 
@@ -117,6 +118,61 @@ const commands = {
117
118
  });
118
119
  },
119
120
 
121
+ 'verify:content': async () => {
122
+ const args = process.argv.slice(3);
123
+ let content = '';
124
+ let fileName = '';
125
+
126
+ // Parse arguments
127
+ for (let i = 0; i < args.length; i++) {
128
+ if (args[i] === '--content' && i + 1 < args.length) {
129
+ content = args[i + 1];
130
+ break;
131
+ } else if (args[i] === '--file' && i + 1 < args.length) {
132
+ const filePath = args[i + 1];
133
+ if (!existsSync(filePath)) {
134
+ console.error(`❌ Error: File not found: ${filePath}`);
135
+ process.exit(1);
136
+ }
137
+ content = readFileSync(filePath, 'utf8');
138
+ fileName = filePath;
139
+ break;
140
+ }
141
+ }
142
+
143
+ if (!content) {
144
+ console.error('❌ Error: --content or --file argument is required');
145
+ console.log('Usage: dory verify:content --content "<mdx-content>" | --file <path-to-mdx-file>');
146
+ process.exit(1);
147
+ }
148
+
149
+ try {
150
+ // Use the shared MDX processor that matches the main build exactly
151
+ const { verifyMdxContent } = await import('../src/mdx/processor.ts');
152
+ const result = await verifyMdxContent(content, fileName);
153
+
154
+ if (!result.valid) {
155
+ throw result.error;
156
+ }
157
+
158
+ // Silent success - no output means no errors
159
+
160
+ } catch (error) {
161
+ console.error('❌ MDX compilation failed:');
162
+ console.error(error.message);
163
+
164
+ // Provide more detailed error information if available
165
+ if (error.line !== undefined && error.column !== undefined) {
166
+ console.error(` at line ${error.line}, column ${error.column}`);
167
+ }
168
+ if (error.source) {
169
+ console.error(' Source:', error.source);
170
+ }
171
+
172
+ process.exit(1);
173
+ }
174
+ },
175
+
120
176
  help: () => {
121
177
  console.log(`
122
178
  🐟 Dory CLI - Your Friendly Documentation Builder
@@ -125,19 +181,26 @@ Usage:
125
181
  dory <command>
126
182
 
127
183
  Commands:
128
- build Build your documentation site
129
- - Needs dory.json in your project
130
- - Creates a beautiful dist folder
131
-
132
- preview Preview your built documentation
133
- - Shows your docs in the browser
134
- - Run build first!
135
-
136
- help Show this help message
184
+ build Build your documentation site
185
+ - Needs dory.json in your project
186
+ - Creates a beautiful dist folder
187
+
188
+ verify:content Verify that MDX content compiles without errors
189
+ - Silent on success, shows errors on failure
190
+ - Uses the same preprocessing as the main build
191
+ - Accepts --content or --file arguments
192
+
193
+ preview Preview your built documentation
194
+ - Shows your docs in the browser
195
+ - Run build first!
196
+
197
+ help Show this help message
137
198
 
138
199
  Examples:
139
- dory build # Build your docs
140
- dory preview # Preview your docs
200
+ dory build # Build your docs
201
+ dory verify:content --content "# Hello World" # Verify MDX content
202
+ dory verify:content --file content.mdx # Verify MDX from file
203
+ dory preview # Preview your docs
141
204
  `);
142
205
  }
143
206
  };
@@ -145,12 +208,19 @@ Examples:
145
208
  // Parse command line arguments
146
209
  const command = process.argv[2];
147
210
 
148
- if (!command || command === 'help' || command === '--help' || command === '-h') {
149
- commands.help();
150
- } else if (commands[command]) {
151
- commands[command]();
152
- } else {
153
- console.error(`❌ Unknown command: ${command}`);
154
- console.log('Run "dory help" for usage information');
211
+ async function runCommand() {
212
+ if (!command || command === 'help' || command === '--help' || command === '-h') {
213
+ commands.help();
214
+ } else if (commands[command]) {
215
+ await commands[command]();
216
+ } else {
217
+ console.error(`❌ Unknown command: ${command}`);
218
+ console.log('Run "dory help" for usage information');
219
+ process.exit(1);
220
+ }
221
+ }
222
+
223
+ runCommand().catch((error) => {
224
+ console.error('❌ Command failed:', error.message);
155
225
  process.exit(1);
156
- }
226
+ });
package/k8s/Dockerfile CHANGED
@@ -8,7 +8,7 @@ RUN apk add --no-cache git
8
8
  COPY ./docs/logo/logo.svg /app/docs/logo/logo.svg
9
9
  COPY ./k8s/config/nginx-default.conf /app/k8s/config/nginx-default.conf
10
10
 
11
- RUN npm install -g @clidey/dory@0.21.0
11
+ RUN npm install -g @clidey/dory@0.21.1
12
12
  EXPOSE 3000
13
13
 
14
14
  CMD ["dory", "preview"]
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@clidey/dory",
3
3
  "private": false,
4
- "version": "0.21.1",
4
+ "version": "0.21.4",
5
5
  "type": "module",
6
6
  "description": "A CLI tool for building and previewing documentation sites",
7
7
  "keywords": [
@@ -12,7 +12,7 @@
12
12
  "static-site"
13
13
  ],
14
14
  "bin": {
15
- "dory": "./bin/dory.js"
15
+ "dory": "./bin/dory.ts"
16
16
  },
17
17
  "repository": {
18
18
  "type": "git",
@@ -24,12 +24,6 @@
24
24
  "bugs": {
25
25
  "url": "https://github.com/clidey/dory/issues"
26
26
  },
27
- "scripts": {
28
- "dev": "vite",
29
- "build": "tsc -b && vite build",
30
- "preview": "vite preview",
31
- "publish": "npm publish --access public"
32
- },
33
27
  "dependencies": {
34
28
  "@algolia/autocomplete-core": "^1.19.2",
35
29
  "@fortawesome/fontawesome-svg-core": "^6.7.2",
@@ -39,6 +33,7 @@
39
33
  "@fortawesome/react-fontawesome": "^0.2.2",
40
34
  "@headlessui/react": "^2.2.4",
41
35
  "@heroicons/react": "^2.2.0",
36
+ "@mdx-js/mdx": "^3.1.0",
42
37
  "@mdx-js/preact": "^3.1.0",
43
38
  "@mdx-js/rollup": "^3.1.0",
44
39
  "@preact/preset-vite": "^2.10.1",
@@ -60,12 +55,19 @@
60
55
  "sass-embedded": "^1.89.2",
61
56
  "sirv": "^3.0.1",
62
57
  "tailwindcss": "^4.1.8",
58
+ "tsx": "^4.20.4",
63
59
  "typescript": "~5.8.3",
64
60
  "unist-util-visit": "^5.0.0",
65
61
  "vite": "^6.3.5",
66
62
  "vite-plugin-mdx": "^3.6.1",
67
- "wouter-preact": "^3.7.1",
63
+ "wouter-preact": "^3.7.1"
64
+ },
65
+ "devDependencies": {
68
66
  "@types/node": "^24.0.12"
69
67
  },
70
- "packageManager": "pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39"
71
- }
68
+ "scripts": {
69
+ "dev": "vite",
70
+ "build": "tsc -b && vite build",
71
+ "preview": "vite preview"
72
+ }
73
+ }
Binary file
@@ -0,0 +1,12 @@
1
+ import remarkGfm from 'remark-gfm';
2
+ import { remarkSafeVars } from '../plugins/sanitize.ts';
3
+
4
+ /**
5
+ * Shared MDX configuration used by both main build (vite.config.ts)
6
+ * and CLI build:file command (bin/dory.js)
7
+ */
8
+ export const getMdxConfig = (isDevelopment = false) => ({
9
+ providerImportSource: '@mdx-js/preact',
10
+ remarkPlugins: [remarkGfm, remarkSafeVars],
11
+ development: isDevelopment,
12
+ });
@@ -0,0 +1,12 @@
1
+ import remarkGfm from 'remark-gfm';
2
+ import { remarkSafeVars } from '../plugins/sanitize';
3
+
4
+ /**
5
+ * Shared MDX configuration used by both main build (vite.config.ts)
6
+ * and CLI build:file command (bin/dory.js)
7
+ */
8
+ export const getMdxConfig = (isDevelopment: boolean = false) => ({
9
+ providerImportSource: '@mdx-js/preact',
10
+ remarkPlugins: [remarkGfm, remarkSafeVars],
11
+ development: isDevelopment,
12
+ });
@@ -0,0 +1,174 @@
1
+ import { compile } from '@mdx-js/mdx';
2
+ import { preprocessMdxTags } from '../plugins/sanitize';
3
+ import { getMdxConfig } from '../config/mdx';
4
+
5
+ export interface ProcessMdxOptions {
6
+ isDevelopment?: boolean;
7
+ fileName?: string;
8
+ }
9
+
10
+ /**
11
+ * SINGLE SOURCE OF TRUTH for MDX preprocessing.
12
+ *
13
+ * This processor is used by:
14
+ * - CLI verify:content command (bin/dory.ts) - full processing + compilation
15
+ * - Vite build via unified-mdx-plugin.ts - preprocessing only
16
+ *
17
+ * ALL MDX processing steps should be added here to ensure consistency.
18
+ */
19
+ export async function preprocessMdxContent(
20
+ content: string,
21
+ fileName: string = 'content.mdx'
22
+ ): Promise<{
23
+ success: boolean;
24
+ processedContent?: string;
25
+ error?: Error;
26
+ }> {
27
+ try {
28
+ // Step 1: Apply preprocessor (handles MDX tags, code blocks, etc.)
29
+ const preprocessor = preprocessMdxTags();
30
+ let processedContent = content;
31
+
32
+ if (preprocessor.transform) {
33
+ const result = preprocessor.transform(content, fileName);
34
+ if (result && typeof result === 'object' && result.code) {
35
+ processedContent = result.code;
36
+ } else if (typeof result === 'string') {
37
+ processedContent = result;
38
+ }
39
+ }
40
+
41
+ // Step 2: Convert URLs in angle brackets to markdown links
42
+ // Handles cases like <https://example.com> which MDX would interpret as JSX
43
+ // But preserves them inside code blocks
44
+
45
+ // Process line by line to handle code blocks correctly
46
+ const lines = processedContent.split('\n');
47
+ let inCodeBlock = false;
48
+
49
+ processedContent = lines.map(line => {
50
+ // Check if we're entering or leaving a code block (with optional indentation)
51
+ if (line.trim().startsWith('```')) {
52
+ inCodeBlock = !inCodeBlock;
53
+ return line;
54
+ }
55
+
56
+ // Don't process lines inside code blocks
57
+ if (inCodeBlock) {
58
+ return line;
59
+ }
60
+
61
+ // For lines outside code blocks, preserve inline code
62
+ // More robust regex that handles inline code with potential spaces
63
+ // Matches: `...` including multi-line content
64
+ let result = '';
65
+ let lastIndex = 0;
66
+
67
+ // Find all inline code spans in the line
68
+ const inlineCodeRegex = /`([^`]+)`/g;
69
+ let match;
70
+
71
+ while ((match = inlineCodeRegex.exec(line)) !== null) {
72
+ // Process text before the inline code
73
+ const beforeCode = line.substring(lastIndex, match.index);
74
+ result += beforeCode.replace(/<(https?:\/\/[^\s>]+)>/g, '[$1]($1)');
75
+
76
+ // Keep inline code as-is
77
+ result += match[0];
78
+
79
+ lastIndex = match.index + match[0].length;
80
+ }
81
+
82
+ // Process remaining text after last inline code (or entire line if no inline code)
83
+ const remainingText = line.substring(lastIndex);
84
+ result += remainingText.replace(/<(https?:\/\/[^\s>]+)>/g, '[$1]($1)');
85
+
86
+ return result;
87
+ }).join('\n');
88
+
89
+ // Step 3: Add any future preprocessing steps here
90
+ // Example: processedContent = await yourNewPreprocessor(processedContent);
91
+ // Example: processedContent = removeHTMLComments(processedContent);
92
+ // Example: processedContent = expandCustomShortcodes(processedContent);
93
+ // ALL preprocessing added here will automatically apply to:
94
+ // - CLI commands (verify:content)
95
+ // - Vite build (pnpm run build)
96
+ // - Vite dev server (pnpm run dev)
97
+
98
+ return {
99
+ success: true,
100
+ processedContent
101
+ };
102
+ } catch (error) {
103
+ return {
104
+ success: false,
105
+ error: error as Error
106
+ };
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Process and compile MDX content through the full pipeline.
112
+ * Used by CLI commands that need the compiled output.
113
+ */
114
+ export async function processMdxContent(
115
+ content: string,
116
+ options: ProcessMdxOptions = {}
117
+ ): Promise<{
118
+ success: boolean;
119
+ compiled?: any;
120
+ error?: Error;
121
+ processedContent?: string;
122
+ }> {
123
+ const { isDevelopment = false, fileName = 'content.mdx' } = options;
124
+
125
+ try {
126
+ // Step 1: Preprocess
127
+ const preprocessResult = await preprocessMdxContent(content, fileName);
128
+ if (!preprocessResult.success) {
129
+ return {
130
+ success: false,
131
+ error: preprocessResult.error
132
+ };
133
+ }
134
+
135
+ const processedContent = preprocessResult.processedContent || content;
136
+
137
+ // Step 2: Compile MDX with the same config as main build
138
+ const mdxConfig = getMdxConfig(isDevelopment);
139
+ const compiled = await compile(processedContent, {
140
+ ...mdxConfig,
141
+ });
142
+
143
+ return {
144
+ success: true,
145
+ compiled,
146
+ processedContent
147
+ };
148
+ } catch (error) {
149
+ return {
150
+ success: false,
151
+ error: error as Error
152
+ };
153
+ }
154
+ }
155
+
156
+ /**
157
+ * Verify MDX content can be compiled without errors.
158
+ * Uses the same processing pipeline as processMdxContent.
159
+ */
160
+ export async function verifyMdxContent(
161
+ content: string,
162
+ fileName?: string
163
+ ): Promise<{ valid: boolean; error?: Error }> {
164
+ const result = await processMdxContent(content, { fileName });
165
+
166
+ if (result.success) {
167
+ return { valid: true };
168
+ } else {
169
+ return {
170
+ valid: false,
171
+ error: result.error
172
+ };
173
+ }
174
+ }
@@ -83,9 +83,23 @@ export function preprocessMdxTags() {
83
83
  // Remove leading whitespace from code fence blocks
84
84
  let processed = code.replace(/^(\s+)(```\w*)/gm, '$2');
85
85
 
86
+ // Handle self-closing tags first (like <VideoPlayer />)
87
+ processed = processed.replace(/<([A-Za-z][A-Za-z0-9]*)[^>]*\/>/g, (match, tag, offset) => {
88
+ // If inside a code block, do not touch
89
+ if (isInsideCodeBlock(processed, offset)) {
90
+ return match;
91
+ }
92
+
93
+ // If unknown component, treat as text
94
+ if (!KNOWN_COMPONENTS.includes(tag)) {
95
+ return `\`${match}\``;
96
+ }
97
+ return match;
98
+ });
99
+
86
100
  // Only replace unrecognized <someTag> with `"<someTag>"` if NOT inside a code block
87
- // This regex finds all <tag> occurrences
88
- processed = processed.replace(/<([a-z][a-z0-9]*)>/gi, (match, tag, offset) => {
101
+ // This regex finds all <tag> occurrences (fixed to handle uppercase)
102
+ processed = processed.replace(/<([A-Za-z][A-Za-z0-9]*)>/g, (match, tag, offset) => {
89
103
  // If inside a code block, do not touch
90
104
  if (isInsideCodeBlock(processed, offset)) {
91
105
  return match;
@@ -111,8 +125,8 @@ export function preprocessMdxTags() {
111
125
  return `\`<${tag}>\``;
112
126
  });
113
127
 
114
- // This regex finds all <tag> and </tag> occurrences
115
- processed = processed.replace(/<\/?([a-z][a-z0-9]*)>/gi, (match, tag, offset) => {
128
+ // This regex finds all <tag> and </tag> occurrences (fixed to handle uppercase)
129
+ processed = processed.replace(/<\/?([A-Za-z][A-Za-z0-9]*)>/g, (match, tag, offset) => {
116
130
  // If inside a code block, do not touch
117
131
  if (isInsideCodeBlock(processed, offset)) {
118
132
  return match;
@@ -0,0 +1,35 @@
1
+ import type { Plugin } from 'vite';
2
+ import { preprocessMdxContent } from '../mdx/processor';
3
+
4
+ /**
5
+ * Unified MDX preprocessing plugin for Vite.
6
+ * This plugin ensures that ALL MDX preprocessing goes through the same pipeline
7
+ * as the CLI verify:content command.
8
+ *
9
+ * This is the SINGLE SOURCE OF TRUTH for MDX preprocessing.
10
+ * Any changes to MDX processing should be made in src/mdx/processor.ts
11
+ */
12
+ export function unifiedMdxPreprocessor(): Plugin {
13
+ return {
14
+ name: 'unified-mdx-preprocessor',
15
+ enforce: 'pre', // Must run before the MDX plugin
16
+ async transform(code: string, id: string) {
17
+ if (!id.endsWith('.mdx')) return;
18
+
19
+ // Process through the unified preprocessing pipeline
20
+ const result = await preprocessMdxContent(code, id);
21
+
22
+ if (!result.success) {
23
+ // Throw the error to stop the build
24
+ throw result.error;
25
+ }
26
+
27
+ // Return the preprocessed content
28
+ // The actual MDX compilation will be handled by @mdx-js/rollup plugin
29
+ return {
30
+ code: result.processedContent || code,
31
+ map: null
32
+ };
33
+ }
34
+ };
35
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2023"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "node",
7
+ "allowImportingTsExtensions": true,
8
+ "skipLibCheck": true,
9
+ "strict": false,
10
+ "esModuleInterop": true,
11
+ "allowSyntheticDefaultImports": true,
12
+ "noEmit": true,
13
+ "noImplicitAny": false,
14
+ "noImplicitReturns": false,
15
+ "noImplicitThis": false
16
+ },
17
+ "include": [
18
+ "bin/dory.ts"
19
+ ]
20
+ }
package/vite.config.ts CHANGED
@@ -2,21 +2,19 @@ import { defineConfig } from 'vite';
2
2
  import preact from '@preact/preset-vite';
3
3
  import mdx from '@mdx-js/rollup';
4
4
  import tailwindcss from '@tailwindcss/vite'
5
- import remarkGfm from 'remark-gfm';
6
- import { preprocessMdxTags, remarkSafeVars } from './src/plugins/sanitize';
5
+ import { unifiedMdxPreprocessor } from './src/plugins/unified-mdx-plugin';
7
6
  import { llmTxtGenerator } from './src/plugins/llm-txt-generator';
8
7
  import { llmTxtDevServer } from './src/plugins/llm-txt-dev-server';
9
8
  import { frontmatterGenerator } from './src/plugins/frontmatter-generator';
10
9
  import { frontmatterDevServer } from './src/plugins/frontmatter-dev-server';
10
+ import { getMdxConfig } from './src/config/mdx';
11
11
 
12
- export default defineConfig({
12
+ export default defineConfig(({ command }) => ({
13
13
  plugins: [
14
- preprocessMdxTags(),
14
+ // SINGLE SOURCE OF TRUTH: All MDX preprocessing happens in src/mdx/processor.ts
15
+ unifiedMdxPreprocessor(),
15
16
  preact(),
16
- mdx({
17
- providerImportSource: '@mdx-js/preact',
18
- remarkPlugins: [remarkGfm, remarkSafeVars],
19
- }),
17
+ mdx(getMdxConfig(command === 'serve')),
20
18
  tailwindcss(),
21
19
  llmTxtGenerator(),
22
20
  llmTxtDevServer(),
@@ -33,4 +31,4 @@ export default defineConfig({
33
31
  server: {
34
32
  allowedHosts: true,
35
33
  },
36
- });
34
+ }));