mikel-press 0.18.1 → 0.18.2

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.
Files changed (2) hide show
  1. package/index.js +68 -7
  2. package/package.json +3 -3
package/index.js CHANGED
@@ -1,7 +1,24 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
+ import * as http from "node:http";
3
4
  import mikel from "mikel";
4
5
 
6
+ // @description default mime types
7
+ const DEFAULT_MIME_TYPES = {
8
+ ".css": "text/css",
9
+ ".gif": "image/gif",
10
+ ".html": "text/html",
11
+ ".ico": "image/vnd.microsoft.icon",
12
+ ".jpg": "image/jpeg",
13
+ ".jpeg": "image/jpeg",
14
+ ".js": "text/javascript",
15
+ ".json": "application/json",
16
+ ".mjs": "text/javascript",
17
+ ".png": "image/png",
18
+ ".svg": "image/svg+xml",
19
+ ".txt": "text/plain",
20
+ };
21
+
5
22
  // @description general utilities
6
23
  const utils = {
7
24
  // @description read a file from disk
@@ -42,17 +59,19 @@ const utils = {
42
59
  walkdir: (folder, extensions = "*") => {
43
60
  const files = [];
44
61
  const walkSync = currentFolder => {
45
- fs.readdirSync(currentFolder).forEach(file => {
46
- const pathToFile = path.join(currentFolder, file);
47
- if (fs.statSync(pathToFile).isDirectory()) {
48
- return walkSync(pathToFile);
62
+ const fullFolderPath = path.join(folder, currentFolder);
63
+ fs.readdirSync(fullFolderPath).forEach(file => {
64
+ const filePath = path.join(currentFolder, file);
65
+ const fullFilePath = path.join(fullFolderPath, file);
66
+ if (fs.statSync(fullFilePath).isDirectory()) {
67
+ return walkSync(filePath);
49
68
  }
50
69
  if (extensions === "*" || extensions.includes(path.extname(file))) {
51
- files.push(pathToFile);
70
+ files.push(filePath);
52
71
  }
53
72
  });
54
73
  };
55
- walkSync(folder);
74
+ walkSync("./");
56
75
  return files;
57
76
  },
58
77
  // @description watch for file changes
@@ -75,6 +94,10 @@ const utils = {
75
94
  const basename = options.basename || path.basename(filePath, path.extname(filePath));
76
95
  return path.join(dirname, `${basename}${extname}`);
77
96
  },
97
+ // @description get the mime type from the given extension
98
+ getMimeType: (extname = ".txt") => {
99
+ return DEFAULT_MIME_TYPES[extname] || "text/plain";
100
+ },
78
101
  };
79
102
 
80
103
  // @description add a new node item
@@ -197,6 +220,42 @@ const watchContext = context => {
197
220
  });
198
221
  };
199
222
 
223
+ // @description start a server on the current context
224
+ // @param {Object} context current site context
225
+ // @param {Object} options server options
226
+ // @param {String} options.port port that the server will listen. Default: "3000"
227
+ // @param {Function} options.getMimeType function to obtain the associated mime type from the given extension
228
+ const serveContext = (context, options = {}) => {
229
+ const port = parseInt(options?.port || "3000");
230
+ const getMimeType = options?.getMimeType || utils.getMimeType;
231
+ const server = http.createServer((request, response) => {
232
+ let responseCode = 200;
233
+ let url = path.join(context.destination, path.normalize(request.url));
234
+ // check for directory
235
+ if (url.endsWith("/") || (fs.existsSync(url) && fs.statSync(url).isDirectory())) {
236
+ url = path.join(url, "index.html");
237
+ }
238
+ // check if we have to append the '.html' extension
239
+ if (!fs.existsSync(url) && fs.existsSync(url + ".html")) {
240
+ url = url + ".html";
241
+ }
242
+ // check if the file does not exist
243
+ if (!fs.existsSync(url)) {
244
+ url = path.join(context.destination, "404.html");
245
+ responseCode = 404;
246
+ }
247
+ // send the file
248
+ response.writeHead(responseCode, {
249
+ "Content-Type": getMimeType?.(path.extname(url)) || "text/plain",
250
+ });
251
+ fs.createReadStream(url).pipe(response);
252
+ console.log(`[${responseCode}] ${request.method} ${request.url}`);
253
+ });
254
+ // launch server
255
+ server.listen(port);
256
+ console.log(`Server running at http://127.0.0.1:${port}/`);
257
+ };
258
+
200
259
  // @description source plugin
201
260
  const SourcePlugin = (options = {}) => {
202
261
  const label = options.label || "pages";
@@ -303,7 +362,8 @@ const ContentPlugin = (options = {}) => {
303
362
  return {
304
363
  name: "ContentPlugin",
305
364
  load: context => {
306
- return createNode(context.source, context.config.layout || options.layout, label);
365
+ const layoutPath = path.resolve(context.source, context.config.layout || options.layout);
366
+ return createNode(path.dirname(layoutPath), path.basename(layoutPath), label);
307
367
  },
308
368
  transform: (_, node) => {
309
369
  if (node.label === label) {
@@ -390,6 +450,7 @@ export default {
390
450
  createContext: createContext,
391
451
  buildContext: buildContext,
392
452
  watchContext: watchContext,
453
+ serveContext: serveContext,
393
454
  // plugins
394
455
  SourcePlugin: SourcePlugin,
395
456
  DataPlugin: DataPlugin,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mikel-press",
3
3
  "description": "A tiny and fast static site generator based on mikel templating",
4
- "version": "0.18.1",
4
+ "version": "0.18.2",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": {
@@ -16,10 +16,10 @@
16
16
  "./package.json": "./package.json"
17
17
  },
18
18
  "engines": {
19
- "node": "20 || >=22"
19
+ "node": ">=20"
20
20
  },
21
21
  "dependencies": {
22
- "mikel": "^0.18.1"
22
+ "mikel": "^0.18.2"
23
23
  },
24
24
  "files": [
25
25
  "README.md",