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.
@@ -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
- // Générer la vue hiérarchique dynamiquement
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 defer src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></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
- overflow: auto;
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
- ${mermaidGraph || "graph TD\n Root[Projet]"}
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(/[.*+?^\\\${}()|[\\]\\\\]/g, "\\\\$&") + ")", "gi");
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, 8); // Limiter pour lisibilité
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
- traverse(tree, null, 0);
499
- return graph || getDefaultHierarchyGraph();
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":"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"}
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/exporters/html.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docstodev",
3
- "version": "1.0.2",
3
+ "version": "1.1.1",
4
4
  "description": "Solution d’automatisation de documentation technique intelligente avec IA",
5
5
  "type": "module",
6
6
  "main": "dist/cli/index.js",
@@ -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
- - Ne mentionnez pas de code technique (pas de "il y a une fonction X"), expliquez le BUT du fichier.
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
- export function getAnalyzer(filePath: string): LanguageAnalyzer | null {
560
+ const defaultAnalyzer = new DefaultAnalyzer();
561
+
562
+ export function getAnalyzer(filePath: string): LanguageAnalyzer {
280
563
  const lastDotIndex = filePath.lastIndexOf('.');
281
- if (lastDotIndex === -1) return null;
564
+ if (lastDotIndex === -1) return defaultAnalyzer;
565
+
282
566
  const ext = filePath.substring(lastDotIndex).toLowerCase();
283
- return analyzers.find(a => a.extensions.includes(ext)) || null;
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
  }