host-mdx 2.1.1 → 2.2.1

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 CHANGED
@@ -1,9 +1,10 @@
1
1
  # host-mdx
2
- [![Version](https://img.shields.io/npm/v/host-mdx.svg)](https://www.npmjs.com/package/host-mdx)
3
- A cli tool to create and serve a static html website from a given mdx directory
4
2
 
3
+ [![Version](https://img.shields.io/npm/v/host-mdx.svg)](https://www.npmjs.com/package/host-mdx)\
4
+ A cli tool to create and serve a static html website from a given mdx directory
5
5
 
6
6
  ## 🛠️ Usage
7
+
7
8
  ```
8
9
  host-mdx [options]
9
10
 
@@ -16,35 +17,48 @@ Options:
16
17
  --track-changes, -t Tracks any changes made & auto reloads
17
18
  --verobse, -v Shows additional log messages
18
19
  ```
19
-
20
- > If `--input-path` is not provided it will default to `./` i.e. current working directory
21
- > If `--output-path` is not provided a temp folder will be created automatically & deleted upon exit
22
20
 
23
- Add a file by the name `.hostmdxignore` at the root of your project to filter out which files/folders to skip while generating html
24
- (similar to [.gitignore](https://git-scm.com/docs/gitignore))
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
25
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))
26
26
 
27
- Add a file by the name `host-mdx.js` at the root of your input folder as a config file with the following:
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:
28
28
 
29
29
  ```js
30
+ onHostStart(port)
31
+ onHostEnd(port)
32
+ toTriggerRecreate(event, path)
30
33
  onSiteCreateStart(inputPath, outputPath)
31
34
  onSiteCreateEnd(inputPath, outputPath, wasInterrupted)
32
- onFileCreateStart(inputFilePath, outputFilePath)
33
- onFileCreateEnd(inputFilePath, outputFilePath)
35
+ onFileCreateStart(inputPath, outputPath, inFilePath, outFilePath)
36
+ onFileCreateEnd(inputPath, outputPath, inFilePath, outFilePath, result)
37
+ modMDXCode(inputPath, outputPath, inFilePath, outFilePath, code)
38
+ modGlobalArgs(inputPath, outputPath, globalArgs)
34
39
  modBundleMDXSettings(inputPath, outputPath, settings)
35
- toTriggerRecreate(event, path)
36
40
  ```
37
41
 
38
42
  > **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)
39
43
 
44
+ Default global variables you can use inside any .mdx files:
45
+
46
+ ```
47
+ hostmdxCwd
48
+ hostmdxInputPath
49
+ hostmdxOutputPath
50
+ ```
40
51
 
41
52
  ## 📖 Example
53
+
42
54
  Command:
55
+
43
56
  ```bash
44
57
  npx host-mdx --input-path="path/to/my-website-template" --output-path="path/to/my-website" --port=3113 -t
45
58
  ```
46
59
 
47
60
  Input Directory:
61
+
48
62
  ```
49
63
  my-website-template/
50
64
  ├─ index.mdx
@@ -68,6 +82,7 @@ my-website-template/
68
82
  ```
69
83
 
70
84
  `.hostmdxignore` file content:
85
+
71
86
  ```sh
72
87
  *.jsx
73
88
  blog/page2/
@@ -76,40 +91,50 @@ static/temp.jpg
76
91
  ```
77
92
 
78
93
  `host-mdx.js` file content:
94
+
79
95
  ```js
80
- export function onSiteCreateStart(inputPath, outputPath) {
96
+ export async function onHostStart(port) {
97
+ console.log("onHostStart", port)
98
+ }
99
+ export async function onHostEnd(port) {
100
+ console.log("onHostEnd", port)
101
+ }
102
+ export async function toTriggerRecreate(event, path) {
103
+ const isGOutputStream = /\.goutputstream-\w+$/.test(path);
104
+ if (isGOutputStream) {
105
+ return false;
106
+ }
107
+
108
+ return true;
109
+ }
110
+ export async function onSiteCreateStart(inputPath, outputPath) {
81
111
  console.log("onSiteCreateStart", inputPath, outputPath)
82
112
  }
83
- export function onSiteCreateEnd(inputPath, outputPath, wasSuccessful) {
113
+ export async function onSiteCreateEnd(inputPath, outputPath, wasSuccessful) {
84
114
  console.log("onSiteCreateEnd", inputPath, outputPath, wasSuccessful)
85
115
  }
86
- export function onFileCreateStart(inputFilePath, outputFilePath) {
116
+ export async function onFileCreateStart(inputFilePath, outputFilePath) {
87
117
  console.log("onFileCreateStart", inputFilePath, outputFilePath)
88
118
  }
89
- export function onFileCreateEnd(inputFilePath, outputFilePath) {
119
+ export async function onFileCreateEnd(inputFilePath, outputFilePath) {
90
120
  console.log("onFileCreateEnd", inputFilePath, outputFilePath)
91
121
  }
92
- export function onHostStart(port) {
93
- console.log("onHostStart", port)
122
+ export async function modMDXCode(inputPath, outputPath, inFilePath, outFilePath, code){
123
+ // Modify code ...
124
+ return code;
94
125
  }
95
- export function onHostEnd(port) {
96
- console.log("onHostEnd", port)
126
+ export async function modGlobalArgs(inputPath, outputPath, globalArgs){
127
+ // Modify globalArgs ...
128
+ return globalArgs;
97
129
  }
98
- export function modBundleMDXSettings(inputPath, outputPath, settings) {
130
+ export async function modBundleMDXSettings(inputPath, outputPath, settings) {
99
131
  // Modify settings ...
100
132
  return settings
101
133
  }
102
- export function toTriggerRecreate(event, path) {
103
- const isGOutputStream = /\.goutputstream-\w+$/.test(path);
104
- if (isGOutputStream) {
105
- return false;
106
- }
107
-
108
- return true;
109
- }
110
134
  ```
111
135
 
112
136
  Output Directory:
137
+
113
138
  ```
114
139
  my-website/
115
140
  ├─ index.html
@@ -127,6 +152,6 @@ my-website/
127
152
 
128
153
  The site will now be visible in the browser at `localhost:3113`
129
154
 
130
-
131
155
  ## 🔑 License
156
+
132
157
  MIT © [Manas Ravindra Makde](https://manasmakde.github.io/)
package/index.js CHANGED
@@ -141,7 +141,7 @@ async function createSite(inputPath, outputPath) {
141
141
 
142
142
  // Broadcast site creation started
143
143
  log("Creating site...")
144
- configs?.onSiteCreateStart?.(inputPath, outputPath)
144
+ await configs?.onSiteCreateStart?.(inputPath, outputPath)
145
145
 
146
146
 
147
147
  // Remove html folder if it already exists
@@ -182,9 +182,9 @@ async function createSite(inputPath, outputPath) {
182
182
  // Make dir
183
183
  if (isDir) {
184
184
  log(`${currentPath} ---> ${absToOutput}`, true)
185
- configs?.onFileCreateStart?.(currentPath, absToOutput)
185
+ await configs?.onFileCreateStart?.(inputPath, outputPath, currentPath, absToOutput)
186
186
  fs.mkdirSync(absToOutput, { recursive: true });
187
- configs?.onFileCreateEnd?.(currentPath, absToOutput)
187
+ await configs?.onFileCreateEnd?.(inputPath, outputPath, currentPath, absToOutput, undefined)
188
188
  }
189
189
  // Make html file from mdx
190
190
  else if (!isDir && isMdx) {
@@ -192,30 +192,39 @@ async function createSite(inputPath, outputPath) {
192
192
  // Broadcast file creation started
193
193
  let absHtmlPath = path.format({ ...path.parse(absToOutput), base: '', ext: '.html' })
194
194
  log(`${currentPath} ---> ${absHtmlPath}`, true)
195
- configs?.onFileCreateStart?.(currentPath, absHtmlPath)
195
+ await configs?.onFileCreateStart?.(inputPath, outputPath, currentPath, absHtmlPath)
196
196
 
197
197
 
198
- // convert mdx code into html & paste into file
198
+ // Intercept mdx code
199
199
  let mdxCode = fs.readFileSync(currentPath, 'utf8');
200
- let parentDir = path.dirname(currentPath)
200
+ if (typeof configs?.modMDXCode === 'function') {
201
+ log(`Modifying mdx code of ${currentPath}`, true);
202
+ mdxCode = await configs?.modMDXCode(inputPath, outputPath, currentPath, absHtmlPath, mdxCode);
203
+ }
204
+
205
+
206
+ // convert mdx code into html & paste into file
207
+ let parentDir = path.dirname(currentPath);
201
208
  let globalArgs = {
202
209
  hostmdxCwd: parentDir,
203
210
  hostmdxInputPath: inputPath,
204
211
  hostmdxOutputPath: outputPath
205
212
  };
206
- let htmlCode = await mdxToHtml(mdxCode, parentDir, globalArgs, (settings) => { return configs?.modBundleMDXSettings?.(inputPath, outputPath, settings) ?? settings });
207
- createFile(absHtmlPath, `<!DOCTYPE html>\n${htmlCode}`);
213
+ globalArgs = await configs?.modGlobalArgs?.(inputPath, outputPath, globalArgs) ?? globalArgs;
214
+ let result = await mdxToHtml(mdxCode, parentDir, globalArgs, async (settings) => { return await configs?.modBundleMDXSettings?.(inputPath, outputPath, settings) ?? settings });
215
+ let htmlCode = result.html;
216
+ createFile(absHtmlPath, `<!DOCTYPE html>${htmlCode}`);
208
217
 
209
218
 
210
219
  // Broadcast file creation ended
211
- configs?.onFileCreateEnd?.(currentPath, absHtmlPath)
220
+ await configs?.onFileCreateEnd?.(inputPath, outputPath, currentPath, absHtmlPath, result)
212
221
  }
213
222
  // Copy paste file
214
223
  else if (!isDir) {
215
224
  log(`${currentPath} ---> ${absToOutput}`, true)
216
- configs?.onFileCreateStart?.(currentPath, absToOutput)
225
+ await configs?.onFileCreateStart?.(inputPath, outputPath, currentPath, absToOutput)
217
226
  fs.copyFileSync(currentPath, absToOutput)
218
- configs?.onFileCreateEnd?.(currentPath, absToOutput)
227
+ await configs?.onFileCreateEnd?.(inputPath, outputPath, currentPath, absToOutput, undefined)
219
228
  }
220
229
 
221
230
 
@@ -244,7 +253,7 @@ async function createSite(inputPath, outputPath) {
244
253
  else {
245
254
  log(`Created site at ${outputPath}`)
246
255
  }
247
- configs?.onSiteCreateEnd?.(inputPath, outputPath, isCreateSitePending)
256
+ await configs?.onSiteCreateEnd?.(inputPath, outputPath, isCreateSitePending)
248
257
 
249
258
 
250
259
  // Reinvoke creation
@@ -305,7 +314,7 @@ function isSubPath(potentialParent, thePath) {
305
314
  thePath[potentialParent.length] === path.sep ||
306
315
  thePath[potentialParent.length] === undefined
307
316
  );
308
- };
317
+ }
309
318
  async function filterArgs(rawArgs) {
310
319
  // Assign to create
311
320
  let toCreateOnly = rawArgs.includes(CREATE_FLAG) || rawArgs.includes(CREATE_SHORT_FLAG)
@@ -412,10 +421,10 @@ async function watchForChanges(pathTowatch, callback) {
412
421
  ignoreInitial: true
413
422
  }).on('all', callback);
414
423
  }
415
- function startServer(htmlDir, port) { // Starts server at given port
424
+ async function startServer(htmlDir, port) { // Starts server at given port
416
425
 
417
426
  // Broadcast server starting
418
- configs?.onHostStart?.(port)
427
+ await configs?.onHostStart?.(port)
419
428
 
420
429
 
421
430
  // Start Server
@@ -446,7 +455,7 @@ function startServer(htmlDir, port) { // Starts server at given port
446
455
 
447
456
  // Start listening
448
457
  newApp.listen(port)
449
- newApp.server.on("close", () => { configs?.onHostEnd?.(port) });
458
+ newApp.server.on("close", async () => { await configs?.onHostEnd?.(port) });
450
459
  newApp.server.on("error", (e) => { log(`Failed to start server: ${e.message}`); throw e; });
451
460
  log(`Server listening at ${port} ... (Press 'r' to manually reload, Press 'Ctrl+c' to exit)`)
452
461
 
@@ -480,6 +489,7 @@ async function Main() {
480
489
  // Get config
481
490
  let configFilePath = path.join(args.inputPath, `./${CONFIG_FILE_NAME}`)
482
491
  if (fs.existsSync(configFilePath)) {
492
+ log(`Importing config file ${CONFIG_FILE_NAME}`);
483
493
  configs = await import(pathToFileURL(configFilePath).href);
484
494
  }
485
495
 
@@ -498,8 +508,8 @@ async function Main() {
498
508
 
499
509
  // Watch for changes
500
510
  if (args.toTrackChanges) {
501
- watchForChanges(args.inputPath, (event, path) => {
502
- if (typeof configs.toTriggerRecreate === 'function' && !configs?.toTriggerRecreate(event, path)) {
511
+ watchForChanges(args.inputPath, async (event, path) => {
512
+ if (typeof configs?.toTriggerRecreate === 'function' && !(await configs?.toTriggerRecreate(event, path))) {
503
513
  return;
504
514
  }
505
515
 
@@ -510,7 +520,7 @@ async function Main() {
510
520
 
511
521
 
512
522
  // Start server
513
- app = startServer(args.outputPath, args.port);
523
+ app = await startServer(args.outputPath, args.port);
514
524
 
515
525
 
516
526
  // Handle quit
package/mdx-to-html.js CHANGED
@@ -27,10 +27,9 @@ const jsxBundlerConfig = {
27
27
 
28
28
 
29
29
  // Methods
30
- function getMDXComponent(code, globals) {
30
+ function getMDXExport(code, globals) {
31
31
  const fn = new Function(...Object.keys(globals), code);
32
- const mdxExport = fn(...Object.values(globals));
33
- return mdxExport.default;
32
+ return fn(...Object.values(globals));
34
33
  }
35
34
  export async function mdxToHtml(mdxCode, baseUrl, globalArgs = {}, modSettingsCallback = undefined) {
36
35
 
@@ -55,14 +54,18 @@ export async function mdxToHtml(mdxCode, baseUrl, globalArgs = {}, modSettingsCa
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 Component = getMDXComponent(code, { Preact, PreactDOM, _jsx_runtime, require: nativeRequire, ...globalArgs })
63
+ const Exports = getMDXExport(code, { Preact, PreactDOM, _jsx_runtime, require: nativeRequire, ...globalArgs });
64
+ const Component = Exports.default;
65
65
 
66
66
 
67
- return renderToString(Preact.h(Component, {}));
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.1.1",
3
+ "version": "2.2.1",
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",