diagram-2020 0.0.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/diagram.txt +3 -0
- package/index.html +39 -0
- package/mermaid.min.js +2029 -0
- package/package.json +18 -0
- package/server.js +161 -0
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "diagram-2020",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"start": "node server.js"
|
|
7
|
+
},
|
|
8
|
+
"bin": {
|
|
9
|
+
"diagram": "server.js"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"chokidar": "^3.6.0",
|
|
13
|
+
"express": "^4.19.2",
|
|
14
|
+
"livereload": "^0.9.3",
|
|
15
|
+
"connect-livereload": "^0.6.1",
|
|
16
|
+
"node-fetch": "^3.3.2"
|
|
17
|
+
}
|
|
18
|
+
}
|
package/server.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import fetch from "node-fetch";
|
|
5
|
+
import chokidar from "chokidar";
|
|
6
|
+
import express from "express";
|
|
7
|
+
import livereload from "livereload";
|
|
8
|
+
import connectLiveReload from "connect-livereload";
|
|
9
|
+
|
|
10
|
+
const PORT = 3000;
|
|
11
|
+
const MERMAID_URL =
|
|
12
|
+
"https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js";
|
|
13
|
+
|
|
14
|
+
const MERMAID_FILE = "mermaid.min.js";
|
|
15
|
+
const DIAGRAM_FILE = "diagram.txt";
|
|
16
|
+
const HTML_FILE = "index.html";
|
|
17
|
+
|
|
18
|
+
function humanize(text) {
|
|
19
|
+
return text
|
|
20
|
+
.replace(/([A-Z])/g, " $1")
|
|
21
|
+
.replace(/_/g, " ")
|
|
22
|
+
.toLowerCase()
|
|
23
|
+
.trim();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function processDiagram(raw) {
|
|
27
|
+
const lines = raw
|
|
28
|
+
.split("\n")
|
|
29
|
+
.map(l => l.trim())
|
|
30
|
+
.filter(Boolean);
|
|
31
|
+
|
|
32
|
+
const groups = {};
|
|
33
|
+
const relations = [];
|
|
34
|
+
|
|
35
|
+
for (const line of lines) {
|
|
36
|
+
relations.push(line);
|
|
37
|
+
|
|
38
|
+
const nodes = line
|
|
39
|
+
.replace(/:.+$/, "")
|
|
40
|
+
.split("-->")
|
|
41
|
+
.map(s => s.trim());
|
|
42
|
+
|
|
43
|
+
for (const node of nodes) {
|
|
44
|
+
const [group, state] = node.split("_");
|
|
45
|
+
if (!group || !state) continue;
|
|
46
|
+
|
|
47
|
+
if (!groups[group]) {
|
|
48
|
+
groups[group] = new Set();
|
|
49
|
+
}
|
|
50
|
+
groups[group].add(node);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let output = [];
|
|
55
|
+
output.push("stateDiagram-v2");
|
|
56
|
+
|
|
57
|
+
// group labels
|
|
58
|
+
for (const group of Object.keys(groups)) {
|
|
59
|
+
output.push(`${group}: ${humanize(group)}`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// group states
|
|
63
|
+
for (const [group, states] of Object.entries(groups)) {
|
|
64
|
+
output.push(`state ${group} {`);
|
|
65
|
+
for (const full of states) {
|
|
66
|
+
const label = full.split("_")[1];
|
|
67
|
+
output.push(` ${full}: ${humanize(label)}`);
|
|
68
|
+
}
|
|
69
|
+
output.push("}");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// relations
|
|
73
|
+
output.push(...relations);
|
|
74
|
+
|
|
75
|
+
return output.join("\n");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
/* =========================
|
|
80
|
+
1. DOWNLOAD MERMAID JS
|
|
81
|
+
========================= */
|
|
82
|
+
async function ensureMermaid() {
|
|
83
|
+
if (fs.existsSync(MERMAID_FILE)) {
|
|
84
|
+
console.log("✅ mermaid.min.js sudah ada");
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
console.log("⬇️ Downloading mermaid.min.js...");
|
|
89
|
+
const res = await fetch(MERMAID_URL);
|
|
90
|
+
const text = await res.text();
|
|
91
|
+
fs.writeFileSync(MERMAID_FILE, text);
|
|
92
|
+
console.log("✅ mermaid.min.js berhasil di-download");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* =========================
|
|
96
|
+
2. GENERATE HTML
|
|
97
|
+
========================= */
|
|
98
|
+
function generateHTML() {
|
|
99
|
+
let diagram = fs.existsSync(DIAGRAM_FILE)
|
|
100
|
+
? fs.readFileSync(DIAGRAM_FILE, "utf8")
|
|
101
|
+
: "";
|
|
102
|
+
|
|
103
|
+
diagram = processDiagram(diagram)
|
|
104
|
+
|
|
105
|
+
const html = `<!DOCTYPE html>
|
|
106
|
+
<html lang="en">
|
|
107
|
+
<head>
|
|
108
|
+
<meta charset="UTF-8" />
|
|
109
|
+
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
110
|
+
<title>Mermaid Preview</title>
|
|
111
|
+
<script src="./mermaid.min.js"></script>
|
|
112
|
+
<script>
|
|
113
|
+
mermaid.initialize({ startOnLoad: true });
|
|
114
|
+
</script>
|
|
115
|
+
<style>
|
|
116
|
+
body {
|
|
117
|
+
font-family: sans-serif;
|
|
118
|
+
padding: 20px;
|
|
119
|
+
}
|
|
120
|
+
</style>
|
|
121
|
+
</head>
|
|
122
|
+
<body>
|
|
123
|
+
<div class="mermaid">
|
|
124
|
+
${diagram}
|
|
125
|
+
</div>
|
|
126
|
+
</body>
|
|
127
|
+
</html>`;
|
|
128
|
+
|
|
129
|
+
fs.writeFileSync(HTML_FILE, html);
|
|
130
|
+
console.log("🔄 index.html updated");
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/* =========================
|
|
134
|
+
3. LIVE RELOAD SERVER
|
|
135
|
+
========================= */
|
|
136
|
+
const liveReloadServer = livereload.createServer();
|
|
137
|
+
liveReloadServer.watch(process.cwd());
|
|
138
|
+
|
|
139
|
+
const app = express();
|
|
140
|
+
app.use(connectLiveReload());
|
|
141
|
+
app.use(express.static(process.cwd()));
|
|
142
|
+
|
|
143
|
+
app.listen(PORT, () => {
|
|
144
|
+
console.log(`🚀 Static server running at http://localhost:${PORT}`);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
/* =========================
|
|
148
|
+
4. WATCH FILE
|
|
149
|
+
========================= */
|
|
150
|
+
async function main() {
|
|
151
|
+
await ensureMermaid();
|
|
152
|
+
generateHTML();
|
|
153
|
+
|
|
154
|
+
chokidar.watch(DIAGRAM_FILE).on("change", () => {
|
|
155
|
+
console.log("✏️ diagram.txt changed");
|
|
156
|
+
generateHTML();
|
|
157
|
+
liveReloadServer.refresh("/");
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
main();
|