@mryhryki/markdown-preview 0.6.1 → 0.7.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 CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  Markdown realtime preview on browser with your favorite editor.
4
4
 
5
+ ## Concept
6
+
7
+ - Execute immediately with [npx](#npx).
8
+ - Offline support if [installed](#npm--yarn-install).
9
+ - [You can create your own template easily.](#2-how-to-create-a-template-file)
10
+
5
11
  ## Demo
6
12
 
7
13
  <video
@@ -14,7 +20,7 @@ Markdown realtime preview on browser with your favorite editor.
14
20
  ### npx
15
21
 
16
22
  ```shell
17
- $ npx @mryhryki/markdown-preview --file README.md --template default --port 34567 --log-level info --no-opener
23
+ $ npx @mryhryki/markdown-preview
18
24
  Version : v0.6.0
19
25
  Root Directory : /current/dir
20
26
  Default File : README.md
@@ -23,14 +29,14 @@ Template File : /path/to/template/default.html
23
29
  Preview URL : http://localhost:34567
24
30
  ```
25
31
 
26
- ### npm / yarn
32
+ ### npm / yarn (install)
27
33
 
28
34
  ```shell
29
35
  $ npm install -g @mryhryki/markdown-preview
30
36
  # or
31
37
  $ yarn install -g @mryhryki/markdown-preview
32
38
 
33
- $ markdown-preview --file README.md --template default-dark --port 34567 --log-level info --no-opener
39
+ $ markdown-preview
34
40
  Version : v0.6.0
35
41
  Root Directory : /current/dir
36
42
  Default File : README.md
@@ -41,15 +47,16 @@ Preview URL : http://localhost:34567
41
47
 
42
48
  ## Parameter
43
49
 
44
- | short | long | environment variable | parameter | required | default |
45
- |-------|-------------|----------------------------|-------------------------------------------------------|----------|-----------|
46
- | -f | --file | MARKDOWN_PREVIEW_FILE | ***relative*** file path | no | README.md |
47
- | -t | --template | MARKDOWN_PREVIEW_TEMPLATE | defined template name (*1) or template file path (*2) | no | default |
48
- | -p | --port | MARKDOWN_PREVIEW_PORT | port number | no | 34567 |
49
- | | --log-level | MARKDOWN_PREVIEW_LOG_LEVEL | trace, debug, info<br>warn, error, fatal | no | info |
50
- | | --no-opener | MARKDOWN_PREVIEW_NO_OPENER | true (only env var) | no | |
51
- | -v | --version | | | no | |
52
- | -h | --help | | | no | |
50
+ | short | long | environment variable | parameter | required | default |
51
+ |-------|--------------|-----------------------------|-------------------------------------------------------|----------|-------------|
52
+ | -f | --file | MARKDOWN_PREVIEW_FILE | ***relative*** file path | no | README.md |
53
+ | -e | --extensions | MARKDOWN_PREVIEW_EXTENSIONS | comma separated extensions | no | md,markdown |
54
+ | -t | --template | MARKDOWN_PREVIEW_TEMPLATE | defined template name (*1) or template file path (*2) | no | default |
55
+ | -p | --port | MARKDOWN_PREVIEW_PORT | port number | no | 34567 |
56
+ | | --log-level | MARKDOWN_PREVIEW_LOG_LEVEL | trace, debug, info<br>warn, error, fatal | no | info |
57
+ | | --no-opener | MARKDOWN_PREVIEW_NO_OPENER | true (only env var) | no | |
58
+ | -v | --version | | | no | |
59
+ | -h | --help | | | no | |
53
60
 
54
61
  ### *1: Defined Template Names
55
62
 
@@ -57,10 +64,9 @@ Preview URL : http://localhost:34567
57
64
 
58
65
  ### *2: How to create a template file
59
66
 
60
- Creating a template file is easy.
61
- At a minimum, all you need to do is load `/markdown-preview-websocket.js` and pass a callback function with the necessary processing to `connectMarkdownPreview`.
67
+ You just need to load `/markdown-preview-websocket.js` and register a callback to `connectMarkdownPreview`.
62
68
 
63
- Sample code is presented below.
69
+ A simple example code is below:
64
70
 
65
71
  ```html
66
72
  <!doctype html>
@@ -106,3 +112,7 @@ $ npm run lint
106
112
  # Formatter
107
113
  $ npm run fmt
108
114
  ```
115
+
116
+ ## Release
117
+
118
+ Run [release](https://github.com/mryhryki/markdown-preview/actions/workflows/release.yaml) workflow.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mryhryki/markdown-preview",
3
3
  "description": "Markdown realtime preview on browser with your favorite editor",
4
- "version": "0.6.1",
4
+ "version": "0.7.0",
5
5
  "author": "mryhryki",
6
6
  "license": "MIT",
7
7
  "publishConfig": {
@@ -32,8 +32,8 @@
32
32
  "build:server": "tsc",
33
33
  "build:css": "cp ./node_modules/github-markdown-css/github-markdown.css ./static/github-markdown.css && cp ./node_modules/highlight.js/styles/github.css ./static/highlightjs-github.css",
34
34
  "build:js": "esbuild --bundle --platform=browser --format=esm --outfile=./static/convert-markdown.js ./script/convert-markdown.ts",
35
- "fmt": "prettier --write ./src/**/*.ts ./**/*.html && eslint ./src/**/*.ts --fix",
36
- "lint": "prettier --check ./src/**/*.ts ./**/*.html && eslint ./src/**/*.ts",
35
+ "fmt": "biome check --write ./src/**/*.ts ./**/*.html",
36
+ "lint": "biome check ./src/**/*.ts ./**/*.html",
37
37
  "release": "npm run build && npm publish",
38
38
  "start": "npm run build && node ./index.js",
39
39
  "test": "jest",
@@ -47,32 +47,24 @@
47
47
  "log4js": "^6.9.1",
48
48
  "opener": "^1.5.2",
49
49
  "serve-index": "^1.9.1",
50
- "ws": "^8.16.0"
50
+ "ws": "^8.17.0"
51
51
  },
52
52
  "devDependencies": {
53
+ "@biomejs/biome": "1.8.3",
53
54
  "@types/express": "^4.17.21",
54
55
  "@types/express-ws": "^3.0.4",
55
56
  "@types/jest": "^29.5.12",
56
57
  "@types/opener": "^1.4.3",
57
58
  "@types/serve-index": "^1.9.4",
58
59
  "emojilib": "^3.0.12",
59
- "esbuild": "^0.21.1",
60
- "eslint": "^8.57.0",
61
- "eslint-config-prettier": "^9.1.0",
62
- "eslint-plugin-jest": "^28.2.0",
63
- "eslint-plugin-node": "^11.1.0",
64
- "eslint-plugin-prettier": "^5.1.3",
65
- "eslint-plugin-react": "^7.34.1",
66
- "eslint-plugin-react-hooks": "^4.6.0",
67
- "eslint-plugin-simple-import-sort": "^12.1.0",
68
- "eslint-plugin-unused-imports": "^3.1.0",
60
+ "esbuild": "^0.21.3",
69
61
  "github-markdown-css": "^5.5.1",
70
62
  "highlight.js": "^11.9.0",
71
63
  "jest": "^29.7.0",
72
64
  "marked": "^12.0.2",
73
65
  "marked-emoji": "^1.4.0",
74
66
  "marked-highlight": "^2.1.1",
75
- "mermaid": "^10.9.0",
67
+ "mermaid": "^10.9.1",
76
68
  "nodemon": "^3.1.0",
77
69
  "ts-jest": "^29.1.2",
78
70
  "typescript": "^5.4.5"
@@ -83,9 +75,6 @@
83
75
  "static/**/*",
84
76
  "template/**/*"
85
77
  ],
86
- "prettier": {
87
- "printWidth": 120
88
- },
89
78
  "jest": {
90
79
  "preset": "ts-jest",
91
80
  "testEnvironment": "node"
@@ -4,8 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.templateDir = exports.staticDir = exports.projectDir = exports.rootDir = void 0;
7
- const path_1 = __importDefault(require("path"));
7
+ const node_path_1 = __importDefault(require("node:path"));
8
8
  exports.rootDir = process.cwd();
9
- exports.projectDir = path_1.default.resolve(__dirname, "..", "..");
10
- exports.staticDir = path_1.default.resolve(exports.projectDir, "static");
11
- exports.templateDir = path_1.default.resolve(exports.projectDir, "template");
9
+ exports.projectDir = node_path_1.default.resolve(__dirname, "..", "..");
10
+ exports.staticDir = node_path_1.default.resolve(exports.projectDir, "static");
11
+ exports.templateDir = node_path_1.default.resolve(exports.projectDir, "template");
package/src/lib/file.js CHANGED
@@ -4,10 +4,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.existsFile = void 0;
7
- const fs_1 = __importDefault(require("fs"));
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
8
  function existsFile(filepath) {
9
9
  try {
10
- fs_1.default.statSync(filepath);
10
+ node_fs_1.default.statSync(filepath);
11
11
  return true;
12
12
  }
13
13
  catch (_) {
@@ -4,20 +4,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.FileWatcher = void 0;
7
- const fs_1 = __importDefault(require("fs"));
8
- const path_1 = __importDefault(require("path"));
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
9
  const directory_1 = require("./directory");
10
10
  class FileWatcher {
11
11
  constructor(logger) {
12
12
  this.logger = logger;
13
13
  this._target = {};
14
14
  setInterval(() => {
15
- Object.keys(this._target).forEach((filepath) => {
15
+ for (const filepath in this._target) {
16
16
  try {
17
17
  const fileinfo = this._target[filepath];
18
18
  const currentLastModified = this.getFileLastModified(filepath);
19
19
  if (fileinfo.lastModified !== currentLastModified) {
20
- this.logger.info("File update:", path_1.default.resolve(directory_1.rootDir, filepath));
20
+ this.logger.info("File update:", node_path_1.default.resolve(directory_1.rootDir, filepath));
21
21
  fileinfo.lastModified = currentLastModified;
22
22
  if (this._onFileChanged != null) {
23
23
  this._onFileChanged(this.getFileInfo(filepath));
@@ -27,7 +27,7 @@ class FileWatcher {
27
27
  catch (err) {
28
28
  console.error(err);
29
29
  }
30
- });
30
+ }
31
31
  }, 250 /* check 4 times per second */);
32
32
  }
33
33
  onFileChanged(callback) {
@@ -48,11 +48,11 @@ class FileWatcher {
48
48
  delete this._target[filepath];
49
49
  }
50
50
  getFileLastModified(filepath) {
51
- return fs_1.default.statSync(path_1.default.resolve(directory_1.rootDir, filepath)).mtimeMs;
51
+ return node_fs_1.default.statSync(node_path_1.default.resolve(directory_1.rootDir, filepath)).mtimeMs;
52
52
  }
53
53
  getFileInfo(filepath) {
54
- const absolutePath = path_1.default.resolve(directory_1.rootDir, filepath);
55
- const markdown = fs_1.default.readFileSync(absolutePath, "utf-8");
54
+ const absolutePath = node_path_1.default.resolve(directory_1.rootDir, filepath);
55
+ const markdown = node_fs_1.default.readFileSync(absolutePath, "utf-8");
56
56
  return { filepath, markdown };
57
57
  }
58
58
  }
package/src/lib/params.js CHANGED
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Params = void 0;
7
- const path_1 = __importDefault(require("path"));
7
+ const node_path_1 = __importDefault(require("node:path"));
8
8
  const directory_1 = require("./directory");
9
9
  const file_1 = require("./file");
10
10
  const logger_1 = require("./logger");
@@ -46,7 +46,7 @@ class Params {
46
46
  params.template = env.MARKDOWN_PREVIEW_TEMPLATE;
47
47
  }
48
48
  if (env.MARKDOWN_PREVIEW_PORT) {
49
- params.port = parseInt(env.MARKDOWN_PREVIEW_PORT, 10);
49
+ params.port = Number.parseInt(env.MARKDOWN_PREVIEW_PORT, 10);
50
50
  }
51
51
  if (env.MARKDOWN_PREVIEW_NO_OPENER) {
52
52
  params.noOpener = env.MARKDOWN_PREVIEW_NO_OPENER === "true";
@@ -77,7 +77,7 @@ class Params {
77
77
  break;
78
78
  case "-p":
79
79
  case "--port":
80
- params.port = parseInt(argv[i + 1], 10);
80
+ params.port = Number.parseInt(argv[i + 1], 10);
81
81
  i++;
82
82
  break;
83
83
  case "-l":
@@ -103,13 +103,13 @@ class Params {
103
103
  return params;
104
104
  }
105
105
  checkFilepath(filepath) {
106
- if (path_1.default.isAbsolute(filepath)) {
106
+ if (node_path_1.default.isAbsolute(filepath)) {
107
107
  throw new Error(`Absolute path is prohibited: ${filepath}`);
108
108
  }
109
109
  if (!(0, file_1.existsFile)(filepath)) {
110
110
  throw new Error(`File not found: ${filepath}`);
111
111
  }
112
- if (path_1.default.relative(directory_1.rootDir, filepath).match(/\.\./) != null) {
112
+ if (node_path_1.default.relative(directory_1.rootDir, filepath).match(/\.\./) != null) {
113
113
  throw new Error(`Illegal file path: ${filepath}`);
114
114
  }
115
115
  return filepath;
@@ -122,16 +122,16 @@ class Params {
122
122
  return extensionList;
123
123
  }
124
124
  checkTemplate(template) {
125
- if ((0, file_1.existsFile)(path_1.default.resolve(directory_1.templateDir, `${template}.html`))) {
126
- return path_1.default.resolve(directory_1.templateDir, `${template}.html`);
125
+ if ((0, file_1.existsFile)(node_path_1.default.resolve(directory_1.templateDir, `${template}.html`))) {
126
+ return node_path_1.default.resolve(directory_1.templateDir, `${template}.html`);
127
127
  }
128
- else if ((0, file_1.existsFile)(path_1.default.resolve(directory_1.rootDir, template))) {
129
- return path_1.default.resolve(directory_1.rootDir, template);
128
+ if ((0, file_1.existsFile)(node_path_1.default.resolve(directory_1.rootDir, template))) {
129
+ return node_path_1.default.resolve(directory_1.rootDir, template);
130
130
  }
131
131
  throw new Error(`Template file not found: ${template}`);
132
132
  }
133
133
  checkPort(port) {
134
- if (!isNaN(port) && 0 < port && port <= 65535) {
134
+ if (!Number.isNaN(port) && 0 < port && port <= 65535) {
135
135
  return port;
136
136
  }
137
137
  throw new Error(`Invalid port: ${port}`);
@@ -3,13 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const path_1 = __importDefault(require("path"));
6
+ const node_path_1 = __importDefault(require("node:path"));
7
7
  const directory_1 = require("./directory");
8
8
  const params_1 = require("./params");
9
9
  const DEFAULT_VALUES = {
10
10
  filepath: "README.md",
11
11
  extensions: ["md", "markdown"],
12
- template: path_1.default.resolve(directory_1.projectDir, "template/default.html"),
12
+ template: node_path_1.default.resolve(directory_1.projectDir, "template/default.html"),
13
13
  port: 34567,
14
14
  logLevel: "info",
15
15
  noOpener: false,
@@ -37,7 +37,7 @@ describe("Params", () => {
37
37
  const expectParams = {
38
38
  filepath: "test/markdown/markdown1.md",
39
39
  extensions: ["ext1", "ext2"],
40
- template: path_1.default.resolve(directory_1.projectDir, "test/template/template1.html"),
40
+ template: node_path_1.default.resolve(directory_1.projectDir, "test/template/template1.html"),
41
41
  port: 100,
42
42
  logLevel: "info",
43
43
  noOpener: false,
@@ -66,7 +66,7 @@ describe("Params", () => {
66
66
  const expectParams = {
67
67
  filepath: "test/markdown/markdown1.md",
68
68
  extensions: ["ext1", "ext2"],
69
- template: path_1.default.resolve(directory_1.projectDir, "test/template/template1.html"),
69
+ template: node_path_1.default.resolve(directory_1.projectDir, "test/template/template1.html"),
70
70
  port: 100,
71
71
  logLevel: "trace",
72
72
  noOpener: true,
@@ -88,7 +88,7 @@ describe("Params", () => {
88
88
  const expectParams = {
89
89
  filepath: "test/markdown/markdown1.md",
90
90
  extensions: ["ext1", "ext2"],
91
- template: path_1.default.resolve(directory_1.projectDir, "test/template/template1.html"),
91
+ template: node_path_1.default.resolve(directory_1.projectDir, "test/template/template1.html"),
92
92
  port: 100,
93
93
  logLevel: "trace",
94
94
  noOpener: true,
@@ -12,7 +12,9 @@ class SocketManager {
12
12
  this._sockets = this._sockets.filter(({ socket: s }) => s !== socket);
13
13
  }
14
14
  getSockets(filepath) {
15
- return this._sockets.filter(({ filepath: fp }) => fp === filepath).map((s) => s.socket);
15
+ return this._sockets
16
+ .filter(({ filepath: fp }) => fp === filepath)
17
+ .map((s) => s.socket);
16
18
  }
17
19
  countSocket(filepath = null) {
18
20
  if (filepath == null) {
@@ -1,9 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const socket_manager_1 = require("./socket_manager");
4
- const dummySocket1 = { name: "socket1" }; // eslint-disable-line @typescript-eslint/no-explicit-any
5
- const dummySocket2 = { name: "socket2" }; // eslint-disable-line @typescript-eslint/no-explicit-any
6
- const dummySocket3 = { name: "socket3" }; // eslint-disable-line @typescript-eslint/no-explicit-any
4
+ // biome-ignore lint/suspicious/noExplicitAny: It is used for testing only.
5
+ const dummySocket1 = { name: "socket1" };
6
+ // biome-ignore lint/suspicious/noExplicitAny: It is used for testing only.
7
+ const dummySocket2 = { name: "socket2" };
8
+ // biome-ignore lint/suspicious/noExplicitAny: It is used for testing only.
9
+ const dummySocket3 = { name: "socket3" };
7
10
  const dummyFilepath1 = "file1";
8
11
  const dummyFilepath2 = "file2";
9
12
  const dummyInfo1 = { socket: dummySocket1, filepath: dummyFilepath1 };
@@ -18,9 +21,16 @@ describe("SocketManager", () => {
18
21
  socketManager.addSocket(dummySocket2, dummyFilepath2);
19
22
  expect(socketManager._sockets).toEqual([dummyInfo1, dummyInfo2]);
20
23
  socketManager.addSocket(dummySocket3, dummyFilepath2);
21
- expect(socketManager._sockets).toEqual([dummyInfo1, dummyInfo2, dummyInfo3]);
24
+ expect(socketManager._sockets).toEqual([
25
+ dummyInfo1,
26
+ dummyInfo2,
27
+ dummyInfo3,
28
+ ]);
22
29
  expect(socketManager.getSockets(dummyFilepath1)).toEqual([dummySocket1]);
23
- expect(socketManager.getSockets(dummyFilepath2)).toEqual([dummySocket2, dummySocket3]);
30
+ expect(socketManager.getSockets(dummyFilepath2)).toEqual([
31
+ dummySocket2,
32
+ dummySocket3,
33
+ ]);
24
34
  expect(socketManager.countSocket()).toEqual(3);
25
35
  expect(socketManager.countSocket(dummyFilepath1)).toEqual(1);
26
36
  expect(socketManager.countSocket(dummyFilepath2)).toEqual(2);