mdts 0.4.5 → 0.5.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.
@@ -54,22 +54,71 @@
54
54
  }
55
55
 
56
56
  hr {
57
- color: rgba(0, 0, 0, .12);
57
+ margin: 48px 0;
58
+ border: 0;
59
+ border-bottom: 1px solid rgba(0, 0, 0, .12);
58
60
  }
59
61
 
60
62
  img {
61
63
  max-width: 100%;
62
64
  }
63
65
 
66
+ table {
67
+ display: block;
68
+ margin: 48px 0;
69
+ width: max-content;
70
+ overflow: auto;
71
+ border-spacing: 0;
72
+ border-collapse: collapse;
73
+
74
+ thead {
75
+ text-align: left;
76
+ }
77
+
78
+ tr {
79
+ border-top: 1px solid rgba(0, 0, 0, .12);
80
+ }
81
+
82
+ td, th {
83
+ padding: 6px 12px;
84
+ border: 1px solid rgba(0, 0, 0, .12);
85
+ }
86
+ }
87
+
64
88
  pre {
65
89
  padding: 16px;
66
90
  overflow: auto;
67
91
  background-color: #f4f5f7;
92
+
93
+ code {
94
+ padding: 0;
95
+ font-size: 100%;
96
+ word-break: normal;
97
+ white-space: pre;
98
+ background: transparent;
99
+ border: 0;
100
+ }
101
+ }
102
+
103
+ code {
104
+ display: inline-block;
105
+ padding: .1em .6em;
106
+ margin: 0;
107
+ font-size: 80%;
108
+ background-color: #f4f5f7;
109
+ border-radius: 2px;
68
110
  }
69
111
 
70
112
  blockquote {
113
+ margin: 24px 0;
71
114
  padding: 5px 16px;
72
115
  font-size: 14px;
116
+ color: rgba(0, 0, 0, .24);
117
+ border-left: 4px solid rgba(0, 0, 0, .12);
118
+
119
+ blockquote {
120
+ margin: 12px 0;
121
+ }
73
122
 
74
123
  p {
75
124
  margin: 0;
@@ -89,18 +138,37 @@
89
138
 
90
139
  .markdown-body.dark {
91
140
  h1 {
92
- border-bottom: 1px solid rgba(255, 255, 255, .12);
141
+ border-color: rgba(255, 255, 255, .12);
93
142
  }
94
143
 
95
144
  h2 {
96
- border-bottom: 1px solid rgba(255, 255, 255, .12);
145
+ border-color: rgba(255, 255, 255, .12);
146
+ }
147
+
148
+ table {
149
+ tr {
150
+ border-color: rgba(255, 255, 255, .12);
151
+ }
152
+
153
+ td, th {
154
+ border-color: rgba(255, 255, 255, .12);
155
+ }
97
156
  }
98
157
 
99
158
  pre {
100
159
  background-color: #20252c;
101
160
  }
102
161
 
162
+ code {
163
+ background-color: #20252c;
164
+ }
165
+
166
+ blockquote {
167
+ color: rgba(255, 255, 255, .24);
168
+ border-color: rgba(255, 255, 255, .12);
169
+ }
170
+
103
171
  hr {
104
- color: rgba(255, 255, 255, .12);
172
+ border-color: rgba(255, 255, 255, .12);
105
173
  }
106
174
  }
@@ -35,7 +35,7 @@ const getFileTree = (baseDirectory, currentRelativePath) => {
35
35
  const fileTreeRouter = (directory) => {
36
36
  const router = (0, express_1.Router)();
37
37
  router.get('/', (req, res) => {
38
- res.json(getFileTree(directory, ''));
38
+ res.json({ fileTree: getFileTree(directory, ''), mountedDirectoryPath: directory });
39
39
  });
40
40
  return router;
41
41
  };
@@ -1,11 +1,44 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
5
38
  Object.defineProperty(exports, "__esModule", { value: true });
6
39
  exports.outlineRouter = void 0;
7
40
  const express_1 = require("express");
8
- const fs_1 = __importDefault(require("fs"));
41
+ const fs = __importStar(require("fs"));
9
42
  const markdown_it_1 = __importDefault(require("markdown-it"));
10
43
  const path_1 = __importDefault(require("path"));
11
44
  const md = new markdown_it_1.default();
@@ -18,7 +51,10 @@ const slugify = (text) => {
18
51
  .replace(/^-+|-+$/g, ''); // Trim leading/trailing hyphens
19
52
  };
20
53
  const getMarkdownOutline = (filePath) => {
21
- const fileContent = fs_1.default.readFileSync(filePath, 'utf-8');
54
+ if (!fs.existsSync(filePath)) {
55
+ return [];
56
+ }
57
+ const fileContent = fs.readFileSync(filePath, 'utf-8');
22
58
  const tokens = md.parse(fileContent, {});
23
59
  const outline = [];
24
60
  for (const token of tokens) {
@@ -74,6 +74,25 @@ const createApp = (directory, currentLocation = __dirname) => {
74
74
  res.setHeader('Content-Type', 'text/plain');
75
75
  res.sendFile(path_1.default.join(currentLocation, './public/welcome.md'));
76
76
  });
77
+ app.use('/api/markdown', (req, res, next) => {
78
+ // Decode the URI component to handle encoded characters in the path
79
+ const decodedPath = decodeURIComponent(req.path);
80
+ // Normalize the path to resolve '..' and '.' segments
81
+ const normalizedPath = path_1.default.normalize(decodedPath);
82
+ // Construct the full file path
83
+ const filePath = path_1.default.join(directory, normalizedPath);
84
+ // Security check: Ensure the resolved path is within the designated directory
85
+ // This prevents path traversal attacks (e.g., accessing files outside 'directory')
86
+ if (!filePath.startsWith(directory)) {
87
+ console.error(`🚫 Attempted path traversal: ${filePath}`);
88
+ return res.status(403).send('Forbidden');
89
+ }
90
+ if (!fs.existsSync(filePath)) {
91
+ console.error(`🚫 File not found: ${filePath}`);
92
+ return res.status(404).send('File not found');
93
+ }
94
+ next();
95
+ });
77
96
  app.use('/api/markdown', express_1.default.static(directory));
78
97
  // Catch-all route to serve index.html for any other requests
79
98
  app.get('*', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
@@ -92,7 +111,18 @@ const createApp = (directory, currentLocation = __dirname) => {
92
111
  return res.sendFile(path_1.default.join(currentLocation, '../frontend/index.html'));
93
112
  }
94
113
  else {
95
- return res.sendFile(req.path, { root: directory });
114
+ return res.sendFile(req.path, { root: directory }, (err) => {
115
+ if (err) {
116
+ if ('code' in err && err.code === 'ENOENT') {
117
+ console.error(`🚫 File not found: ${path_1.default.join(directory, req.path)}`);
118
+ res.status(404).send('File not found');
119
+ }
120
+ else {
121
+ console.error(`🚫 Error serving file ${path_1.default.join(directory, req.path)}:`, err);
122
+ res.status(500).send('Internal Server Error');
123
+ }
124
+ }
125
+ });
96
126
  }
97
127
  }));
98
128
  return app;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdts",
3
- "version": "0.4.5",
3
+ "version": "0.5.1",
4
4
  "description": "A markdown preview server.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",