docstodev 1.0.0 → 1.0.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.
@@ -1,142 +1,558 @@
1
- // Emplacement absolu : M:\workspace\extensions\docstodev\src\exporters\html.ts
2
1
  import { writeFileSync } from "node:fs";
3
2
  import path from "node:path";
4
3
 
5
- export function exportToHTML(docsDir: string, markdownContent: string, mermaidGraph: string, lang: "fr" | "en" = "fr") {
6
- const lines = markdownContent.split('\n');
4
+ interface TreeStructure {
5
+ [key: string]: TreeStructure | null;
6
+ }
7
+
8
+ export function exportToHTML(
9
+ docsDir: string,
10
+ markdownContent: string,
11
+ mermaidGraph: string,
12
+ lang: "fr" | "en" = "fr",
13
+ fileTree?: TreeStructure
14
+ ) {
15
+ const lines = markdownContent.split("\n");
16
+
7
17
  let htmlResult = "";
8
18
  let inTable = false;
19
+ let inSection = false;
9
20
 
10
- const formatText = (text: string) => {
11
- return text
12
- .replace(/`(.*?)`/g, '<code>$1</code>')
13
- .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
21
+ const formatText = (text: string) =>
22
+ text
23
+ .replace(/`(.*?)`/g, "<code>$1</code>")
24
+ .replace(/\*\*(.*?)\*\*/g, "$1")
14
25
  .replace(/\[(.*?)\]\((.*?)\)/g, '<a href="$2">$1</a>');
15
- };
16
-
17
- lines.forEach(line => {
18
- let processed = line.trim();
19
-
20
- if (processed.startsWith('|')) {
21
- if (!inTable) { htmlResult += '<div class="table-container"><table>'; inTable = true; }
22
- if (processed.includes('---')) return;
23
- const cells = processed.split('|').filter(c => c.trim() !== "");
24
- const tag = (processed.includes('Module') || processed.includes('Type')) ? 'th' : 'td';
25
- htmlResult += `<tr>${cells.map(c => `<${tag}>${formatText(c.trim())}</${tag}>`).join('')}</tr>`;
26
- return;
27
- } else if (inTable) { htmlResult += '</table></div>'; inTable = false; }
28
-
29
- if (processed.includes('├─') || processed.includes('└─') || processed.includes('│')) {
30
- const treeLine = line
26
+
27
+ for (const line of lines) {
28
+ const processed = line.trim();
29
+
30
+ /* ================= TABLES ================= */
31
+ if (processed.startsWith("|")) {
32
+ if (!inTable) {
33
+ htmlResult += `<div class="table-container"><table>`;
34
+ inTable = true;
35
+ }
36
+ if (processed.includes("---")) continue;
37
+
38
+ const cells = processed.split("|").filter(c => c.trim());
39
+ const isHeader = processed.includes("Module") || processed.includes("Type");
40
+
41
+ htmlResult += `<tr>${
42
+ cells.map(c =>
43
+ isHeader
44
+ ? `<th>${formatText(c.trim())}</th>`
45
+ : `<td>${formatText(c.trim())}</td>`
46
+ ).join("")
47
+ }</tr>`;
48
+ continue;
49
+ } else if (inTable) {
50
+ htmlResult += "</table></div>";
51
+ inTable = false;
52
+ }
53
+
54
+ /* ================= TREE VIEW ================= */
55
+ if (
56
+ processed.match(/^[│├└─\s]+/) ||
57
+ processed.includes("/") ||
58
+ processed.match(/\.(ts|js|py|java|cs|go|rs|tsx|jsx)$/)
59
+ ) {
60
+ const hasFile = processed.match(/\.(ts|js|py|java|cs|go|rs|tsx|jsx)$/);
61
+ const fileMatch = hasFile ? processed.match(/([\w-]+\.(ts|js|py|java|cs|go|rs|tsx|jsx))/)?.[0] : null;
62
+
63
+ let treeLine = line
31
64
  .replace(/├─/g, '<span class="branch">├─</span>')
32
65
  .replace(/└─/g, '<span class="branch">└─</span>')
33
66
  .replace(/│/g, '<span class="pipe">│</span>');
67
+
68
+ if (fileMatch) {
69
+ treeLine = treeLine.replace(
70
+ fileMatch,
71
+ `<span class="file-badge">${fileMatch}</span>`
72
+ );
73
+ }
74
+
34
75
  htmlResult += `<div class="tree-line">${formatText(treeLine)}</div>`;
35
- return;
76
+ continue;
36
77
  }
37
78
 
38
- if (processed.startsWith('# ')) {
39
- htmlResult += `<h1>${processed.replace('# ', '')}</h1>`;
40
- } else if (processed.startsWith('## ')) {
41
- htmlResult += `<h2>${processed.replace('## ', '')}</h2>`;
42
- } else if (processed.startsWith('### ')) {
43
- if (htmlResult.includes('</section>')) htmlResult += '</section>';
44
- htmlResult += `<section class="component-card"><h3 class="comp-title">${formatText(processed.replace('### ', ''))}</h3>`;
45
- } else if (processed.startsWith('•') || processed.startsWith('- ') || processed.startsWith('* ')) {
46
- htmlResult += `<div class="list-item">${formatText(processed.replace(/^[\-\*•]\s+/, ''))}</div>`;
47
- } else if (processed.length > 0) {
79
+ /* ================= HEADERS ================= */
80
+ if (processed.startsWith("# ")) {
81
+ htmlResult += `<h1>${processed.slice(2)}</h1>`;
82
+ } else if (processed.startsWith("## ")) {
83
+ if (inSection) {
84
+ htmlResult += "</section>";
85
+ inSection = false;
86
+ }
87
+ htmlResult += `<h2>${processed.slice(3)}</h2>`;
88
+ } else if (processed.startsWith("### ")) {
89
+ if (inSection) htmlResult += "</section>";
90
+ htmlResult += `<section class="component"><h3>${formatText(processed.slice(4))}</h3>`;
91
+ inSection = true;
92
+ }
93
+
94
+ /* ================= LISTS ================= */
95
+ else if (/^[-*•]\s+/.test(processed)) {
96
+ htmlResult += `<div class="list-item">${formatText(processed.replace(/^[-*•]\s+/, ""))}</div>`;
97
+ }
98
+
99
+ /* ================= PARAGRAPHS ================= */
100
+ else if (processed.length > 0) {
48
101
  htmlResult += `<p>${formatText(processed)}</p>`;
49
102
  }
50
- });
103
+ }
104
+
105
+ if (inSection) htmlResult += "</section>";
51
106
 
52
- if (htmlResult.includes('<section')) htmlResult += '</section>';
107
+ // Générer la vue hiérarchique dynamiquement
108
+ const hierarchyGraph = fileTree ? generateHierarchyGraph(fileTree) : getDefaultHierarchyGraph();
109
+
110
+ // Générer le flux de données (peut être personnalisé selon les imports/exports)
111
+ const dataFlowGraph = generateDataFlowGraph();
53
112
 
54
113
  const html = `<!DOCTYPE html>
55
114
  <html lang="${lang}" data-theme="dark">
56
115
  <head>
57
- <meta charset="UTF-8">
58
- <title>DocsToDev | Rapport Technique</title>
59
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500&family=Fira+Code:wght@400&display=swap" rel="stylesheet">
60
- <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
61
- <style>
62
- :root[data-theme="dark"] {
63
- --bg: #0d1117; --card: #161b22; --text: #c9d1d9; --text-dim: #8b949e;
64
- --accent: #58a6ff; --border: #30363d; --code-bg: rgba(110, 118, 129, 0.2);
65
- --code-text: #ff7b72; --h-color: #f0f6fc;
66
- }
67
- :root[data-theme="light"] {
68
- --bg: #ffffff; --card: #f8f9fa; --text: #24292f; --text-dim: #57606a;
69
- --accent: #0969da; --border: #d0d7de; --code-bg: #afb8c133;
70
- --code-text: #cf222e; --h-color: #1b1f24;
71
- }
116
+ <meta charset="UTF-8">
117
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
118
+ <title>DocsToDev Rapport Technique</title>
72
119
 
73
- body { font-family: 'Inter', sans-serif; background: var(--bg); color: var(--text); padding: 2rem; line-height: 1.6; font-weight: 300; transition: background 0.3s; }
74
- .container { max-width: 1100px; margin: auto; }
75
-
76
- .controls { position: sticky; top: 10px; display: flex; gap: 1rem; margin-bottom: 2rem; z-index: 100; }
77
- #search { flex: 1; padding: 12px 20px; border-radius: 25px; border: 1px solid var(--border); background: var(--card); color: var(--text); outline: none; font-weight: 300; box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
78
- .btn { padding: 10px 20px; border-radius: 25px; cursor: pointer; border: 1px solid var(--border); background: var(--card); color: var(--text); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 1px; }
79
- .pdf-btn { background: #238636; color: white; border: none; }
120
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400&family=Fira+Code&display=swap" rel="stylesheet">
121
+ <script defer src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
80
122
 
81
- h1 { font-weight: 500; font-size: 2.2rem; color: var(--accent); letter-spacing: -1px; }
82
- h2 { font-weight: 400; color: var(--h-color); border-bottom: 1px solid var(--border); padding-bottom: 10px; margin-top: 3.5rem; }
83
-
84
- .mermaid { background: var(--card); padding: 1.5rem; border-radius: 12px; border: 1px solid var(--border); margin: 1.5rem 0; overflow: auto; }
85
- .component-card { background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 1.5rem; margin-bottom: 1.5rem; }
86
- .comp-title { margin: 0 0 1rem 0 !important; color: var(--accent) !important; font-weight: 400; font-size: 1.2rem; border-bottom: 1px solid var(--border); padding-bottom: 10px !important; }
87
-
88
- .tree-line { font-family: 'Fira Code', monospace; font-size: 0.85rem; color: var(--text-dim); white-space: pre; line-height: 1.4; }
89
- .branch { color: var(--accent); opacity: 0.7; }
90
-
91
- .table-container { margin: 1.5rem 0; border-radius: 8px; border: 1px solid var(--border); overflow: hidden; }
92
- table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
93
- th { background: rgba(88, 166, 255, 0.05); color: var(--accent); font-weight: 500; text-align: left; padding: 12px; border-bottom: 1px solid var(--border); }
94
- td { padding: 10px 12px; border-bottom: 1px solid var(--border); }
95
-
96
- code { font-family: 'Fira Code', monospace; background: var(--code-bg); color: var(--code-text); padding: 2px 6px; border-radius: 4px; font-size: 0.9em; font-weight: 400; }
97
- a { color: var(--accent); text-decoration: none; }
98
- .list-item { margin-bottom: 8px; }
99
- .list-item::before { content: "•"; color: var(--accent); margin-right: 12px; font-weight: bold; }
100
-
101
- @media print { .controls { display: none; } body { padding: 0; } .container { max-width: 100%; border: none; } }
102
- </style>
123
+ <style>
124
+ :root[data-theme="dark"] {
125
+ --bg: #0d1117;
126
+ --card: #161b22;
127
+ --text: #c9d1d9;
128
+ --muted: #8b949e;
129
+ --border: #30363d;
130
+ --accent: #58a6ff;
131
+ --code-bg: #1f2428;
132
+ --file-badge-bg: rgba(248, 81, 73, 0.15);
133
+ --file-badge-text: #f85149;
134
+ }
135
+
136
+ :root[data-theme="light"] {
137
+ --bg: #ffffff;
138
+ --card: #f6f8fa;
139
+ --text: #24292f;
140
+ --muted: #57606a;
141
+ --border: #d0d7de;
142
+ --accent: #0969da;
143
+ --code-bg: #eaeef2;
144
+ --file-badge-bg: rgba(218, 54, 51, 0.15);
145
+ --file-badge-text: #da3633;
146
+ }
147
+
148
+ * {
149
+ margin: 0;
150
+ padding: 0;
151
+ box-sizing: border-box;
152
+ }
153
+
154
+ body {
155
+ font-family: Inter, sans-serif;
156
+ background: var(--bg);
157
+ color: var(--text);
158
+ line-height: 1.6;
159
+ }
160
+
161
+ .container {
162
+ max-width: 1400px;
163
+ margin: 0 auto;
164
+ padding: 2rem;
165
+ }
166
+
167
+ .controls {
168
+ position: sticky;
169
+ top: 0;
170
+ background: var(--bg);
171
+ padding: 1rem 0;
172
+ display: flex;
173
+ gap: 0.75rem;
174
+ z-index: 100;
175
+ border-bottom: 1px solid var(--border);
176
+ margin-bottom: 2rem;
177
+ }
178
+
179
+ #search {
180
+ flex: 1;
181
+ padding: 0.6rem 1rem;
182
+ border: 1px solid var(--border);
183
+ background: var(--card);
184
+ color: var(--text);
185
+ font-size: 0.95rem;
186
+ font-family: Inter, sans-serif;
187
+ transition: border-color 0.2s;
188
+ }
189
+
190
+ #search:focus {
191
+ outline: none;
192
+ border-color: var(--accent);
193
+ }
194
+
195
+ button {
196
+ padding: 0.6rem 1.2rem;
197
+ border: 1px solid var(--border);
198
+ background: var(--card);
199
+ color: var(--text);
200
+ cursor: pointer;
201
+ font-size: 0.95rem;
202
+ font-family: Inter, sans-serif;
203
+ transition: all 0.2s;
204
+ display: flex;
205
+ align-items: center;
206
+ gap: 0.5rem;
207
+ }
208
+
209
+ button:hover {
210
+ background: var(--border);
211
+ }
212
+
213
+ button svg {
214
+ width: 16px;
215
+ height: 16px;
216
+ }
217
+
218
+ h1 {
219
+ font-size: 2.5rem;
220
+ color: var(--accent);
221
+ margin-bottom: 3rem;
222
+ font-weight: 400;
223
+ letter-spacing: -0.02em;
224
+ }
225
+
226
+ h2 {
227
+ font-size: 1.5rem;
228
+ margin: 3rem 0 1.5rem 0;
229
+ padding-bottom: 0.75rem;
230
+ border-bottom: 1px solid var(--border);
231
+ font-weight: 400;
232
+ color: var(--text);
233
+ }
234
+
235
+ h3 {
236
+ font-size: 1.1rem;
237
+ margin-bottom: 1rem;
238
+ color: var(--accent);
239
+ font-weight: 400;
240
+ }
241
+
242
+ .graphs-grid {
243
+ display: grid;
244
+ grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
245
+ gap: 2rem;
246
+ margin: 2rem 0;
247
+ }
248
+
249
+ .graph-container {
250
+ border: 1px solid var(--border);
251
+ background: var(--card);
252
+ padding: 1.5rem;
253
+ }
254
+
255
+ .graph-title {
256
+ font-size: 1rem;
257
+ color: var(--muted);
258
+ margin-bottom: 1rem;
259
+ text-transform: uppercase;
260
+ letter-spacing: 0.05em;
261
+ font-size: 0.85rem;
262
+ }
263
+
264
+ .component {
265
+ border: 1px solid var(--border);
266
+ background: var(--card);
267
+ padding: 1.5rem;
268
+ margin-bottom: 1.5rem;
269
+ }
270
+
271
+ .tree-line {
272
+ font-family: "Fira Code", monospace;
273
+ font-size: 0.85rem;
274
+ white-space: pre;
275
+ color: var(--muted);
276
+ line-height: 1.8;
277
+ }
278
+
279
+ .branch {
280
+ color: var(--accent);
281
+ }
282
+
283
+ .pipe {
284
+ color: var(--border);
285
+ }
286
+
287
+ .file-badge {
288
+ background: var(--file-badge-bg);
289
+ color: var(--file-badge-text);
290
+ padding: 0.15rem 0.5rem;
291
+ font-size: 0.8rem;
292
+ font-family: "Fira Code", monospace;
293
+ display: inline-block;
294
+ margin-left: 0.25rem;
295
+ }
296
+
297
+ .table-container {
298
+ border: 1px solid var(--border);
299
+ margin: 1.5rem 0;
300
+ overflow-x: auto;
301
+ background: var(--card);
302
+ }
303
+
304
+ table {
305
+ width: 100%;
306
+ border-collapse: collapse;
307
+ font-size: 0.9rem;
308
+ }
309
+
310
+ th, td {
311
+ border-bottom: 1px solid var(--border);
312
+ padding: 0.75rem 1rem;
313
+ text-align: left;
314
+ }
315
+
316
+ th {
317
+ background: var(--bg);
318
+ color: var(--muted);
319
+ text-transform: uppercase;
320
+ font-size: 0.8rem;
321
+ letter-spacing: 0.05em;
322
+ font-weight: 400;
323
+ }
324
+
325
+ tr:last-child td {
326
+ border-bottom: none;
327
+ }
328
+
329
+ code {
330
+ font-family: "Fira Code", monospace;
331
+ background: var(--code-bg);
332
+ padding: 0.2rem 0.4rem;
333
+ font-size: 0.9em;
334
+ color: var(--accent);
335
+ }
336
+
337
+ .list-item {
338
+ margin-bottom: 0.5rem;
339
+ padding-left: 1.5rem;
340
+ position: relative;
341
+ }
342
+
343
+ .list-item::before {
344
+ content: "";
345
+ position: absolute;
346
+ left: 0.5rem;
347
+ top: 0.7rem;
348
+ width: 4px;
349
+ height: 4px;
350
+ background: var(--accent);
351
+ }
352
+
353
+ p {
354
+ margin-bottom: 1rem;
355
+ color: var(--muted);
356
+ }
357
+
358
+ a {
359
+ color: var(--accent);
360
+ text-decoration: none;
361
+ }
362
+
363
+ a:hover {
364
+ text-decoration: underline;
365
+ }
366
+
367
+ mark {
368
+ background: #ffd33d;
369
+ color: #000;
370
+ padding: 0.1rem 0.3rem;
371
+ }
372
+
373
+ .mermaid {
374
+ background: transparent;
375
+ overflow: auto;
376
+ }
377
+
378
+ @media print {
379
+ .controls {
380
+ display: none;
381
+ }
382
+
383
+ .container {
384
+ max-width: 100%;
385
+ padding: 0;
386
+ }
387
+
388
+ .component {
389
+ page-break-inside: avoid;
390
+ }
391
+ }
392
+
393
+ @media (max-width: 768px) {
394
+ .graphs-grid {
395
+ grid-template-columns: 1fr;
396
+ }
397
+
398
+ .controls {
399
+ flex-direction: column;
400
+ }
401
+ }
402
+ </style>
103
403
  </head>
404
+
104
405
  <body>
105
- <div class="container">
106
- <div class="controls">
107
- <input type="text" id="search" placeholder="Rechercher par nom, rôle, technologie...">
108
- <button class="btn pdf-btn" onclick="window.print()">📥 Imprimer / PDF</button>
109
- <button class="btn" onclick="toggleTheme()">🌓 Theme</button>
110
- </div>
406
+ <div class="container">
111
407
 
112
- <h2>📊 Graphe des Dépendances</h2>
408
+ <div class="controls">
409
+ <input id="search" placeholder="${lang === 'fr' ? 'Rechercher dans la documentation...' : 'Search in documentation...'}" type="text">
410
+ <button onclick="toggleTheme()">
411
+ <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
412
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/>
413
+ </svg>
414
+ ${lang === 'fr' ? 'Thème' : 'Theme'}
415
+ </button>
416
+ <button onclick="window.print()">
417
+ <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
418
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z"/>
419
+ </svg>
420
+ ${lang === 'fr' ? 'Exporter PDF' : 'Export PDF'}
421
+ </button>
422
+ </div>
423
+
424
+ <h2>${lang === 'fr' ? 'Architecture du projet' : 'Project Architecture'}</h2>
425
+ <div class="graphs-grid">
426
+ <div class="graph-container">
427
+ <div class="graph-title">${lang === 'fr' ? 'Graphe des dépendances' : 'Dependency Graph'}</div>
113
428
  <div class="mermaid">
114
- graph TD
115
- ${mermaidGraph || "A[Projet] --> B[Initialisation]"}
429
+ ${mermaidGraph || "graph TD\n Root[Projet]"}
116
430
  </div>
431
+ </div>
432
+
433
+ <div class="graph-container">
434
+ <div class="graph-title">${lang === 'fr' ? 'Structure du projet' : 'Project Structure'}</div>
435
+ <div class="mermaid">
436
+ ${hierarchyGraph}
437
+ </div>
438
+ </div>
439
+ </div>
117
440
 
118
- <div id="content-area">${htmlResult}</div>
441
+ <div class="graph-container" style="margin-bottom: 3rem;">
442
+ <div class="graph-title">${lang === 'fr' ? 'Flux de données' : 'Data Flow'}</div>
443
+ <div class="mermaid">
444
+ ${dataFlowGraph}
119
445
  </div>
446
+ </div>
120
447
 
121
- <script>
122
- mermaid.initialize({ startOnLoad: true, theme: 'dark', securityLevel: 'loose' });
123
- function toggleTheme() {
124
- const html = document.documentElement;
125
- const next = html.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
126
- html.setAttribute('data-theme', next);
127
- localStorage.setItem('docs-theme', next);
128
- }
129
- document.documentElement.setAttribute('data-theme', localStorage.getItem('docs-theme') || 'dark');
448
+ <div id="content-area">${htmlResult}</div>
449
+
450
+ </div>
130
451
 
131
- document.getElementById('search').addEventListener('input', (e) => {
132
- const term = e.target.value.toLowerCase();
133
- document.querySelectorAll('.component-card, .tree-line, .table-container').forEach(el => {
134
- el.style.display = el.innerText.toLowerCase().includes(term) ? '' : 'none';
135
- });
452
+ <script>
453
+ document.addEventListener("DOMContentLoaded", () => {
454
+ if (window.mermaid) {
455
+ mermaid.initialize({
456
+ startOnLoad: true,
457
+ theme: document.documentElement.dataset.theme === "dark" ? "dark" : "default",
458
+ themeVariables: {
459
+ darkMode: document.documentElement.dataset.theme === "dark",
460
+ background: "transparent",
461
+ primaryColor: "#58a6ff",
462
+ primaryTextColor: "#c9d1d9",
463
+ primaryBorderColor: "#30363d",
464
+ lineColor: "#8b949e",
465
+ secondaryColor: "#161b22",
466
+ tertiaryColor: "#0d1117"
467
+ }
136
468
  });
137
- </script>
469
+ }
470
+ });
471
+
472
+ function toggleTheme() {
473
+ const root = document.documentElement;
474
+ const next = root.dataset.theme === "dark" ? "light" : "dark";
475
+ root.dataset.theme = next;
476
+ localStorage.setItem("theme", next);
477
+
478
+ if (window.mermaid) {
479
+ location.reload();
480
+ }
481
+ }
482
+
483
+ document.documentElement.dataset.theme = localStorage.getItem("theme") || "dark";
484
+
485
+ const originalHTML = document.getElementById("content-area").innerHTML;
486
+
487
+ document.getElementById("search").addEventListener("input", e => {
488
+ const term = e.target.value.trim();
489
+ const container = document.getElementById("content-area");
490
+
491
+ if (!term) {
492
+ container.innerHTML = originalHTML;
493
+ return;
494
+ }
495
+
496
+ const regex = new RegExp("(" + term.replace(/[.*+?^\\\${}()|[\\]\\\\]/g, "\\\\$&") + ")", "gi");
497
+ container.innerHTML = originalHTML.replace(regex, "<mark>$1</mark>");
498
+
499
+ const first = container.querySelector("mark");
500
+ if (first) first.scrollIntoView({ behavior: "smooth", block: "center" });
501
+ });
502
+ </script>
503
+
138
504
  </body>
139
505
  </html>`;
140
506
 
141
507
  writeFileSync(path.join(docsDir, "report.html"), html);
508
+ }
509
+
510
+ function generateHierarchyGraph(tree: TreeStructure, maxDepth = 3): string {
511
+ let graph = "graph TD\n";
512
+ let nodeId = 0;
513
+ const nodeMap = new Map<string, string>();
514
+
515
+ function traverse(obj: TreeStructure, parentId: string | null, depth: number, prefix = ""): void {
516
+ if (depth > maxDepth) return;
517
+
518
+ const entries = Object.entries(obj).slice(0, 8); // Limiter pour lisibilité
519
+
520
+ entries.forEach(([key, value]) => {
521
+ const currentId = `node${nodeId++}`;
522
+ const isFolder = value && typeof value === 'object' && Object.keys(value).length > 0;
523
+ const label = isFolder ? `${key}/` : key;
524
+
525
+ nodeMap.set(currentId, label);
526
+ graph += ` ${currentId}["${label}"]\n`;
527
+
528
+ if (parentId) {
529
+ graph += ` ${parentId} --> ${currentId}\n`;
530
+ }
531
+
532
+ if (isFolder && value) {
533
+ traverse(value, currentId, depth + 1, prefix + key + "/");
534
+ }
535
+ });
536
+ }
537
+
538
+ traverse(tree, null, 0);
539
+ return graph || getDefaultHierarchyGraph();
540
+ }
541
+
542
+ function getDefaultHierarchyGraph(): string {
543
+ return `graph TD
544
+ A[Root] --> B[src]
545
+ A --> C[config]
546
+ B --> D[components]
547
+ B --> E[utils]
548
+ B --> F[services]`;
549
+ }
550
+
551
+ function generateDataFlowGraph(): string {
552
+ return `graph LR
553
+ A[Input] --> B[Analyzer]
554
+ B --> C[Parser]
555
+ C --> D[Generator]
556
+ D --> E[Exporter]
557
+ E --> F[Output]`;
142
558
  }
package/dist/index.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js DELETED
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}