host-mdx 2.1.0 → 2.2.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/README.md +40 -24
- package/index.js +142 -43
- package/mdx-to-html.js +10 -7
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# host-mdx
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/host-mdx
|
|
4
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/host-mdx)\
|
|
5
4
|
A cli tool to create and serve a static html website from a given mdx directory
|
|
6
5
|
|
|
7
6
|
## 🛠️ Usage
|
|
@@ -18,38 +17,45 @@ Options:
|
|
|
18
17
|
--track-changes, -t Tracks any changes made & auto reloads
|
|
19
18
|
--verobse, -v Shows additional log messages
|
|
20
19
|
```
|
|
21
|
-
|
|
22
|
-
> If `--input-path` is not provided it will default to `./` i.e. current working directory
|
|
23
|
-
> If `--output-path` is not provided a temp folder will be created automatically & deleted upon exit
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
> If `--input-path` is not provided it will default to `./` i.e. current working directory\
|
|
22
|
+
> If `--output-path` is not provided a temp folder will be created automatically & deleted upon exit
|
|
27
23
|
|
|
24
|
+
You can add a file by the name `.hostmdxignore` at the root of your project to filter out which files/folders to skip while generating html
|
|
25
|
+
(similar to [.gitignore](https://git-scm.com/docs/gitignore))
|
|
28
26
|
|
|
29
|
-
|
|
27
|
+
You can also add a file by the name `host-mdx.js` at the root of your input folder as a config file with access to the following:
|
|
30
28
|
|
|
31
29
|
```js
|
|
32
|
-
// Modify
|
|
33
|
-
modBundleMDXSettings(settings)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
// Hooks
|
|
37
30
|
onSiteCreateStart(inputPath, outputPath)
|
|
38
31
|
onSiteCreateEnd(inputPath, outputPath, wasInterrupted)
|
|
39
|
-
onFileCreateStart(
|
|
40
|
-
onFileCreateEnd(
|
|
32
|
+
onFileCreateStart(inputPath, outputPath, inFilePath, outFilePath)
|
|
33
|
+
onFileCreateEnd(inputPath, outputPath, inFilePath, outFilePath, result)
|
|
34
|
+
modBundleMDXSettings(inputPath, outputPath, settings)
|
|
35
|
+
modGlobalArgs(inputPath, outputPath, globalArgs)
|
|
36
|
+
toTriggerRecreate(event, path)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
> **Note:** Any changes made to `host-mdx.js` or any new package added requires complete restart otherwise changes will not reflect due to [this bug](https://github.com/nodejs/node/issues/49442)
|
|
40
|
+
|
|
41
|
+
Default global variables you can use inside any .mdx files:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
hostmdxCwd
|
|
45
|
+
hostmdxInputPath
|
|
46
|
+
hostmdxOutputPath
|
|
41
47
|
```
|
|
42
|
-
> Note: Any changes made to `host-mdx.js` require complete restart otherwise changes will not reflect
|
|
43
48
|
|
|
44
49
|
## 📖 Example
|
|
45
50
|
|
|
46
51
|
Command:
|
|
52
|
+
|
|
47
53
|
```bash
|
|
48
54
|
npx host-mdx --input-path="path/to/my-website-template" --output-path="path/to/my-website" --port=3113 -t
|
|
49
55
|
```
|
|
50
56
|
|
|
51
|
-
|
|
52
57
|
Input Directory:
|
|
58
|
+
|
|
53
59
|
```
|
|
54
60
|
my-website-template/
|
|
55
61
|
├─ index.mdx
|
|
@@ -73,6 +79,7 @@ my-website-template/
|
|
|
73
79
|
```
|
|
74
80
|
|
|
75
81
|
`.hostmdxignore` file content:
|
|
82
|
+
|
|
76
83
|
```sh
|
|
77
84
|
*.jsx
|
|
78
85
|
blog/page2/
|
|
@@ -81,32 +88,42 @@ static/temp.jpg
|
|
|
81
88
|
```
|
|
82
89
|
|
|
83
90
|
`host-mdx.js` file content:
|
|
91
|
+
|
|
84
92
|
```js
|
|
85
93
|
export function onSiteCreateStart(inputPath, outputPath) {
|
|
86
94
|
console.log("onSiteCreateStart", inputPath, outputPath)
|
|
87
95
|
}
|
|
88
|
-
export function onSiteCreateEnd(inputPath, outputPath, wasSuccessful){
|
|
96
|
+
export function onSiteCreateEnd(inputPath, outputPath, wasSuccessful) {
|
|
89
97
|
console.log("onSiteCreateEnd", inputPath, outputPath, wasSuccessful)
|
|
90
98
|
}
|
|
91
|
-
export function onFileCreateStart(inputFilePath, outputFilePath){
|
|
99
|
+
export function onFileCreateStart(inputFilePath, outputFilePath) {
|
|
92
100
|
console.log("onFileCreateStart", inputFilePath, outputFilePath)
|
|
93
101
|
}
|
|
94
|
-
export function onFileCreateEnd(inputFilePath, outputFilePath){
|
|
102
|
+
export function onFileCreateEnd(inputFilePath, outputFilePath) {
|
|
95
103
|
console.log("onFileCreateEnd", inputFilePath, outputFilePath)
|
|
96
104
|
}
|
|
97
|
-
export function onHostStart(port){
|
|
105
|
+
export function onHostStart(port) {
|
|
98
106
|
console.log("onHostStart", port)
|
|
99
107
|
}
|
|
100
|
-
export function onHostEnd(port){
|
|
108
|
+
export function onHostEnd(port) {
|
|
101
109
|
console.log("onHostEnd", port)
|
|
102
110
|
}
|
|
103
|
-
export function modBundleMDXSettings(settings){
|
|
111
|
+
export function modBundleMDXSettings(inputPath, outputPath, settings) {
|
|
104
112
|
// Modify settings ...
|
|
105
113
|
return settings
|
|
106
114
|
}
|
|
115
|
+
export function toTriggerRecreate(event, path) {
|
|
116
|
+
const isGOutputStream = /\.goutputstream-\w+$/.test(path);
|
|
117
|
+
if (isGOutputStream) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
107
123
|
```
|
|
108
124
|
|
|
109
125
|
Output Directory:
|
|
126
|
+
|
|
110
127
|
```
|
|
111
128
|
my-website/
|
|
112
129
|
├─ index.html
|
|
@@ -124,7 +141,6 @@ my-website/
|
|
|
124
141
|
|
|
125
142
|
The site will now be visible in the browser at `localhost:3113`
|
|
126
143
|
|
|
127
|
-
|
|
128
144
|
## 🔑 License
|
|
129
145
|
|
|
130
146
|
MIT © [Manas Ravindra Makde](https://manasmakde.github.io/)
|
package/index.js
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import fs from 'fs'
|
|
4
|
-
import os from 'os'
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import net from 'net';
|
|
5
6
|
import path from 'path'
|
|
6
|
-
import polka from 'polka';
|
|
7
7
|
import sirv from 'sirv';
|
|
8
|
-
import
|
|
8
|
+
import polka from 'polka';
|
|
9
|
+
import ignore from 'ignore';
|
|
9
10
|
import chokidar from 'chokidar';
|
|
10
11
|
import * as readline from 'readline';
|
|
11
12
|
import { pathToFileURL } from 'url';
|
|
12
|
-
import { mdxToHtml } from './mdx-to-html.js'
|
|
13
|
+
import { mdxToHtml } from './mdx-to-html.js';
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
// To-Set Properties
|
|
16
17
|
const APP_NAME = "host-mdx";
|
|
17
18
|
const DEFAULT_PORT = 3000;
|
|
19
|
+
const MAX_PORT = 3002;
|
|
18
20
|
const IGNORE_FILE_NAME = ".hostmdxignore";
|
|
19
21
|
const CONFIG_FILE_NAME = "host-mdx.js";
|
|
20
|
-
const
|
|
21
|
-
const NOT_FOUND_404_MESSAGE = "404"
|
|
22
|
+
const FILE_404 = "404.html";
|
|
23
|
+
const NOT_FOUND_404_MESSAGE = "404";
|
|
22
24
|
const DEFAULT_IGNORES = `
|
|
23
25
|
${IGNORE_FILE_NAME}
|
|
24
26
|
${CONFIG_FILE_NAME}
|
|
@@ -26,6 +28,8 @@ node_modules
|
|
|
26
28
|
package-lock.json
|
|
27
29
|
package.json
|
|
28
30
|
.git
|
|
31
|
+
.github
|
|
32
|
+
.gitignore
|
|
29
33
|
`;
|
|
30
34
|
|
|
31
35
|
|
|
@@ -135,17 +139,9 @@ async function createSite(inputPath, outputPath) {
|
|
|
135
139
|
isCreateSitePending = false
|
|
136
140
|
|
|
137
141
|
|
|
138
|
-
// Get config properties
|
|
139
|
-
let configFilePath = path.join(inputPath, `./${CONFIG_FILE_NAME}`)
|
|
140
|
-
if (fs.existsSync(configFilePath)) {
|
|
141
|
-
|
|
142
|
-
configs = await import(pathToFileURL(configFilePath).href);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
146
142
|
// Broadcast site creation started
|
|
147
143
|
log("Creating site...")
|
|
148
|
-
configs?.onSiteCreateStart?.(inputPath, outputPath)
|
|
144
|
+
await configs?.onSiteCreateStart?.(inputPath, outputPath)
|
|
149
145
|
|
|
150
146
|
|
|
151
147
|
// Remove html folder if it already exists
|
|
@@ -186,9 +182,9 @@ async function createSite(inputPath, outputPath) {
|
|
|
186
182
|
// Make dir
|
|
187
183
|
if (isDir) {
|
|
188
184
|
log(`${currentPath} ---> ${absToOutput}`, true)
|
|
189
|
-
configs?.onFileCreateStart?.(currentPath, absToOutput)
|
|
185
|
+
await configs?.onFileCreateStart?.(inputPath, outputPath, currentPath, absToOutput)
|
|
190
186
|
fs.mkdirSync(absToOutput, { recursive: true });
|
|
191
|
-
configs?.onFileCreateEnd?.(currentPath, absToOutput)
|
|
187
|
+
await configs?.onFileCreateEnd?.(inputPath, outputPath, currentPath, absToOutput, undefined)
|
|
192
188
|
}
|
|
193
189
|
// Make html file from mdx
|
|
194
190
|
else if (!isDir && isMdx) {
|
|
@@ -196,25 +192,32 @@ async function createSite(inputPath, outputPath) {
|
|
|
196
192
|
// Broadcast file creation started
|
|
197
193
|
let absHtmlPath = path.format({ ...path.parse(absToOutput), base: '', ext: '.html' })
|
|
198
194
|
log(`${currentPath} ---> ${absHtmlPath}`, true)
|
|
199
|
-
configs?.onFileCreateStart?.(currentPath, absHtmlPath)
|
|
195
|
+
await configs?.onFileCreateStart?.(inputPath, outputPath, currentPath, absHtmlPath, undefined)
|
|
200
196
|
|
|
201
197
|
|
|
202
198
|
// convert mdx code into html & paste into file
|
|
203
199
|
let mdxCode = fs.readFileSync(currentPath, 'utf8');
|
|
204
200
|
let parentDir = path.dirname(currentPath)
|
|
205
|
-
let
|
|
206
|
-
|
|
201
|
+
let globalArgs = {
|
|
202
|
+
hostmdxCwd: parentDir,
|
|
203
|
+
hostmdxInputPath: inputPath,
|
|
204
|
+
hostmdxOutputPath: outputPath
|
|
205
|
+
};
|
|
206
|
+
globalArgs = await configs?.modGlobalArgs?.(inputPath, outputPath, globalArgs) ?? globalArgs;
|
|
207
|
+
let result = await mdxToHtml(mdxCode, parentDir, globalArgs, async (settings) => { return await configs?.modBundleMDXSettings?.(inputPath, outputPath, settings) ?? settings });
|
|
208
|
+
let htmlCode = result.html;
|
|
209
|
+
createFile(absHtmlPath, `<!DOCTYPE html>${htmlCode}`);
|
|
207
210
|
|
|
208
211
|
|
|
209
212
|
// Broadcast file creation ended
|
|
210
|
-
configs?.onFileCreateEnd?.(currentPath, absHtmlPath)
|
|
213
|
+
await configs?.onFileCreateEnd?.(inputPath, outputPath, currentPath, absHtmlPath, result)
|
|
211
214
|
}
|
|
212
215
|
// Copy paste file
|
|
213
216
|
else if (!isDir) {
|
|
214
217
|
log(`${currentPath} ---> ${absToOutput}`, true)
|
|
215
|
-
configs?.onFileCreateStart?.(currentPath, absToOutput)
|
|
218
|
+
await configs?.onFileCreateStart?.(inputPath, outputPath, currentPath, absToOutput)
|
|
216
219
|
fs.copyFileSync(currentPath, absToOutput)
|
|
217
|
-
configs?.onFileCreateEnd?.(currentPath, absToOutput)
|
|
220
|
+
await configs?.onFileCreateEnd?.(inputPath, outputPath, currentPath, absToOutput, undefined)
|
|
218
221
|
}
|
|
219
222
|
|
|
220
223
|
|
|
@@ -237,16 +240,75 @@ async function createSite(inputPath, outputPath) {
|
|
|
237
240
|
|
|
238
241
|
|
|
239
242
|
// Broadcast site creation ended
|
|
240
|
-
|
|
241
|
-
|
|
243
|
+
if (isCreateSitePending) {
|
|
244
|
+
log(`Restarting site creation...`)
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
log(`Created site at ${outputPath}`)
|
|
248
|
+
}
|
|
249
|
+
await configs?.onSiteCreateEnd?.(inputPath, outputPath, isCreateSitePending)
|
|
242
250
|
|
|
243
251
|
|
|
244
252
|
// Reinvoke creation
|
|
245
|
-
if(isCreateSitePending){
|
|
253
|
+
if (isCreateSitePending) {
|
|
246
254
|
await createSite(inputPath, outputPath);
|
|
247
255
|
}
|
|
248
256
|
}
|
|
249
|
-
function
|
|
257
|
+
async function isPortAvailable(port) {
|
|
258
|
+
const server = net.createServer();
|
|
259
|
+
server.unref();
|
|
260
|
+
|
|
261
|
+
return new Promise((resolve) => {
|
|
262
|
+
server.once('error', () => {
|
|
263
|
+
server.close();
|
|
264
|
+
resolve(false);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
server.once('listening', () => {
|
|
268
|
+
server.close(() => resolve(true));
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
server.listen(port);
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
async function getAvailablePort(startPort, maxPort) {
|
|
275
|
+
let currentPort = startPort;
|
|
276
|
+
while (currentPort <= maxPort) {
|
|
277
|
+
if (await isPortAvailable(currentPort)) {
|
|
278
|
+
return currentPort;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
currentPort++;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
return -1;
|
|
285
|
+
}
|
|
286
|
+
function stripTrailingSep(thePath) {
|
|
287
|
+
if (thePath[thePath.length - 1] === path.sep) {
|
|
288
|
+
return thePath.slice(0, -1);
|
|
289
|
+
}
|
|
290
|
+
return thePath;
|
|
291
|
+
}
|
|
292
|
+
function isSubPath(potentialParent, thePath) {
|
|
293
|
+
// For inside-directory checking, we want to allow trailing slashes, so normalize.
|
|
294
|
+
thePath = stripTrailingSep(thePath);
|
|
295
|
+
potentialParent = stripTrailingSep(potentialParent);
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
// Node treats only Windows as case-insensitive in its path module; we follow those conventions.
|
|
299
|
+
if (process.platform === "win32") {
|
|
300
|
+
thePath = thePath.toLowerCase();
|
|
301
|
+
potentialParent = potentialParent.toLowerCase();
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
return thePath.lastIndexOf(potentialParent, 0) === 0 &&
|
|
306
|
+
(
|
|
307
|
+
thePath[potentialParent.length] === path.sep ||
|
|
308
|
+
thePath[potentialParent.length] === undefined
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
async function filterArgs(rawArgs) {
|
|
250
312
|
// Assign to create
|
|
251
313
|
let toCreateOnly = rawArgs.includes(CREATE_FLAG) || rawArgs.includes(CREATE_SHORT_FLAG)
|
|
252
314
|
|
|
@@ -283,14 +345,25 @@ function filterArgs(rawArgs) {
|
|
|
283
345
|
}
|
|
284
346
|
|
|
285
347
|
|
|
348
|
+
// Check if output path is inside input path (causing infinite loop)
|
|
349
|
+
if (isSubPath(inputPath, outputPath)) {
|
|
350
|
+
log(`Output path "${outputPath}" cannot be inside or same as input path "${inputPath}"`);
|
|
351
|
+
return null;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
|
|
286
355
|
// Assign port
|
|
287
356
|
let port = rawArgs.find(val => val.startsWith(PORT_FLAG));
|
|
288
357
|
let portProvided = port !== undefined;
|
|
289
|
-
port = portProvided ? Number(port.split('=')[1]) : DEFAULT_PORT;
|
|
358
|
+
port = portProvided ? Number(port.split('=')[1]) : (await getAvailablePort(DEFAULT_PORT, MAX_PORT));
|
|
290
359
|
|
|
291
360
|
|
|
292
361
|
// Check port
|
|
293
|
-
if (
|
|
362
|
+
if (port === -1) {
|
|
363
|
+
log(`Could not find any available ports between ${DEFAULT_PORT} to ${MAX_PORT}, Try manually passing ${PORT_FLAG}=... flag`);
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
else if (!Number.isInteger(port)) {
|
|
294
367
|
log(`Invalid port`)
|
|
295
368
|
return null;
|
|
296
369
|
}
|
|
@@ -314,7 +387,7 @@ async function createSiteSafe(...args) {
|
|
|
314
387
|
catch (err) {
|
|
315
388
|
success = false;
|
|
316
389
|
isCreatingSite = false;
|
|
317
|
-
log(`Failed to create site!\n${err}`);
|
|
390
|
+
log(`Failed to create site!\n${err.stack}`);
|
|
318
391
|
}
|
|
319
392
|
|
|
320
393
|
return success;
|
|
@@ -332,27 +405,31 @@ async function listenForKey(createSiteCallback) {
|
|
|
332
405
|
createSiteCallback();
|
|
333
406
|
}
|
|
334
407
|
else if (key && key.sequence == '\x03') {
|
|
335
|
-
app
|
|
408
|
+
app?.server?.close((e) => { process.exit() })
|
|
336
409
|
}
|
|
337
410
|
});
|
|
338
411
|
}
|
|
339
|
-
function
|
|
412
|
+
async function watchForChanges(pathTowatch, callback) {
|
|
413
|
+
chokidar.watch(pathTowatch, {
|
|
414
|
+
ignoreInitial: true
|
|
415
|
+
}).on('all', callback);
|
|
416
|
+
}
|
|
417
|
+
async function startServer(htmlDir, port) { // Starts server at given port
|
|
340
418
|
|
|
341
419
|
// Broadcast server starting
|
|
342
|
-
configs?.onHostStart?.(port)
|
|
420
|
+
await configs?.onHostStart?.(port)
|
|
343
421
|
|
|
344
422
|
|
|
345
423
|
// Start Server
|
|
346
424
|
const assets = sirv(htmlDir, { dev: true });
|
|
347
425
|
const newApp = polka({
|
|
348
426
|
onNoMatch: (req, res) => {
|
|
349
|
-
|
|
350
427
|
// Set status code to 404
|
|
351
428
|
res.statusCode = 404;
|
|
352
429
|
|
|
353
430
|
|
|
354
|
-
// Send 404 file if found
|
|
355
|
-
const errorFile = path.join(htmlDir,
|
|
431
|
+
// Send 404 file if found else not found message
|
|
432
|
+
const errorFile = path.join(htmlDir, FILE_404);
|
|
356
433
|
if (fs.existsSync(errorFile)) {
|
|
357
434
|
res.setHeader('Content-Type', 'text/html');
|
|
358
435
|
res.end(fs.readFileSync(errorFile));
|
|
@@ -360,10 +437,18 @@ function startServer(htmlDir, port) { // Starts server at given port
|
|
|
360
437
|
res.end(NOT_FOUND_404_MESSAGE);
|
|
361
438
|
}
|
|
362
439
|
}
|
|
440
|
+
}).use((req, res, next) => { // Add trailing slash
|
|
441
|
+
if (1 < req.path.length && !req.path.endsWith('/') && !path.extname(req.path)) {
|
|
442
|
+
res.writeHead(301, { Location: req.path + '/' });
|
|
443
|
+
return res.end();
|
|
444
|
+
}
|
|
445
|
+
next();
|
|
363
446
|
}).use(assets)
|
|
364
447
|
|
|
448
|
+
|
|
449
|
+
// Start listening
|
|
365
450
|
newApp.listen(port)
|
|
366
|
-
newApp.server.on("close", () => { configs?.onHostEnd?.(port) });
|
|
451
|
+
newApp.server.on("close", async () => { await configs?.onHostEnd?.(port) });
|
|
367
452
|
newApp.server.on("error", (e) => { log(`Failed to start server: ${e.message}`); throw e; });
|
|
368
453
|
log(`Server listening at ${port} ... (Press 'r' to manually reload, Press 'Ctrl+c' to exit)`)
|
|
369
454
|
|
|
@@ -371,6 +456,7 @@ function startServer(htmlDir, port) { // Starts server at given port
|
|
|
371
456
|
return newApp
|
|
372
457
|
}
|
|
373
458
|
async function Main() {
|
|
459
|
+
|
|
374
460
|
// Get all arguments
|
|
375
461
|
const rawArgs = process.argv.slice(2);
|
|
376
462
|
|
|
@@ -387,12 +473,20 @@ async function Main() {
|
|
|
387
473
|
|
|
388
474
|
|
|
389
475
|
// Filter arguments
|
|
390
|
-
let args = filterArgs(rawArgs);
|
|
476
|
+
let args = await filterArgs(rawArgs);
|
|
391
477
|
if (args === null) {
|
|
392
478
|
return;
|
|
393
479
|
}
|
|
394
480
|
|
|
395
481
|
|
|
482
|
+
// Get config
|
|
483
|
+
let configFilePath = path.join(args.inputPath, `./${CONFIG_FILE_NAME}`)
|
|
484
|
+
if (fs.existsSync(configFilePath)) {
|
|
485
|
+
log(`Importing config file ${CONFIG_FILE_NAME}`);
|
|
486
|
+
configs = await import(pathToFileURL(configFilePath).href);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
|
|
396
490
|
// Create site from mdx & return if only needed to create site
|
|
397
491
|
let wasCreated = await createSiteSafe(args.inputPath, args.outputPath);
|
|
398
492
|
if (args.toCreateOnly) {
|
|
@@ -407,16 +501,19 @@ async function Main() {
|
|
|
407
501
|
|
|
408
502
|
// Watch for changes
|
|
409
503
|
if (args.toTrackChanges) {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
504
|
+
watchForChanges(args.inputPath, async (event, path) => {
|
|
505
|
+
if (typeof configs?.toTriggerRecreate === 'function' && !(await configs?.toTriggerRecreate(event, path))) {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
log(`Recreating site, Event: ${event}, Path: ${path}`, true)
|
|
413
510
|
createSiteSafe(args.inputPath, args.outputPath)
|
|
414
511
|
});
|
|
415
512
|
}
|
|
416
513
|
|
|
417
514
|
|
|
418
515
|
// Start server
|
|
419
|
-
app = startServer(args.outputPath, args.port);
|
|
516
|
+
app = await startServer(args.outputPath, args.port);
|
|
420
517
|
|
|
421
518
|
|
|
422
519
|
// Handle quit
|
|
@@ -425,6 +522,8 @@ async function Main() {
|
|
|
425
522
|
if (!args.outputPathProvided && fs.existsSync(args.outputPath)) {
|
|
426
523
|
fs.rmSync(args.outputPath, { recursive: true, force: true })
|
|
427
524
|
}
|
|
525
|
+
|
|
526
|
+
process.stdin.setRawMode(false);
|
|
428
527
|
}
|
|
429
528
|
process.on("exit", cleanup);
|
|
430
529
|
process.on("SIGINT", cleanup);
|
package/mdx-to-html.js
CHANGED
|
@@ -27,12 +27,11 @@ const jsxBundlerConfig = {
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
// Methods
|
|
30
|
-
function
|
|
30
|
+
function getMDXExport(code, globals) {
|
|
31
31
|
const fn = new Function(...Object.keys(globals), code);
|
|
32
|
-
|
|
33
|
-
return mdxExport.default;
|
|
32
|
+
return fn(...Object.values(globals));
|
|
34
33
|
}
|
|
35
|
-
export async function mdxToHtml(mdxCode, baseUrl, modSettingsCallback = undefined) {
|
|
34
|
+
export async function mdxToHtml(mdxCode, baseUrl, globalArgs = {}, modSettingsCallback = undefined) {
|
|
36
35
|
|
|
37
36
|
// Assign default settings
|
|
38
37
|
let settings = {
|
|
@@ -55,14 +54,18 @@ export async function mdxToHtml(mdxCode, baseUrl, modSettingsCallback = undefine
|
|
|
55
54
|
|
|
56
55
|
// Modify settings
|
|
57
56
|
if (modSettingsCallback !== undefined) {
|
|
58
|
-
settings = modSettingsCallback(settings)
|
|
57
|
+
settings = await modSettingsCallback(settings)
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
|
|
62
61
|
// Generate html
|
|
63
62
|
const { code } = await bundleMDX(settings);
|
|
64
|
-
const
|
|
63
|
+
const Exports = getMDXExport(code, { Preact, PreactDOM, _jsx_runtime, require: nativeRequire, ...globalArgs });
|
|
64
|
+
const Component = Exports.default;
|
|
65
65
|
|
|
66
66
|
|
|
67
|
-
return
|
|
67
|
+
return {
|
|
68
|
+
html: renderToString(Preact.h(Component, {})),
|
|
69
|
+
exports: Exports
|
|
70
|
+
}
|
|
68
71
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "host-mdx",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "A cli tool to create and serve a static html website from a given mdx directory",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -10,6 +10,13 @@
|
|
|
10
10
|
"bin": {
|
|
11
11
|
"host-mdx": "index.js"
|
|
12
12
|
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/ManasMakde/host-mdx/issues"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/ManasMakde/host-mdx.git"
|
|
19
|
+
},
|
|
13
20
|
"dependencies": {
|
|
14
21
|
"chokidar": "^5.0.0",
|
|
15
22
|
"ignore": "^7.0.5",
|
|
@@ -25,7 +32,7 @@
|
|
|
25
32
|
"mdx"
|
|
26
33
|
],
|
|
27
34
|
"author": "Manas Makde",
|
|
28
|
-
"license": "
|
|
35
|
+
"license": "MIT",
|
|
29
36
|
"devDependencies": {
|
|
30
37
|
"@babel/preset-react": "^7.28.5",
|
|
31
38
|
"@babel/register": "^7.28.3"
|