@clidey/dory 0.23.0 โ 0.24.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/dist/dory.d.ts +3 -0
- package/bin/dist/dory.d.ts.map +1 -0
- package/bin/dist/dory.js +337 -0
- package/bin/dist/dory.js.map +1 -0
- package/bin/dory.ts +273 -121
- package/package.json +6 -4
- package/tsconfig.app.json +2 -1
- package/tsconfig.bin.json +11 -7
- package/tsconfig.node.json +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dory.d.ts","sourceRoot":"","sources":["../dory.ts"],"names":[],"mappings":""}
|
package/bin/dist/dory.js
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import { existsSync, rmSync, mkdirSync, cpSync, readFileSync, readdirSync } from 'fs';
|
|
4
|
+
import { resolve, dirname } from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { createServer } from 'http';
|
|
7
|
+
import sirv from 'sirv';
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
// Get the root directory of the Dory package
|
|
11
|
+
const getDoryRoot = () => {
|
|
12
|
+
// In development: bin/dory.ts -> root is parent
|
|
13
|
+
// In production: bin/dist/dory.js -> root is parent of parent
|
|
14
|
+
const isDevelopment = __dirname.endsWith('bin');
|
|
15
|
+
return isDevelopment ? resolve(__dirname, '..') : resolve(__dirname, '..', '..');
|
|
16
|
+
};
|
|
17
|
+
// Get the user's current working directory
|
|
18
|
+
const getUserRoot = () => process.cwd();
|
|
19
|
+
const validateDoryConfig = (config) => {
|
|
20
|
+
if (!config || typeof config !== 'object') {
|
|
21
|
+
throw new Error('Configuration must be a valid object');
|
|
22
|
+
}
|
|
23
|
+
// Add more validation as needed
|
|
24
|
+
};
|
|
25
|
+
const commands = {
|
|
26
|
+
build: () => {
|
|
27
|
+
console.log('๐ Dory is ready to build your docs!');
|
|
28
|
+
const userRoot = getUserRoot();
|
|
29
|
+
const doryRoot = getDoryRoot();
|
|
30
|
+
const doryConfigPath = resolve(userRoot, 'dory.json');
|
|
31
|
+
const tempDocsDir = resolve(doryRoot, 'docs');
|
|
32
|
+
const doryDistDir = resolve(doryRoot, 'dist');
|
|
33
|
+
const userDistDir = resolve(userRoot, 'dist');
|
|
34
|
+
// Step 1: Validate prerequisites before making any changes
|
|
35
|
+
console.log('๐ Validating project structure...');
|
|
36
|
+
if (!existsSync(doryConfigPath)) {
|
|
37
|
+
console.error('โ dory.json not found in current directory');
|
|
38
|
+
console.error(` Looking for: ${doryConfigPath}`);
|
|
39
|
+
console.error(' Create a dory.json file to configure your documentation site');
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
// Read and validate dory.json
|
|
43
|
+
let config;
|
|
44
|
+
try {
|
|
45
|
+
const configContent = readFileSync(doryConfigPath, 'utf8');
|
|
46
|
+
config = JSON.parse(configContent);
|
|
47
|
+
validateDoryConfig(config);
|
|
48
|
+
console.log(`๐ Building: ${config.name || 'Documentation'}`);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.error('โ Failed to parse dory.json:');
|
|
52
|
+
if (error instanceof Error) {
|
|
53
|
+
console.error(` ${error.message}`);
|
|
54
|
+
}
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
// Check if pnpm is available
|
|
58
|
+
try {
|
|
59
|
+
execSync('pnpm --version', { stdio: 'ignore' });
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
console.error('โ pnpm is not installed');
|
|
63
|
+
console.error(' Install it with: npm install -g pnpm');
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
// Step 2: Clean up temp directories
|
|
67
|
+
console.log('๐งน Preparing workspace...');
|
|
68
|
+
if (existsSync(tempDocsDir)) {
|
|
69
|
+
rmSync(tempDocsDir, { recursive: true, force: true });
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
// Step 3: Copy user files to temp docs directory
|
|
73
|
+
mkdirSync(tempDocsDir, { recursive: true });
|
|
74
|
+
console.log('๐ Gathering project files...');
|
|
75
|
+
// Define files/dirs to exclude
|
|
76
|
+
const excludeItems = new Set([
|
|
77
|
+
'node_modules',
|
|
78
|
+
'dist',
|
|
79
|
+
'.git',
|
|
80
|
+
'.github',
|
|
81
|
+
'docs',
|
|
82
|
+
'.DS_Store',
|
|
83
|
+
'.env',
|
|
84
|
+
'.env.local',
|
|
85
|
+
'pnpm-lock.yaml',
|
|
86
|
+
'package-lock.json',
|
|
87
|
+
'yarn.lock'
|
|
88
|
+
]);
|
|
89
|
+
const items = readdirSync(userRoot);
|
|
90
|
+
let copiedCount = 0;
|
|
91
|
+
for (const item of items) {
|
|
92
|
+
if (excludeItems.has(item)) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const srcPath = resolve(userRoot, item);
|
|
96
|
+
const destPath = resolve(tempDocsDir, item);
|
|
97
|
+
try {
|
|
98
|
+
cpSync(srcPath, destPath, { recursive: true, force: true });
|
|
99
|
+
copiedCount++;
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
console.warn(`โ ๏ธ Could not copy ${item}: ${error instanceof Error ? error.message : 'unknown error'}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
console.log(`โ
Copied ${copiedCount} items`);
|
|
106
|
+
// Step 4: Run the build
|
|
107
|
+
console.log('โก Building documentation...');
|
|
108
|
+
try {
|
|
109
|
+
execSync('pnpm run build', {
|
|
110
|
+
stdio: 'inherit',
|
|
111
|
+
cwd: doryRoot,
|
|
112
|
+
env: { ...process.env }
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
console.error('โ Build failed');
|
|
117
|
+
console.error(' Check the error messages above for details');
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
// Step 5: Verify build output
|
|
121
|
+
console.log('๐ Verifying build output...');
|
|
122
|
+
if (!existsSync(doryDistDir)) {
|
|
123
|
+
console.error('โ Build completed but dist folder was not created');
|
|
124
|
+
console.error(` Expected: ${doryDistDir}`);
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
const indexHtml = resolve(doryDistDir, 'index.html');
|
|
128
|
+
if (!existsSync(indexHtml)) {
|
|
129
|
+
console.error('โ Build incomplete: index.html not found');
|
|
130
|
+
console.error(' The build may have failed silently');
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
// Check if dist has content
|
|
134
|
+
const distFiles = readdirSync(doryDistDir);
|
|
135
|
+
if (distFiles.length === 0) {
|
|
136
|
+
console.error('โ Build completed but dist folder is empty');
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
console.log('๐ Build completed successfully!');
|
|
140
|
+
// Step 6: Copy dist to user's directory
|
|
141
|
+
console.log('๐ฆ Copying build output...');
|
|
142
|
+
// Only copy if they're different directories
|
|
143
|
+
if (doryDistDir !== userDistDir) {
|
|
144
|
+
if (existsSync(userDistDir)) {
|
|
145
|
+
rmSync(userDistDir, { recursive: true, force: true });
|
|
146
|
+
}
|
|
147
|
+
cpSync(doryDistDir, userDistDir, { recursive: true, force: true });
|
|
148
|
+
}
|
|
149
|
+
console.log('โจ Documentation ready in dist/');
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
// Step 7: Always clean up temp directories
|
|
153
|
+
console.log('๐งน Cleaning up...');
|
|
154
|
+
try {
|
|
155
|
+
if (existsSync(tempDocsDir)) {
|
|
156
|
+
rmSync(tempDocsDir, { recursive: true, force: true });
|
|
157
|
+
}
|
|
158
|
+
// Only clean up doryDistDir if it's different from userDistDir
|
|
159
|
+
// (in production they're different, in dev they might be the same)
|
|
160
|
+
if (doryDistDir !== userDistDir && existsSync(doryDistDir)) {
|
|
161
|
+
rmSync(doryDistDir, { recursive: true, force: true });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
console.warn('โ ๏ธ Could not clean up temp directories');
|
|
166
|
+
}
|
|
167
|
+
console.log('โ
Done!');
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
preview: () => {
|
|
171
|
+
console.log('๐ Starting docs preview...');
|
|
172
|
+
const userRoot = getUserRoot();
|
|
173
|
+
const distDir = resolve(userRoot, 'dist');
|
|
174
|
+
let port = parseInt(process.env.PORT || '3000', 10);
|
|
175
|
+
// Validate dist folder exists
|
|
176
|
+
if (!existsSync(distDir)) {
|
|
177
|
+
console.error('โ dist folder not found');
|
|
178
|
+
console.error(` Looking for: ${distDir}`);
|
|
179
|
+
console.error(' Run "dory build" first to generate the documentation');
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
// Check if dist has content
|
|
183
|
+
const distFiles = readdirSync(distDir);
|
|
184
|
+
if (distFiles.length === 0) {
|
|
185
|
+
console.error('โ dist folder is empty');
|
|
186
|
+
console.error(' Run "dory build" to generate documentation');
|
|
187
|
+
process.exit(1);
|
|
188
|
+
}
|
|
189
|
+
const serve = sirv(distDir, {
|
|
190
|
+
dev: false,
|
|
191
|
+
single: true,
|
|
192
|
+
etag: true,
|
|
193
|
+
gzip: true,
|
|
194
|
+
brotli: true,
|
|
195
|
+
});
|
|
196
|
+
const server = createServer((req, res) => {
|
|
197
|
+
serve(req, res);
|
|
198
|
+
});
|
|
199
|
+
const tryPort = (currentPort) => {
|
|
200
|
+
server.listen(currentPort)
|
|
201
|
+
.on('listening', () => {
|
|
202
|
+
console.log(`๐ Documentation live at http://localhost:${currentPort}`);
|
|
203
|
+
console.log(' Press Ctrl+C to stop the server');
|
|
204
|
+
})
|
|
205
|
+
.on('error', (err) => {
|
|
206
|
+
if (err.code === 'EADDRINUSE') {
|
|
207
|
+
console.log(`โ ๏ธ Port ${currentPort} in use, trying ${currentPort + 1}...`);
|
|
208
|
+
tryPort(currentPort + 1);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
console.error('โ Failed to start server:', err.message);
|
|
212
|
+
process.exit(1);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
};
|
|
216
|
+
tryPort(port);
|
|
217
|
+
},
|
|
218
|
+
'verify:content': async () => {
|
|
219
|
+
const args = process.argv.slice(3);
|
|
220
|
+
let content = '';
|
|
221
|
+
let fileName = '';
|
|
222
|
+
// Parse arguments
|
|
223
|
+
for (let i = 0; i < args.length; i++) {
|
|
224
|
+
if (args[i] === '--content' && i + 1 < args.length) {
|
|
225
|
+
content = args[i + 1];
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
else if (args[i] === '--file' && i + 1 < args.length) {
|
|
229
|
+
const filePath = resolve(getUserRoot(), args[i + 1]);
|
|
230
|
+
if (!existsSync(filePath)) {
|
|
231
|
+
console.error(`โ File not found: ${filePath}`);
|
|
232
|
+
process.exit(1);
|
|
233
|
+
}
|
|
234
|
+
content = readFileSync(filePath, 'utf8');
|
|
235
|
+
fileName = filePath;
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (!content) {
|
|
240
|
+
console.error('โ --content or --file argument is required');
|
|
241
|
+
console.log('Usage:');
|
|
242
|
+
console.log(' dory verify:content --content "<mdx-content>"');
|
|
243
|
+
console.log(' dory verify:content --file <path-to-mdx-file>');
|
|
244
|
+
process.exit(1);
|
|
245
|
+
}
|
|
246
|
+
try {
|
|
247
|
+
const doryRoot = getDoryRoot();
|
|
248
|
+
const processorPath = resolve(doryRoot, 'src', 'mdx', 'processor.ts');
|
|
249
|
+
if (!existsSync(processorPath)) {
|
|
250
|
+
console.error('โ MDX processor not found');
|
|
251
|
+
console.error(' This feature requires Dory source files');
|
|
252
|
+
process.exit(1);
|
|
253
|
+
}
|
|
254
|
+
// Use the shared MDX processor that matches the main build exactly
|
|
255
|
+
const { verifyMdxContent } = await import(processorPath);
|
|
256
|
+
const result = await verifyMdxContent(content, fileName);
|
|
257
|
+
if (!result.valid) {
|
|
258
|
+
throw result.error;
|
|
259
|
+
}
|
|
260
|
+
// Silent success - no output means no errors
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
console.error('โ MDX compilation failed:');
|
|
264
|
+
if (error instanceof Error) {
|
|
265
|
+
console.error(` ${error.message}`);
|
|
266
|
+
// Provide more detailed error information if available
|
|
267
|
+
const errorWithPosition = error;
|
|
268
|
+
if (errorWithPosition.line !== undefined && errorWithPosition.column !== undefined) {
|
|
269
|
+
console.error(` at line ${errorWithPosition.line}, column ${errorWithPosition.column}`);
|
|
270
|
+
}
|
|
271
|
+
if (errorWithPosition.source) {
|
|
272
|
+
console.error(' Source:', errorWithPosition.source);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
process.exit(1);
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
help: () => {
|
|
279
|
+
console.log(`
|
|
280
|
+
๐ Dory CLI - Documentation Builder
|
|
281
|
+
|
|
282
|
+
Usage:
|
|
283
|
+
dory <command> [options]
|
|
284
|
+
|
|
285
|
+
Commands:
|
|
286
|
+
build Build your documentation site
|
|
287
|
+
Requirements: dory.json in current directory
|
|
288
|
+
Output: dist/ folder with static site
|
|
289
|
+
|
|
290
|
+
preview Preview built documentation
|
|
291
|
+
Requirements: dist/ folder (run build first)
|
|
292
|
+
Starts local server on port 3000
|
|
293
|
+
|
|
294
|
+
verify:content Verify MDX content compilation
|
|
295
|
+
Options: --content "<mdx>" or --file <path>
|
|
296
|
+
Silent on success, shows errors on failure
|
|
297
|
+
|
|
298
|
+
help Show this help message
|
|
299
|
+
|
|
300
|
+
Examples:
|
|
301
|
+
dory build
|
|
302
|
+
dory preview
|
|
303
|
+
dory verify:content --content "# Hello World"
|
|
304
|
+
dory verify:content --file docs/intro.mdx
|
|
305
|
+
|
|
306
|
+
For more information, visit: https://github.com/clidey/dory
|
|
307
|
+
`);
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
// Parse command line arguments
|
|
311
|
+
const command = process.argv[2];
|
|
312
|
+
async function runCommand() {
|
|
313
|
+
if (!command || command === 'help' || command === '--help' || command === '-h') {
|
|
314
|
+
commands.help();
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
if (command in commands) {
|
|
318
|
+
await commands[command]();
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
console.error(`โ Unknown command: ${command}`);
|
|
322
|
+
console.log(' Run "dory help" for available commands');
|
|
323
|
+
process.exit(1);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
runCommand().catch((error) => {
|
|
327
|
+
console.error('โ Command failed');
|
|
328
|
+
if (error instanceof Error) {
|
|
329
|
+
console.error(` ${error.message}`);
|
|
330
|
+
if (error.stack && process.env.DEBUG) {
|
|
331
|
+
console.error('\nStack trace:');
|
|
332
|
+
console.error(error.stack);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
process.exit(1);
|
|
336
|
+
});
|
|
337
|
+
//# sourceMappingURL=dory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dory.js","sourceRoot":"","sources":["../dory.ts"],"names":[],"mappings":"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"}
|
package/bin/dory.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// @ts-nocheck - gang
|
|
4
3
|
import { execSync } from 'child_process';
|
|
5
4
|
import { existsSync, rmSync, mkdirSync, cpSync, readFileSync, readdirSync } from 'fs';
|
|
6
5
|
import { resolve, dirname } from 'path';
|
|
@@ -11,96 +10,221 @@ import sirv from 'sirv';
|
|
|
11
10
|
const __filename = fileURLToPath(import.meta.url);
|
|
12
11
|
const __dirname = dirname(__filename);
|
|
13
12
|
|
|
13
|
+
// Get the root directory of the Dory package
|
|
14
|
+
const getDoryRoot = (): string => {
|
|
15
|
+
// In development: bin/dory.ts -> root is parent
|
|
16
|
+
// In production: bin/dist/dory.js -> root is parent of parent
|
|
17
|
+
const isDevelopment = __dirname.endsWith('bin');
|
|
18
|
+
return isDevelopment ? resolve(__dirname, '..') : resolve(__dirname, '..', '..');
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// Get the user's current working directory
|
|
22
|
+
const getUserRoot = (): string => process.cwd();
|
|
23
|
+
|
|
24
|
+
interface DoryConfig {
|
|
25
|
+
name?: string;
|
|
26
|
+
description?: string;
|
|
27
|
+
navigation?: unknown;
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const validateDoryConfig = (config: DoryConfig): void => {
|
|
32
|
+
if (!config || typeof config !== 'object') {
|
|
33
|
+
throw new Error('Configuration must be a valid object');
|
|
34
|
+
}
|
|
35
|
+
// Add more validation as needed
|
|
36
|
+
};
|
|
37
|
+
|
|
14
38
|
const commands = {
|
|
15
39
|
build: () => {
|
|
16
40
|
console.log('๐ Dory is ready to build your docs!');
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
41
|
+
|
|
42
|
+
const userRoot = getUserRoot();
|
|
43
|
+
const doryRoot = getDoryRoot();
|
|
44
|
+
const doryConfigPath = resolve(userRoot, 'dory.json');
|
|
45
|
+
const tempDocsDir = resolve(doryRoot, 'docs');
|
|
46
|
+
const doryDistDir = resolve(doryRoot, 'dist');
|
|
47
|
+
const userDistDir = resolve(userRoot, 'dist');
|
|
48
|
+
|
|
49
|
+
// Step 1: Validate prerequisites before making any changes
|
|
50
|
+
console.log('๐ Validating project structure...');
|
|
51
|
+
|
|
29
52
|
if (!existsSync(doryConfigPath)) {
|
|
30
|
-
console.error('โ
|
|
53
|
+
console.error('โ dory.json not found in current directory');
|
|
54
|
+
console.error(` Looking for: ${doryConfigPath}`);
|
|
55
|
+
console.error(' Create a dory.json file to configure your documentation site');
|
|
31
56
|
process.exit(1);
|
|
32
57
|
}
|
|
33
|
-
|
|
58
|
+
|
|
34
59
|
// Read and validate dory.json
|
|
60
|
+
let config: DoryConfig;
|
|
35
61
|
try {
|
|
36
|
-
const
|
|
37
|
-
|
|
62
|
+
const configContent = readFileSync(doryConfigPath, 'utf8');
|
|
63
|
+
config = JSON.parse(configContent) as DoryConfig;
|
|
64
|
+
validateDoryConfig(config);
|
|
65
|
+
console.log(`๐ Building: ${config.name || 'Documentation'}`);
|
|
38
66
|
} catch (error) {
|
|
39
|
-
console.error('โ
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
mkdirSync(docsDir, { recursive: true });
|
|
44
|
-
|
|
45
|
-
console.log('๐ Gathering your project files...');
|
|
46
|
-
cpSync(doryConfigPath, resolve(docsDir, 'dory.json'));
|
|
47
|
-
|
|
48
|
-
const copyFiles = (src, dest) => {
|
|
49
|
-
if (existsSync(src)) {
|
|
50
|
-
if (existsSync(dest)) {
|
|
51
|
-
rmSync(dest, { recursive: true, force: true });
|
|
52
|
-
}
|
|
53
|
-
cpSync(src, dest, { recursive: true });
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
// Copy all files and directories except node_modules, dist, and .git
|
|
58
|
-
const excludeDirs = ['node_modules', 'dist', '.git', 'docs', 'pnpm-lock.yaml'];
|
|
59
|
-
|
|
60
|
-
const items = readdirSync(currentDir);
|
|
61
|
-
for (const item of items) {
|
|
62
|
-
if (!excludeDirs.includes(item)) {
|
|
63
|
-
const srcPath = resolve(currentDir, item);
|
|
64
|
-
const destPath = resolve(docsDir, item);
|
|
65
|
-
copyFiles(srcPath, destPath);
|
|
67
|
+
console.error('โ Failed to parse dory.json:');
|
|
68
|
+
if (error instanceof Error) {
|
|
69
|
+
console.error(` ${error.message}`);
|
|
66
70
|
}
|
|
71
|
+
process.exit(1);
|
|
67
72
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
// Run the build command
|
|
72
|
-
console.log('โก Magic is happening...');
|
|
73
|
+
|
|
74
|
+
// Check if pnpm is available
|
|
73
75
|
try {
|
|
74
|
-
execSync('
|
|
75
|
-
} catch
|
|
76
|
-
console.error('โ
|
|
76
|
+
execSync('pnpm --version', { stdio: 'ignore' });
|
|
77
|
+
} catch {
|
|
78
|
+
console.error('โ pnpm is not installed');
|
|
79
|
+
console.error(' Install it with: npm install -g pnpm');
|
|
77
80
|
process.exit(1);
|
|
78
81
|
}
|
|
79
|
-
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
if (existsSync(
|
|
82
|
+
|
|
83
|
+
// Step 2: Clean up temp directories
|
|
84
|
+
console.log('๐งน Preparing workspace...');
|
|
85
|
+
if (existsSync(tempDocsDir)) {
|
|
86
|
+
rmSync(tempDocsDir, { recursive: true, force: true });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
// Step 3: Copy user files to temp docs directory
|
|
91
|
+
mkdirSync(tempDocsDir, { recursive: true });
|
|
92
|
+
|
|
93
|
+
console.log('๐ Gathering project files...');
|
|
94
|
+
|
|
95
|
+
// Define files/dirs to exclude
|
|
96
|
+
const excludeItems = new Set([
|
|
97
|
+
'node_modules',
|
|
98
|
+
'dist',
|
|
99
|
+
'.git',
|
|
100
|
+
'.github',
|
|
101
|
+
'docs',
|
|
102
|
+
'.DS_Store',
|
|
103
|
+
'.env',
|
|
104
|
+
'.env.local',
|
|
105
|
+
'pnpm-lock.yaml',
|
|
106
|
+
'package-lock.json',
|
|
107
|
+
'yarn.lock'
|
|
108
|
+
]);
|
|
109
|
+
|
|
110
|
+
const items = readdirSync(userRoot);
|
|
111
|
+
let copiedCount = 0;
|
|
112
|
+
|
|
113
|
+
for (const item of items) {
|
|
114
|
+
if (excludeItems.has(item)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const srcPath = resolve(userRoot, item);
|
|
119
|
+
const destPath = resolve(tempDocsDir, item);
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
cpSync(srcPath, destPath, { recursive: true, force: true });
|
|
123
|
+
copiedCount++;
|
|
124
|
+
} catch (error) {
|
|
125
|
+
console.warn(`โ ๏ธ Could not copy ${item}: ${error instanceof Error ? error.message : 'unknown error'}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
console.log(`โ
Copied ${copiedCount} items`);
|
|
130
|
+
|
|
131
|
+
// Step 4: Run the build
|
|
132
|
+
console.log('โก Building documentation...');
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
execSync('pnpm run build', {
|
|
136
|
+
stdio: 'inherit',
|
|
137
|
+
cwd: doryRoot,
|
|
138
|
+
env: { ...process.env }
|
|
139
|
+
});
|
|
140
|
+
} catch (error) {
|
|
141
|
+
console.error('โ Build failed');
|
|
142
|
+
console.error(' Check the error messages above for details');
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Step 5: Verify build output
|
|
147
|
+
console.log('๐ Verifying build output...');
|
|
148
|
+
|
|
149
|
+
if (!existsSync(doryDistDir)) {
|
|
150
|
+
console.error('โ Build completed but dist folder was not created');
|
|
151
|
+
console.error(` Expected: ${doryDistDir}`);
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const indexHtml = resolve(doryDistDir, 'index.html');
|
|
156
|
+
if (!existsSync(indexHtml)) {
|
|
157
|
+
console.error('โ Build incomplete: index.html not found');
|
|
158
|
+
console.error(' The build may have failed silently');
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Check if dist has content
|
|
163
|
+
const distFiles = readdirSync(doryDistDir);
|
|
164
|
+
if (distFiles.length === 0) {
|
|
165
|
+
console.error('โ Build completed but dist folder is empty');
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
|
|
83
169
|
console.log('๐ Build completed successfully!');
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
console.log('
|
|
87
|
-
|
|
88
|
-
|
|
170
|
+
|
|
171
|
+
// Step 6: Copy dist to user's directory
|
|
172
|
+
console.log('๐ฆ Copying build output...');
|
|
173
|
+
|
|
174
|
+
// Only copy if they're different directories
|
|
175
|
+
if (doryDistDir !== userDistDir) {
|
|
176
|
+
if (existsSync(userDistDir)) {
|
|
177
|
+
rmSync(userDistDir, { recursive: true, force: true });
|
|
178
|
+
}
|
|
179
|
+
cpSync(doryDistDir, userDistDir, { recursive: true, force: true });
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
console.log('โจ Documentation ready in dist/');
|
|
183
|
+
|
|
184
|
+
} finally {
|
|
185
|
+
// Step 7: Always clean up temp directories
|
|
186
|
+
console.log('๐งน Cleaning up...');
|
|
187
|
+
|
|
188
|
+
try {
|
|
189
|
+
if (existsSync(tempDocsDir)) {
|
|
190
|
+
rmSync(tempDocsDir, { recursive: true, force: true });
|
|
191
|
+
}
|
|
192
|
+
// Only clean up doryDistDir if it's different from userDistDir
|
|
193
|
+
// (in production they're different, in dev they might be the same)
|
|
194
|
+
if (doryDistDir !== userDistDir && existsSync(doryDistDir)) {
|
|
195
|
+
rmSync(doryDistDir, { recursive: true, force: true });
|
|
196
|
+
}
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.warn('โ ๏ธ Could not clean up temp directories');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
console.log('โ
Done!');
|
|
89
202
|
}
|
|
90
|
-
rmSync(distDir, { recursive: true, force: true });
|
|
91
|
-
|
|
92
|
-
// Revert docs folder back to original state
|
|
93
|
-
console.log('๐งน Cleaning up...');
|
|
94
|
-
rmSync(docsDir, { recursive: true, force: true });
|
|
95
|
-
console.log('โ
All done!');
|
|
96
203
|
},
|
|
97
204
|
|
|
98
205
|
preview: () => {
|
|
99
|
-
console.log('๐ Starting
|
|
100
|
-
|
|
101
|
-
const
|
|
206
|
+
console.log('๐ Starting docs preview...');
|
|
207
|
+
|
|
208
|
+
const userRoot = getUserRoot();
|
|
209
|
+
const distDir = resolve(userRoot, 'dist');
|
|
102
210
|
let port = parseInt(process.env.PORT || '3000', 10);
|
|
103
211
|
|
|
212
|
+
// Validate dist folder exists
|
|
213
|
+
if (!existsSync(distDir)) {
|
|
214
|
+
console.error('โ dist folder not found');
|
|
215
|
+
console.error(` Looking for: ${distDir}`);
|
|
216
|
+
console.error(' Run "dory build" first to generate the documentation');
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Check if dist has content
|
|
221
|
+
const distFiles = readdirSync(distDir);
|
|
222
|
+
if (distFiles.length === 0) {
|
|
223
|
+
console.error('โ dist folder is empty');
|
|
224
|
+
console.error(' Run "dory build" to generate documentation');
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
227
|
+
|
|
104
228
|
const serve = sirv(distDir, {
|
|
105
229
|
dev: false,
|
|
106
230
|
single: true,
|
|
@@ -113,14 +237,15 @@ const commands = {
|
|
|
113
237
|
serve(req, res);
|
|
114
238
|
});
|
|
115
239
|
|
|
116
|
-
const tryPort = (currentPort: number) => {
|
|
240
|
+
const tryPort = (currentPort: number): void => {
|
|
117
241
|
server.listen(currentPort)
|
|
118
242
|
.on('listening', () => {
|
|
119
|
-
console.log(`๐
|
|
243
|
+
console.log(`๐ Documentation live at http://localhost:${currentPort}`);
|
|
244
|
+
console.log(' Press Ctrl+C to stop the server');
|
|
120
245
|
})
|
|
121
|
-
.on('error', (err:
|
|
246
|
+
.on('error', (err: NodeJS.ErrnoException) => {
|
|
122
247
|
if (err.code === 'EADDRINUSE') {
|
|
123
|
-
console.log(`โ ๏ธ Port ${currentPort}
|
|
248
|
+
console.log(`โ ๏ธ Port ${currentPort} in use, trying ${currentPort + 1}...`);
|
|
124
249
|
tryPort(currentPort + 1);
|
|
125
250
|
} else {
|
|
126
251
|
console.error('โ Failed to start server:', err.message);
|
|
@@ -136,16 +261,16 @@ const commands = {
|
|
|
136
261
|
const args = process.argv.slice(3);
|
|
137
262
|
let content = '';
|
|
138
263
|
let fileName = '';
|
|
139
|
-
|
|
264
|
+
|
|
140
265
|
// Parse arguments
|
|
141
266
|
for (let i = 0; i < args.length; i++) {
|
|
142
267
|
if (args[i] === '--content' && i + 1 < args.length) {
|
|
143
268
|
content = args[i + 1];
|
|
144
269
|
break;
|
|
145
270
|
} else if (args[i] === '--file' && i + 1 < args.length) {
|
|
146
|
-
const filePath = args[i + 1];
|
|
271
|
+
const filePath = resolve(getUserRoot(), args[i + 1]);
|
|
147
272
|
if (!existsSync(filePath)) {
|
|
148
|
-
console.error(`โ
|
|
273
|
+
console.error(`โ File not found: ${filePath}`);
|
|
149
274
|
process.exit(1);
|
|
150
275
|
}
|
|
151
276
|
content = readFileSync(filePath, 'utf8');
|
|
@@ -153,88 +278,115 @@ const commands = {
|
|
|
153
278
|
break;
|
|
154
279
|
}
|
|
155
280
|
}
|
|
156
|
-
|
|
281
|
+
|
|
157
282
|
if (!content) {
|
|
158
|
-
console.error('โ
|
|
159
|
-
console.log('Usage:
|
|
283
|
+
console.error('โ --content or --file argument is required');
|
|
284
|
+
console.log('Usage:');
|
|
285
|
+
console.log(' dory verify:content --content "<mdx-content>"');
|
|
286
|
+
console.log(' dory verify:content --file <path-to-mdx-file>');
|
|
160
287
|
process.exit(1);
|
|
161
288
|
}
|
|
162
|
-
|
|
289
|
+
|
|
163
290
|
try {
|
|
291
|
+
const doryRoot = getDoryRoot();
|
|
292
|
+
const processorPath = resolve(doryRoot, 'src', 'mdx', 'processor.ts');
|
|
293
|
+
|
|
294
|
+
if (!existsSync(processorPath)) {
|
|
295
|
+
console.error('โ MDX processor not found');
|
|
296
|
+
console.error(' This feature requires Dory source files');
|
|
297
|
+
process.exit(1);
|
|
298
|
+
}
|
|
299
|
+
|
|
164
300
|
// Use the shared MDX processor that matches the main build exactly
|
|
165
|
-
const { verifyMdxContent } = await import(
|
|
301
|
+
const { verifyMdxContent } = await import(processorPath);
|
|
166
302
|
const result = await verifyMdxContent(content, fileName);
|
|
167
|
-
|
|
303
|
+
|
|
168
304
|
if (!result.valid) {
|
|
169
305
|
throw result.error;
|
|
170
306
|
}
|
|
171
|
-
|
|
307
|
+
|
|
172
308
|
// Silent success - no output means no errors
|
|
173
|
-
|
|
309
|
+
|
|
174
310
|
} catch (error) {
|
|
175
311
|
console.error('โ MDX compilation failed:');
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
312
|
+
if (error instanceof Error) {
|
|
313
|
+
console.error(` ${error.message}`);
|
|
314
|
+
|
|
315
|
+
// Provide more detailed error information if available
|
|
316
|
+
const errorWithPosition = error as Error & { line?: number; column?: number; source?: string };
|
|
317
|
+
if (errorWithPosition.line !== undefined && errorWithPosition.column !== undefined) {
|
|
318
|
+
console.error(` at line ${errorWithPosition.line}, column ${errorWithPosition.column}`);
|
|
319
|
+
}
|
|
320
|
+
if (errorWithPosition.source) {
|
|
321
|
+
console.error(' Source:', errorWithPosition.source);
|
|
322
|
+
}
|
|
184
323
|
}
|
|
185
|
-
|
|
324
|
+
|
|
186
325
|
process.exit(1);
|
|
187
326
|
}
|
|
188
327
|
},
|
|
189
328
|
|
|
190
329
|
help: () => {
|
|
191
330
|
console.log(`
|
|
192
|
-
๐ Dory CLI -
|
|
331
|
+
๐ Dory CLI - Documentation Builder
|
|
193
332
|
|
|
194
333
|
Usage:
|
|
195
|
-
dory <command>
|
|
334
|
+
dory <command> [options]
|
|
196
335
|
|
|
197
336
|
Commands:
|
|
198
|
-
build
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
help Show this help message
|
|
337
|
+
build Build your documentation site
|
|
338
|
+
Requirements: dory.json in current directory
|
|
339
|
+
Output: dist/ folder with static site
|
|
340
|
+
|
|
341
|
+
preview Preview built documentation
|
|
342
|
+
Requirements: dist/ folder (run build first)
|
|
343
|
+
Starts local server on port 3000
|
|
344
|
+
|
|
345
|
+
verify:content Verify MDX content compilation
|
|
346
|
+
Options: --content "<mdx>" or --file <path>
|
|
347
|
+
Silent on success, shows errors on failure
|
|
348
|
+
|
|
349
|
+
help Show this help message
|
|
212
350
|
|
|
213
351
|
Examples:
|
|
214
|
-
dory build
|
|
215
|
-
dory
|
|
216
|
-
dory verify:content --
|
|
217
|
-
dory
|
|
352
|
+
dory build
|
|
353
|
+
dory preview
|
|
354
|
+
dory verify:content --content "# Hello World"
|
|
355
|
+
dory verify:content --file docs/intro.mdx
|
|
356
|
+
|
|
357
|
+
For more information, visit: https://github.com/clidey/dory
|
|
218
358
|
`);
|
|
219
359
|
}
|
|
220
360
|
};
|
|
221
361
|
|
|
362
|
+
type CommandName = keyof typeof commands;
|
|
363
|
+
|
|
222
364
|
// Parse command line arguments
|
|
223
365
|
const command = process.argv[2];
|
|
224
366
|
|
|
225
|
-
async function runCommand() {
|
|
367
|
+
async function runCommand(): Promise<void> {
|
|
226
368
|
if (!command || command === 'help' || command === '--help' || command === '-h') {
|
|
227
369
|
commands.help();
|
|
228
|
-
|
|
229
|
-
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (command in commands) {
|
|
374
|
+
await commands[command as CommandName]();
|
|
230
375
|
} else {
|
|
231
376
|
console.error(`โ Unknown command: ${command}`);
|
|
232
|
-
console.log('Run "dory help" for
|
|
377
|
+
console.log(' Run "dory help" for available commands');
|
|
233
378
|
process.exit(1);
|
|
234
379
|
}
|
|
235
380
|
}
|
|
236
381
|
|
|
237
|
-
runCommand().catch((error) => {
|
|
238
|
-
console.error('โ Command failed
|
|
382
|
+
runCommand().catch((error: unknown) => {
|
|
383
|
+
console.error('โ Command failed');
|
|
384
|
+
if (error instanceof Error) {
|
|
385
|
+
console.error(` ${error.message}`);
|
|
386
|
+
if (error.stack && process.env.DEBUG) {
|
|
387
|
+
console.error('\nStack trace:');
|
|
388
|
+
console.error(error.stack);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
239
391
|
process.exit(1);
|
|
240
392
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clidey/dory",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.24.0",
|
|
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.
|
|
15
|
+
"dory": "./bin/dist/dory.js"
|
|
16
16
|
},
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
@@ -26,9 +26,11 @@
|
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"dev": "vite",
|
|
29
|
-
"build": "tsc -b && vite build",
|
|
29
|
+
"build": "npm run build:cli && tsc -b && vite build",
|
|
30
|
+
"build:cli": "tsc -p tsconfig.bin.json",
|
|
30
31
|
"preview": "vite preview",
|
|
31
|
-
"publish": "npm publish --access public"
|
|
32
|
+
"publish": "npm run build && npm publish --access public",
|
|
33
|
+
"prepublishOnly": "npm run build"
|
|
32
34
|
},
|
|
33
35
|
"dependencies": {
|
|
34
36
|
"@algolia/autocomplete-core": "^1.19.2",
|
package/tsconfig.app.json
CHANGED
package/tsconfig.bin.json
CHANGED
|
@@ -4,17 +4,21 @@
|
|
|
4
4
|
"lib": ["ES2023"],
|
|
5
5
|
"module": "ESNext",
|
|
6
6
|
"moduleResolution": "node",
|
|
7
|
-
"allowImportingTsExtensions": true,
|
|
8
7
|
"skipLibCheck": true,
|
|
9
|
-
"strict":
|
|
8
|
+
"strict": true,
|
|
10
9
|
"esModuleInterop": true,
|
|
11
10
|
"allowSyntheticDefaultImports": true,
|
|
12
|
-
"noEmit":
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
11
|
+
"noEmit": false,
|
|
12
|
+
"outDir": "./bin/dist",
|
|
13
|
+
"rootDir": "./bin",
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"declarationMap": true,
|
|
16
|
+
"sourceMap": true
|
|
16
17
|
},
|
|
17
18
|
"include": [
|
|
18
|
-
"bin
|
|
19
|
+
"bin/**/*.ts"
|
|
20
|
+
],
|
|
21
|
+
"exclude": [
|
|
22
|
+
"bin/dist"
|
|
19
23
|
]
|
|
20
24
|
}
|
package/tsconfig.node.json
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
"lib": ["ES2023"],
|
|
6
6
|
"module": "ESNext",
|
|
7
7
|
"skipLibCheck": true,
|
|
8
|
+
"types": ["node"],
|
|
8
9
|
|
|
9
10
|
/* Bundler mode */
|
|
10
11
|
"moduleResolution": "bundler",
|
|
@@ -21,5 +22,5 @@
|
|
|
21
22
|
"noFallthroughCasesInSwitch": true,
|
|
22
23
|
"noUncheckedSideEffectImports": true
|
|
23
24
|
},
|
|
24
|
-
"include": ["vite.config.ts"]
|
|
25
|
+
"include": ["vite.config.ts", "src/plugins/**/*.ts", "bin/**/*.ts"]
|
|
25
26
|
}
|