docstodev 1.0.2 → 1.1.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/dist/ai/analyzer.d.ts.map +1 -1
- package/dist/ai/analyzer.js +3 -1
- package/dist/ai/analyzer.js.map +1 -1
- package/dist/analyzers/languageAnalyzer.d.ts +3 -1
- package/dist/analyzers/languageAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/languageAnalyzer.js +266 -4
- package/dist/analyzers/languageAnalyzer.js.map +1 -1
- package/dist/commands/generateSummary.d.ts +14 -1
- package/dist/commands/generateSummary.d.ts.map +1 -1
- package/dist/commands/generateSummary.js +101 -39
- package/dist/commands/generateSummary.js.map +1 -1
- package/dist/exporters/html.d.ts.map +1 -1
- package/dist/exporters/html.js +130 -51
- package/dist/exporters/html.js.map +1 -1
- package/package.json +1 -1
- package/src/ai/analyzer.ts +3 -1
- package/src/analyzers/languageAnalyzer.ts +297 -5
- package/src/commands/generateSummary.ts +129 -39
- package/src/exporters/html.ts +134 -52
- package/.env +0 -1
- package/dist/commands/classify.d.ts +0 -2
- package/dist/commands/classify.d.ts.map +0 -1
- package/dist/commands/classify.js +0 -37
- package/dist/commands/classify.js.map +0 -1
- package/src/commands/classify.ts +0 -40
package/dist/exporters/html.js
CHANGED
|
@@ -33,9 +33,9 @@ export function exportToHTML(docsDir, markdownContent, mermaidGraph, lang = "fr"
|
|
|
33
33
|
/* ================= TREE VIEW ================= */
|
|
34
34
|
if (processed.match(/^[│├└─\s]+/) ||
|
|
35
35
|
processed.includes("/") ||
|
|
36
|
-
processed.match(/\.(ts|js|py|java|cs|go|rs|tsx|jsx)$/)) {
|
|
37
|
-
const hasFile = processed.match(/\.(ts|js|py|java|cs|go|rs|tsx|jsx)$/);
|
|
38
|
-
const fileMatch = hasFile ? processed.match(/([\w-]+\.(ts|js|py|java|cs|go|rs|tsx|jsx))/)?.[0] : null;
|
|
36
|
+
processed.match(/\.(ts|js|py|java|cs|go|rs|tsx|jsx|html|css|php|rb|sql)$/)) {
|
|
37
|
+
const hasFile = processed.match(/\.(ts|js|py|java|cs|go|rs|tsx|jsx|html|css|php|rb|sql)$/);
|
|
38
|
+
const fileMatch = hasFile ? processed.match(/([\w-]+\.(ts|js|py|java|cs|go|rs|tsx|jsx|html|css|php|rb|sql))/)?.[0] : null;
|
|
39
39
|
let treeLine = line
|
|
40
40
|
.replace(/├─/g, '<span class="branch">├─</span>')
|
|
41
41
|
.replace(/└─/g, '<span class="branch">└─</span>')
|
|
@@ -74,19 +74,47 @@ export function exportToHTML(docsDir, markdownContent, mermaidGraph, lang = "fr"
|
|
|
74
74
|
}
|
|
75
75
|
if (inSection)
|
|
76
76
|
htmlResult += "</section>";
|
|
77
|
-
//
|
|
77
|
+
// Nettoyer et valider les graphes Mermaid
|
|
78
|
+
const cleanMermaidGraph = sanitizeMermaidGraph(mermaidGraph || "graph TD\n Root[Projet]");
|
|
78
79
|
const hierarchyGraph = fileTree ? generateHierarchyGraph(fileTree) : getDefaultHierarchyGraph();
|
|
79
|
-
// Générer le flux de données (peut être personnalisé selon les imports/exports)
|
|
80
80
|
const dataFlowGraph = generateDataFlowGraph();
|
|
81
81
|
const html = `<!DOCTYPE html>
|
|
82
82
|
<html lang="${lang}" data-theme="dark">
|
|
83
83
|
<head>
|
|
84
84
|
<meta charset="UTF-8">
|
|
85
85
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
86
|
-
<title>DocsToDev – Rapport Technique</title>
|
|
86
|
+
<title>DocsToDev – ${lang === 'fr' ? 'Rapport Technique' : 'Technical Report'}</title>
|
|
87
87
|
|
|
88
88
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400&family=Fira+Code&display=swap" rel="stylesheet">
|
|
89
|
-
<script
|
|
89
|
+
<script type="module">
|
|
90
|
+
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
|
91
|
+
|
|
92
|
+
mermaid.initialize({
|
|
93
|
+
startOnLoad: true,
|
|
94
|
+
theme: document.documentElement.dataset.theme === "dark" ? "dark" : "default",
|
|
95
|
+
securityLevel: 'loose',
|
|
96
|
+
logLevel: 'error',
|
|
97
|
+
themeVariables: {
|
|
98
|
+
darkMode: document.documentElement.dataset.theme === "dark",
|
|
99
|
+
background: "transparent",
|
|
100
|
+
primaryColor: "#58a6ff",
|
|
101
|
+
primaryTextColor: "#c9d1d9",
|
|
102
|
+
primaryBorderColor: "#30363d",
|
|
103
|
+
lineColor: "#8b949e",
|
|
104
|
+
secondaryColor: "#161b22",
|
|
105
|
+
tertiaryColor: "#0d1117",
|
|
106
|
+
fontSize: "14px",
|
|
107
|
+
fontFamily: "Inter, sans-serif"
|
|
108
|
+
},
|
|
109
|
+
flowchart: {
|
|
110
|
+
useMaxWidth: true,
|
|
111
|
+
htmlLabels: true,
|
|
112
|
+
curve: 'basis'
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
window.mermaid = mermaid;
|
|
117
|
+
</script>
|
|
90
118
|
|
|
91
119
|
<style>
|
|
92
120
|
:root[data-theme="dark"] {
|
|
@@ -218,6 +246,8 @@ h3 {
|
|
|
218
246
|
border: 1px solid var(--border);
|
|
219
247
|
background: var(--card);
|
|
220
248
|
padding: 1.5rem;
|
|
249
|
+
min-height: 300px;
|
|
250
|
+
position: relative;
|
|
221
251
|
}
|
|
222
252
|
|
|
223
253
|
.graph-title {
|
|
@@ -229,6 +259,12 @@ h3 {
|
|
|
229
259
|
font-size: 0.85rem;
|
|
230
260
|
}
|
|
231
261
|
|
|
262
|
+
.mermaid-wrapper {
|
|
263
|
+
width: 100%;
|
|
264
|
+
overflow-x: auto;
|
|
265
|
+
overflow-y: hidden;
|
|
266
|
+
}
|
|
267
|
+
|
|
232
268
|
.component {
|
|
233
269
|
border: 1px solid var(--border);
|
|
234
270
|
background: var(--card);
|
|
@@ -340,7 +376,25 @@ mark {
|
|
|
340
376
|
|
|
341
377
|
.mermaid {
|
|
342
378
|
background: transparent;
|
|
343
|
-
|
|
379
|
+
display: flex;
|
|
380
|
+
justify-content: center;
|
|
381
|
+
align-items: center;
|
|
382
|
+
min-height: 200px;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.mermaid svg {
|
|
386
|
+
max-width: 100%;
|
|
387
|
+
height: auto;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
.error-message {
|
|
391
|
+
color: #f85149;
|
|
392
|
+
padding: 1rem;
|
|
393
|
+
background: rgba(248, 81, 73, 0.1);
|
|
394
|
+
border: 1px solid rgba(248, 81, 73, 0.3);
|
|
395
|
+
border-radius: 4px;
|
|
396
|
+
font-family: "Fira Code", monospace;
|
|
397
|
+
font-size: 0.9rem;
|
|
344
398
|
}
|
|
345
399
|
|
|
346
400
|
@media print {
|
|
@@ -393,23 +447,29 @@ mark {
|
|
|
393
447
|
<div class="graphs-grid">
|
|
394
448
|
<div class="graph-container">
|
|
395
449
|
<div class="graph-title">${lang === 'fr' ? 'Graphe des dépendances' : 'Dependency Graph'}</div>
|
|
396
|
-
<div class="mermaid">
|
|
397
|
-
|
|
450
|
+
<div class="mermaid-wrapper">
|
|
451
|
+
<pre class="mermaid">
|
|
452
|
+
${cleanMermaidGraph}
|
|
453
|
+
</pre>
|
|
398
454
|
</div>
|
|
399
455
|
</div>
|
|
400
456
|
|
|
401
457
|
<div class="graph-container">
|
|
402
458
|
<div class="graph-title">${lang === 'fr' ? 'Structure du projet' : 'Project Structure'}</div>
|
|
403
|
-
<div class="mermaid">
|
|
459
|
+
<div class="mermaid-wrapper">
|
|
460
|
+
<pre class="mermaid">
|
|
404
461
|
${hierarchyGraph}
|
|
462
|
+
</pre>
|
|
405
463
|
</div>
|
|
406
464
|
</div>
|
|
407
465
|
</div>
|
|
408
466
|
|
|
409
467
|
<div class="graph-container" style="margin-bottom: 3rem;">
|
|
410
468
|
<div class="graph-title">${lang === 'fr' ? 'Flux de données' : 'Data Flow'}</div>
|
|
411
|
-
<div class="mermaid">
|
|
469
|
+
<div class="mermaid-wrapper">
|
|
470
|
+
<pre class="mermaid">
|
|
412
471
|
${dataFlowGraph}
|
|
472
|
+
</pre>
|
|
413
473
|
</div>
|
|
414
474
|
</div>
|
|
415
475
|
|
|
@@ -418,34 +478,12 @@ ${dataFlowGraph}
|
|
|
418
478
|
</div>
|
|
419
479
|
|
|
420
480
|
<script>
|
|
421
|
-
document.addEventListener("DOMContentLoaded", () => {
|
|
422
|
-
if (window.mermaid) {
|
|
423
|
-
mermaid.initialize({
|
|
424
|
-
startOnLoad: true,
|
|
425
|
-
theme: document.documentElement.dataset.theme === "dark" ? "dark" : "default",
|
|
426
|
-
themeVariables: {
|
|
427
|
-
darkMode: document.documentElement.dataset.theme === "dark",
|
|
428
|
-
background: "transparent",
|
|
429
|
-
primaryColor: "#58a6ff",
|
|
430
|
-
primaryTextColor: "#c9d1d9",
|
|
431
|
-
primaryBorderColor: "#30363d",
|
|
432
|
-
lineColor: "#8b949e",
|
|
433
|
-
secondaryColor: "#161b22",
|
|
434
|
-
tertiaryColor: "#0d1117"
|
|
435
|
-
}
|
|
436
|
-
});
|
|
437
|
-
}
|
|
438
|
-
});
|
|
439
|
-
|
|
440
481
|
function toggleTheme() {
|
|
441
482
|
const root = document.documentElement;
|
|
442
483
|
const next = root.dataset.theme === "dark" ? "light" : "dark";
|
|
443
484
|
root.dataset.theme = next;
|
|
444
485
|
localStorage.setItem("theme", next);
|
|
445
|
-
|
|
446
|
-
if (window.mermaid) {
|
|
447
|
-
location.reload();
|
|
448
|
-
}
|
|
486
|
+
location.reload();
|
|
449
487
|
}
|
|
450
488
|
|
|
451
489
|
document.documentElement.dataset.theme = localStorage.getItem("theme") || "dark";
|
|
@@ -461,57 +499,98 @@ document.getElementById("search").addEventListener("input", e => {
|
|
|
461
499
|
return;
|
|
462
500
|
}
|
|
463
501
|
|
|
464
|
-
const regex = new RegExp("(" + term.replace(/[
|
|
502
|
+
const regex = new RegExp("(" + term.replace(/[.*+?^\${}()|[\\]\\\\]/g, "\\\\$&") + ")", "gi");
|
|
465
503
|
container.innerHTML = originalHTML.replace(regex, "<mark>$1</mark>");
|
|
466
504
|
|
|
467
505
|
const first = container.querySelector("mark");
|
|
468
506
|
if (first) first.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
469
507
|
});
|
|
508
|
+
|
|
509
|
+
// Gestion d'erreur Mermaid
|
|
510
|
+
window.addEventListener('load', () => {
|
|
511
|
+
setTimeout(() => {
|
|
512
|
+
document.querySelectorAll('.mermaid').forEach(el => {
|
|
513
|
+
if (!el.querySelector('svg') && !el.querySelector('.error-message')) {
|
|
514
|
+
const errorMsg = document.createElement('div');
|
|
515
|
+
errorMsg.className = 'error-message';
|
|
516
|
+
errorMsg.textContent = '${lang === 'fr' ? 'Erreur de rendu du graphe' : 'Graph rendering error'}';
|
|
517
|
+
el.appendChild(errorMsg);
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
}, 3000);
|
|
521
|
+
});
|
|
470
522
|
</script>
|
|
471
523
|
|
|
472
524
|
</body>
|
|
473
525
|
</html>`;
|
|
474
526
|
writeFileSync(path.join(docsDir, "report.html"), html);
|
|
475
527
|
}
|
|
528
|
+
function sanitizeMermaidGraph(graph) {
|
|
529
|
+
// Nettoyer les caractères problématiques
|
|
530
|
+
let cleaned = graph
|
|
531
|
+
.replace(/[""]/g, '"')
|
|
532
|
+
.replace(/['']/g, "'")
|
|
533
|
+
.replace(/\u00A0/g, ' ') // Espaces insécables
|
|
534
|
+
.trim();
|
|
535
|
+
// Vérifier que le graphe a une déclaration valide
|
|
536
|
+
if (!cleaned.match(/^(graph|flowchart|sequenceDiagram|classDiagram|stateDiagram|gantt|pie|erDiagram)/)) {
|
|
537
|
+
cleaned = "graph TD\n " + cleaned;
|
|
538
|
+
}
|
|
539
|
+
// Limiter la complexité si trop de nœuds
|
|
540
|
+
const lines = cleaned.split('\n');
|
|
541
|
+
if (lines.length > 50) {
|
|
542
|
+
cleaned = lines.slice(0, 50).join('\n') + '\n More["..."]';
|
|
543
|
+
}
|
|
544
|
+
return cleaned;
|
|
545
|
+
}
|
|
476
546
|
function generateHierarchyGraph(tree, maxDepth = 3) {
|
|
477
547
|
let graph = "graph TD\n";
|
|
478
548
|
let nodeId = 0;
|
|
479
549
|
const nodeMap = new Map();
|
|
550
|
+
function sanitizeLabel(label) {
|
|
551
|
+
return label.replace(/["\[\]]/g, '');
|
|
552
|
+
}
|
|
480
553
|
function traverse(obj, parentId, depth, prefix = "") {
|
|
481
554
|
if (depth > maxDepth)
|
|
482
555
|
return;
|
|
483
|
-
const entries = Object.entries(obj).slice(0,
|
|
556
|
+
const entries = Object.entries(obj).slice(0, 10); // Limiter pour lisibilité
|
|
484
557
|
entries.forEach(([key, value]) => {
|
|
485
558
|
const currentId = `node${nodeId++}`;
|
|
486
559
|
const isFolder = value && typeof value === 'object' && Object.keys(value).length > 0;
|
|
487
|
-
const label = isFolder ? `${key}/` : key;
|
|
560
|
+
const label = sanitizeLabel(isFolder ? `${key}/` : key);
|
|
488
561
|
nodeMap.set(currentId, label);
|
|
489
562
|
graph += ` ${currentId}["${label}"]\n`;
|
|
490
563
|
if (parentId) {
|
|
491
564
|
graph += ` ${parentId} --> ${currentId}\n`;
|
|
492
565
|
}
|
|
493
|
-
if (isFolder && value) {
|
|
566
|
+
if (isFolder && value && depth < maxDepth) {
|
|
494
567
|
traverse(value, currentId, depth + 1, prefix + key + "/");
|
|
495
568
|
}
|
|
496
569
|
});
|
|
497
570
|
}
|
|
498
|
-
|
|
499
|
-
|
|
571
|
+
try {
|
|
572
|
+
traverse(tree, null, 0);
|
|
573
|
+
return graph || getDefaultHierarchyGraph();
|
|
574
|
+
}
|
|
575
|
+
catch (e) {
|
|
576
|
+
console.error("Error generating hierarchy graph:", e);
|
|
577
|
+
return getDefaultHierarchyGraph();
|
|
578
|
+
}
|
|
500
579
|
}
|
|
501
580
|
function getDefaultHierarchyGraph() {
|
|
502
581
|
return `graph TD
|
|
503
|
-
A[Root] --> B[src]
|
|
504
|
-
A --> C[config]
|
|
505
|
-
B --> D[components]
|
|
506
|
-
B --> E[utils]
|
|
507
|
-
B --> F[services]`;
|
|
582
|
+
A["Root"] --> B["src"]
|
|
583
|
+
A --> C["config"]
|
|
584
|
+
B --> D["components"]
|
|
585
|
+
B --> E["utils"]
|
|
586
|
+
B --> F["services"]`;
|
|
508
587
|
}
|
|
509
588
|
function generateDataFlowGraph() {
|
|
510
589
|
return `graph LR
|
|
511
|
-
A[Input] --> B[Analyzer]
|
|
512
|
-
B --> C[Parser]
|
|
513
|
-
C --> D[Generator]
|
|
514
|
-
D --> E[Exporter]
|
|
515
|
-
E --> F[Output]`;
|
|
590
|
+
A["Input"] --> B["Analyzer"]
|
|
591
|
+
B --> C["Parser"]
|
|
592
|
+
C --> D["Generator"]
|
|
593
|
+
D --> E["Exporter"]
|
|
594
|
+
E --> F["Output"]`;
|
|
516
595
|
}
|
|
517
596
|
//# sourceMappingURL=html.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/exporters/html.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAM7B,MAAM,UAAU,YAAY,CACxB,OAAe,EACf,eAAuB,EACvB,YAAoB,EACpB,OAAoB,IAAI,EACxB,QAAwB;IAExB,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE1C,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE,CAChC,IAAI;SACC,OAAO,CAAC,UAAU,EAAE,iBAAiB,CAAC;SACtC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC;SAC/B,OAAO,CAAC,qBAAqB,EAAE,qBAAqB,CAAC,CAAC;IAE/D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAE9B,gDAAgD;QAChD,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO,EAAE,CAAC;gBACX,UAAU,IAAI,sCAAsC,CAAC;gBACrD,OAAO,GAAG,IAAI,CAAC;YACnB,CAAC;YACD,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,SAAS;YAExC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACzD,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAE5E,UAAU,IAAI,OACV,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CACV,QAAQ;gBACJ,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO;gBACpC,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAC3C,CAAC,IAAI,CAAC,EAAE,CACb,OAAO,CAAC;YACR,SAAS;QACb,CAAC;aAAM,IAAI,OAAO,EAAE,CAAC;YACjB,UAAU,IAAI,gBAAgB,CAAC;YAC/B,OAAO,GAAG,KAAK,CAAC;QACpB,CAAC;QAED,mDAAmD;QACnD,IACI,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC;YAC7B,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC;YACvB,SAAS,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/exporters/html.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/ai/analyzer.ts
CHANGED
|
@@ -19,7 +19,9 @@ Instructions :
|
|
|
19
19
|
- Vous allez recevoir une liste de fichiers, leurs rôles et leurs exports.
|
|
20
20
|
- Pour chaque fichier, rédigez UNE SEULE phrase concise expliquant sa responsabilité métier.
|
|
21
21
|
- Soyez pro, mais gardez votre touche amicale et votre pointe d'humour du Congo-Brazzaville.
|
|
22
|
-
-
|
|
22
|
+
- mentionnez les imports, technique ( "il y a une fonction X"), expliquez le BUT du fichier.
|
|
23
|
+
- selon le nombre d'occurance précisez les couleurs qui reviennen souvent eu suggérez un design systèm , pallette de couleur.
|
|
24
|
+
- donnez une très bref description du but de l'ensemble du projet.
|
|
23
25
|
`;
|
|
24
26
|
|
|
25
27
|
try {
|
|
@@ -9,6 +9,7 @@ export interface FileAnalysisResult {
|
|
|
9
9
|
types: string[];
|
|
10
10
|
imports: Array<{ name: string; type: string; usage?: string | undefined }>;
|
|
11
11
|
exports: string[];
|
|
12
|
+
structure?: Record<string, any>; // Pour les fichiers non-standards
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
// Analyseur TypeScript/JavaScript
|
|
@@ -25,7 +26,6 @@ class TSJSAnalyzer implements LanguageAnalyzer {
|
|
|
25
26
|
|
|
26
27
|
const functions: string[] = [];
|
|
27
28
|
const funcRegex = /(?:export\s+)?(?:async\s+)?function\s+([a-zA-Z0-9_]+)/g;
|
|
28
|
-
// Resetting regex because of global flag
|
|
29
29
|
funcRegex.lastIndex = 0;
|
|
30
30
|
while ((match = funcRegex.exec(content)) !== null) {
|
|
31
31
|
if (match[1]) functions.push(match[1]);
|
|
@@ -266,6 +266,282 @@ class RustAnalyzer implements LanguageAnalyzer {
|
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
+
// Analyseur HTML
|
|
270
|
+
class HTMLAnalyzer implements LanguageAnalyzer {
|
|
271
|
+
extensions = [".html", ".htm"];
|
|
272
|
+
|
|
273
|
+
analyzeFile(content: string): FileAnalysisResult {
|
|
274
|
+
const structure: Record<string, any> = {
|
|
275
|
+
tags: new Set<string>(),
|
|
276
|
+
ids: [] as string[],
|
|
277
|
+
classes: [] as string[],
|
|
278
|
+
scripts: [] as string[],
|
|
279
|
+
styles: [] as string[]
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
// Extraire les balises
|
|
283
|
+
const tagRegex = /<(\w+)/g;
|
|
284
|
+
let match: RegExpExecArray | null;
|
|
285
|
+
while ((match = tagRegex.exec(content)) !== null) {
|
|
286
|
+
if (match[1]) structure.tags.add(match[1].toLowerCase());
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Extraire les IDs
|
|
290
|
+
const idRegex = /id=["']([^"']+)["']/g;
|
|
291
|
+
while ((match = idRegex.exec(content)) !== null) {
|
|
292
|
+
if (match[1]) structure.ids.push(match[1]);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Extraire les classes
|
|
296
|
+
const classRegex = /class=["']([^"']+)["']/g;
|
|
297
|
+
while ((match = classRegex.exec(content)) !== null) {
|
|
298
|
+
if (match[1]) {
|
|
299
|
+
structure.classes.push(...match[1].split(/\s+/).filter(Boolean));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Extraire les scripts externes
|
|
304
|
+
const scriptRegex = /<script[^>]+src=["']([^"']+)["']/g;
|
|
305
|
+
while ((match = scriptRegex.exec(content)) !== null) {
|
|
306
|
+
if (match[1]) structure.scripts.push(match[1]);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Extraire les stylesheets externes
|
|
310
|
+
const linkRegex = /<link[^>]+href=["']([^"']+\.css)["']/g;
|
|
311
|
+
while ((match = linkRegex.exec(content)) !== null) {
|
|
312
|
+
if (match[1]) structure.styles.push(match[1]);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
structure.tags = Array.from(structure.tags);
|
|
316
|
+
|
|
317
|
+
return {
|
|
318
|
+
functions: [],
|
|
319
|
+
classes: structure.classes,
|
|
320
|
+
types: [],
|
|
321
|
+
imports: [
|
|
322
|
+
...structure.scripts.map((s : string) => ({ name: s, type: 'Script' })),
|
|
323
|
+
...structure.styles.map((s:string) => ({ name: s, type: 'Stylesheet' }))
|
|
324
|
+
],
|
|
325
|
+
exports: [],
|
|
326
|
+
structure
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Analyseur CSS/SCSS/SASS
|
|
332
|
+
class CSSAnalyzer implements LanguageAnalyzer {
|
|
333
|
+
extensions = [".css", ".scss", ".sass", ".less"];
|
|
334
|
+
|
|
335
|
+
analyzeFile(content: string): FileAnalysisResult {
|
|
336
|
+
const structure: Record<string, any> = {
|
|
337
|
+
selectors: [] as string[],
|
|
338
|
+
ids: [] as string[],
|
|
339
|
+
classes: [] as string[],
|
|
340
|
+
variables: [] as string[],
|
|
341
|
+
mixins: [] as string[],
|
|
342
|
+
imports: [] as string[]
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
// Classes CSS
|
|
346
|
+
const classRegex = /\.([a-zA-Z0-9_-]+)/g;
|
|
347
|
+
let match: RegExpExecArray | null;
|
|
348
|
+
while ((match = classRegex.exec(content)) !== null) {
|
|
349
|
+
if (match[1] && !structure.classes.includes(match[1])) {
|
|
350
|
+
structure.classes.push(match[1]);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// IDs CSS
|
|
355
|
+
const idRegex = /#([a-zA-Z0-9_-]+)/g;
|
|
356
|
+
while ((match = idRegex.exec(content)) !== null) {
|
|
357
|
+
if (match[1] && !structure.ids.includes(match[1])) {
|
|
358
|
+
structure.ids.push(match[1]);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Variables CSS/SCSS
|
|
363
|
+
const varRegex = /(?:--|\$)([a-zA-Z0-9_-]+)/g;
|
|
364
|
+
while ((match = varRegex.exec(content)) !== null) {
|
|
365
|
+
if (match[1] && !structure.variables.includes(match[1])) {
|
|
366
|
+
structure.variables.push(match[1]);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Mixins SCSS
|
|
371
|
+
const mixinRegex = /@mixin\s+([a-zA-Z0-9_-]+)/g;
|
|
372
|
+
while ((match = mixinRegex.exec(content)) !== null) {
|
|
373
|
+
if (match[1]) structure.mixins.push(match[1]);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Imports
|
|
377
|
+
const importRegex = /@import\s+['"]([^'"]+)['"]/g;
|
|
378
|
+
while ((match = importRegex.exec(content)) !== null) {
|
|
379
|
+
if (match[1]) structure.imports.push(match[1]);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return {
|
|
383
|
+
functions: structure.mixins,
|
|
384
|
+
classes: structure.classes,
|
|
385
|
+
types: [],
|
|
386
|
+
imports: structure.imports.map((i:string) => ({ name: i, type: 'CSS' })),
|
|
387
|
+
exports: [],
|
|
388
|
+
structure
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Analyseur PHP
|
|
394
|
+
class PHPAnalyzer implements LanguageAnalyzer {
|
|
395
|
+
extensions = [".php"];
|
|
396
|
+
|
|
397
|
+
analyzeFile(content: string): FileAnalysisResult {
|
|
398
|
+
const functions: string[] = [];
|
|
399
|
+
const funcRegex = /function\s+([a-zA-Z0-9_]+)\s*\(/g;
|
|
400
|
+
let match: RegExpExecArray | null;
|
|
401
|
+
while ((match = funcRegex.exec(content)) !== null) {
|
|
402
|
+
if (match[1]) functions.push(match[1]);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const classes: string[] = [];
|
|
406
|
+
const classRegex = /class\s+([a-zA-Z0-9_]+)/g;
|
|
407
|
+
while ((match = classRegex.exec(content)) !== null) {
|
|
408
|
+
if (match[1]) classes.push(match[1]);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const imports: Array<{ name: string; type: string; usage?: string | undefined }> = [];
|
|
412
|
+
const useRegex = /use\s+([a-zA-Z0-9_\\]+)/g;
|
|
413
|
+
while ((match = useRegex.exec(content)) !== null) {
|
|
414
|
+
if (match[1]) {
|
|
415
|
+
imports.push({ name: match[1], type: 'Composer' });
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const requireRegex = /(?:require|include)(?:_once)?\s*['"]([^'"]+)['"]/g;
|
|
420
|
+
while ((match = requireRegex.exec(content)) !== null) {
|
|
421
|
+
if (match[1]) {
|
|
422
|
+
imports.push({ name: match[1], type: 'Local' });
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
return { functions, classes, types: [], imports, exports: [] };
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Analyseur Ruby
|
|
431
|
+
class RubyAnalyzer implements LanguageAnalyzer {
|
|
432
|
+
extensions = [".rb"];
|
|
433
|
+
|
|
434
|
+
analyzeFile(content: string): FileAnalysisResult {
|
|
435
|
+
const functions: string[] = [];
|
|
436
|
+
const funcRegex = /def\s+([a-zA-Z0-9_?!]+)/g;
|
|
437
|
+
let match: RegExpExecArray | null;
|
|
438
|
+
while ((match = funcRegex.exec(content)) !== null) {
|
|
439
|
+
if (match[1]) functions.push(match[1]);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
const classes: string[] = [];
|
|
443
|
+
const classRegex = /class\s+([a-zA-Z0-9_]+)/g;
|
|
444
|
+
while ((match = classRegex.exec(content)) !== null) {
|
|
445
|
+
if (match[1]) classes.push(match[1]);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
const imports: Array<{ name: string; type: string; usage?: string | undefined }> = [];
|
|
449
|
+
const requireRegex = /require\s+['"]([^'"]+)['"]/g;
|
|
450
|
+
while ((match = requireRegex.exec(content)) !== null) {
|
|
451
|
+
if (match[1]) {
|
|
452
|
+
imports.push({ name: match[1], type: 'Gem' });
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
return { functions, classes, types: [], imports, exports: [] };
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Analyseur SQL
|
|
461
|
+
class SQLAnalyzer implements LanguageAnalyzer {
|
|
462
|
+
extensions = [".sql"];
|
|
463
|
+
|
|
464
|
+
analyzeFile(content: string): FileAnalysisResult {
|
|
465
|
+
const structure: Record<string, any> = {
|
|
466
|
+
tables: [] as string[],
|
|
467
|
+
procedures: [] as string[],
|
|
468
|
+
functions: [] as string[],
|
|
469
|
+
views: [] as string[]
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
const tableRegex = /CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?([a-zA-Z0-9_]+)/gi;
|
|
473
|
+
let match: RegExpExecArray | null;
|
|
474
|
+
while ((match = tableRegex.exec(content)) !== null) {
|
|
475
|
+
if (match[1]) structure.tables.push(match[1]);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const procRegex = /CREATE\s+(?:OR\s+REPLACE\s+)?PROCEDURE\s+([a-zA-Z0-9_]+)/gi;
|
|
479
|
+
while ((match = procRegex.exec(content)) !== null) {
|
|
480
|
+
if (match[1]) structure.procedures.push(match[1]);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
const funcRegex = /CREATE\s+(?:OR\s+REPLACE\s+)?FUNCTION\s+([a-zA-Z0-9_]+)/gi;
|
|
484
|
+
while ((match = funcRegex.exec(content)) !== null) {
|
|
485
|
+
if (match[1]) structure.functions.push(match[1]);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
const viewRegex = /CREATE\s+(?:OR\s+REPLACE\s+)?VIEW\s+([a-zA-Z0-9_]+)/gi;
|
|
489
|
+
while ((match = viewRegex.exec(content)) !== null) {
|
|
490
|
+
if (match[1]) structure.views.push(match[1]);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
return {
|
|
494
|
+
functions: structure.functions,
|
|
495
|
+
classes: structure.tables,
|
|
496
|
+
types: structure.views,
|
|
497
|
+
imports: [],
|
|
498
|
+
exports: [],
|
|
499
|
+
structure
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// Analyseur par défaut pour tous les autres fichiers
|
|
505
|
+
class DefaultAnalyzer implements LanguageAnalyzer {
|
|
506
|
+
extensions = ["*"]; // Wildcard pour tous les fichiers
|
|
507
|
+
|
|
508
|
+
analyzeFile(content: string): FileAnalysisResult {
|
|
509
|
+
const lines = content.split(/\r?\n/);
|
|
510
|
+
const structure: Record<string, any> = {
|
|
511
|
+
lineCount: lines.length,
|
|
512
|
+
nonEmptyLines: lines.filter(l => l.trim().length > 0).length,
|
|
513
|
+
size: content.length,
|
|
514
|
+
hasCode: /[a-zA-Z0-9_]+\s*[=:({]/.test(content),
|
|
515
|
+
encoding: 'UTF-8'
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
// Détection basique de patterns communs
|
|
519
|
+
const patterns = {
|
|
520
|
+
functions: [] as string[],
|
|
521
|
+
variables: [] as string[],
|
|
522
|
+
comments: [] as string[]
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
// Détection générique de fonctions (pattern commun à beaucoup de langages)
|
|
526
|
+
const genericFuncRegex = /(?:function|func|def|fn|sub|procedure)\s+([a-zA-Z0-9_]+)/gi;
|
|
527
|
+
let match: RegExpExecArray | null;
|
|
528
|
+
while ((match = genericFuncRegex.exec(content)) !== null) {
|
|
529
|
+
if (match[1]) patterns.functions.push(match[1]);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
structure.patterns = patterns;
|
|
533
|
+
|
|
534
|
+
return {
|
|
535
|
+
functions: patterns.functions,
|
|
536
|
+
classes: [],
|
|
537
|
+
types: [],
|
|
538
|
+
imports: [],
|
|
539
|
+
exports: [],
|
|
540
|
+
structure
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
269
545
|
// Registry des analyseurs
|
|
270
546
|
const analyzers: LanguageAnalyzer[] = [
|
|
271
547
|
new TSJSAnalyzer(),
|
|
@@ -273,16 +549,32 @@ const analyzers: LanguageAnalyzer[] = [
|
|
|
273
549
|
new JavaAnalyzer(),
|
|
274
550
|
new CSharpAnalyzer(),
|
|
275
551
|
new GoAnalyzer(),
|
|
276
|
-
new RustAnalyzer()
|
|
552
|
+
new RustAnalyzer(),
|
|
553
|
+
new HTMLAnalyzer(),
|
|
554
|
+
new CSSAnalyzer(),
|
|
555
|
+
new PHPAnalyzer(),
|
|
556
|
+
new RubyAnalyzer(),
|
|
557
|
+
new SQLAnalyzer()
|
|
277
558
|
];
|
|
278
559
|
|
|
279
|
-
|
|
560
|
+
const defaultAnalyzer = new DefaultAnalyzer();
|
|
561
|
+
|
|
562
|
+
export function getAnalyzer(filePath: string): LanguageAnalyzer {
|
|
280
563
|
const lastDotIndex = filePath.lastIndexOf('.');
|
|
281
|
-
if (lastDotIndex === -1) return
|
|
564
|
+
if (lastDotIndex === -1) return defaultAnalyzer;
|
|
565
|
+
|
|
282
566
|
const ext = filePath.substring(lastDotIndex).toLowerCase();
|
|
283
|
-
return analyzers.find(a => a.extensions.includes(ext)) ||
|
|
567
|
+
return analyzers.find(a => a.extensions.includes(ext)) || defaultAnalyzer;
|
|
284
568
|
}
|
|
285
569
|
|
|
286
570
|
export function getSupportedExtensions(): string[] {
|
|
287
571
|
return analyzers.flatMap(a => a.extensions);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
export function isExplicitlySupported(filePath: string): boolean {
|
|
575
|
+
const lastDotIndex = filePath.lastIndexOf('.');
|
|
576
|
+
if (lastDotIndex === -1) return false;
|
|
577
|
+
|
|
578
|
+
const ext = filePath.substring(lastDotIndex).toLowerCase();
|
|
579
|
+
return analyzers.some(a => a.extensions.includes(ext));
|
|
288
580
|
}
|