docstodev 1.0.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/.env +1 -0
- package/dist/ai/analyzer.d.ts +3 -0
- package/dist/ai/analyzer.d.ts.map +1 -0
- package/dist/ai/analyzer.js +42 -0
- package/dist/ai/analyzer.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +59 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/classify.d.ts +2 -0
- package/dist/commands/classify.d.ts.map +1 -0
- package/dist/commands/classify.js +37 -0
- package/dist/commands/classify.js.map +1 -0
- package/dist/commands/generateSummary.d.ts +5 -0
- package/dist/commands/generateSummary.d.ts.map +1 -0
- package/dist/commands/generateSummary.js +54 -0
- package/dist/commands/generateSummary.js.map +1 -0
- package/dist/commands/run.d.ts +2 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +142 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/exporters/html.d.ts +2 -0
- package/dist/exporters/html.d.ts.map +1 -0
- package/dist/exporters/html.js +148 -0
- package/dist/exporters/html.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/docs/docs-to-dev.md +111 -0
- package/docs/report.html +90 -0
- package/docs/report.pdf +0 -0
- package/docs/summary.md +16 -0
- package/package.json +39 -0
- package/src/ai/analyzer.ts +46 -0
- package/src/cli/index.ts +70 -0
- package/src/commands/classify.ts +40 -0
- package/src/commands/generateSummary.ts +60 -0
- package/src/commands/run.ts +156 -0
- package/src/exporters/html.ts +142 -0
- package/src/index.ts +0 -0
- package/tsconfig.json +33 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Rapport d'Analyse Technique DocsToDev
|
|
2
|
+
|
|
3
|
+
> 📅 Généré le : 08/01/2026 19:36:56
|
|
4
|
+
|
|
5
|
+
## 💡 Synthèse Métier (par MakazouIA)
|
|
6
|
+
Voici les explications métier pour chaque fichier :
|
|
7
|
+
|
|
8
|
+
* Le fichier `src/index.ts` utilise les dépendances pour initialiser l'application et charger les configurations nécessaires.
|
|
9
|
+
* Le fichier `src/ai/analyzer.ts` utilise l'API Groq pour demander à l'IA de générer des descriptions métier claires à partir de données techniques brutes.
|
|
10
|
+
* Le fichier `src/cli/index.ts` utilise la bibliothèque Commander pour créer une interface de ligne de commande permettant aux utilisateurs d'interagir avec l'application.
|
|
11
|
+
* Le fichier `src/commands/classify.ts` utilise les informations de fichier pour déterminer le rôle métier de chaque fichier dans le projet.
|
|
12
|
+
* Le fichier `src/commands/generateSummary.ts` utilise les données de projet pour générer un résumé global du projet avec un ton humain et bilingue.
|
|
13
|
+
* Le fichier `src/commands/run.ts` utilise les dépendances pour analyser le code source, générer des rapports techniques et créer une représentation visuelle de la structure du projet.
|
|
14
|
+
* Le fichier `src/exporters/html.ts` utilise les données de rapport pour générer une version HTML du rapport technique, avec mise en forme et liens vers les parties pertinentes du projet.
|
|
15
|
+
|
|
16
|
+
En résumé, chaque fichier utilise ses dépendances pour accomplir une tâche spécifique dans le processus d'analyse et de documentation du projet.
|
|
17
|
+
|
|
18
|
+
## đź“‚ Architecture des dossiers
|
|
19
|
+
|
|
20
|
+
├─ [package-lock.json](../package-lock.json)
|
|
21
|
+
├─ [package.json](../package.json)
|
|
22
|
+
├─ [src/ai/analyzer.ts](../src/ai/analyzer.ts)
|
|
23
|
+
├─ [src/cli/index.ts](../src/cli/index.ts)
|
|
24
|
+
├─ [src/commands/classify.ts](../src/commands/classify.ts)
|
|
25
|
+
├─ [src/commands/generateSummary.ts](../src/commands/generateSummary.ts)
|
|
26
|
+
├─ [src/commands/run.ts](../src/commands/run.ts)
|
|
27
|
+
├─ [src/exporters/html.ts](../src/exporters/html.ts)
|
|
28
|
+
├─ [src/index.ts](../src/index.ts)
|
|
29
|
+
└─ [tsconfig.json](../tsconfig.json)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## 🔬 Analyse détaillée des composants
|
|
33
|
+
|
|
34
|
+
### đź“„ [`src/index.ts`](../src/index.ts)
|
|
35
|
+
• **Densité et maintenance :** 1 lignes
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
### đź“„ [`src/ai/analyzer.ts`](../src/ai/analyzer.ts)
|
|
40
|
+
• **Densité et maintenance :** 46 lignes
|
|
41
|
+
• **Capacités offertes :** `askAI`
|
|
42
|
+
• **Collaborations sollicitées :**
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
### đź“„ [`src/cli/index.ts`](../src/cli/index.ts)
|
|
47
|
+
• **Densité et maintenance :** 70 lignes
|
|
48
|
+
• **Collaborations sollicitées :**
|
|
49
|
+
- Utilise `commander` (External)
|
|
50
|
+
- Utilise `../commands/run.js` (Internal)
|
|
51
|
+
- Utilise `../commands/generateSummary.js` (Internal)
|
|
52
|
+
- Utilise `node:readline/promises` (Node.js)
|
|
53
|
+
- Utilise `node:process` (Node.js)
|
|
54
|
+
- Utilise `node:path` (Node.js)
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
### đź“„ [`src/commands/classify.ts`](../src/commands/classify.ts)
|
|
59
|
+
• **Densité et maintenance :** 40 lignes
|
|
60
|
+
• **Capacités offertes :** `determineRole`
|
|
61
|
+
• **Collaborations sollicitées :**
|
|
62
|
+
- Utilise `node:path` (Node.js)
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
### đź“„ [`src/commands/generateSummary.ts`](../src/commands/generateSummary.ts)
|
|
67
|
+
• **Densité et maintenance :** 60 lignes
|
|
68
|
+
• **Capacités offertes :** `generateSummary`
|
|
69
|
+
• **Collaborations sollicitées :**
|
|
70
|
+
- Utilise `node:fs` (Node.js)
|
|
71
|
+
- Utilise `node:path` (Node.js)
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
### đź“„ [`src/commands/run.ts`](../src/commands/run.ts)
|
|
76
|
+
• **Densité et maintenance :** 156 lignes
|
|
77
|
+
• **Capacités offertes :** `runCommand`
|
|
78
|
+
• **Collaborations sollicitées :**
|
|
79
|
+
- Utilise `globby` (External)
|
|
80
|
+
- Utilise `node:fs` (Node.js)
|
|
81
|
+
- Utilise `node:path` (Node.js)
|
|
82
|
+
- Utilise `puppeteer` (External)
|
|
83
|
+
- Utilise `../exporters/html.js` (Internal)
|
|
84
|
+
- Utilise `../ai/analyzer.js` (Internal)
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
### đź“„ [`src/exporters/html.ts`](../src/exporters/html.ts)
|
|
89
|
+
• **Densité et maintenance :** 142 lignes
|
|
90
|
+
• **Capacités offertes :** `exportToHTML`
|
|
91
|
+
• **Collaborations sollicitées :**
|
|
92
|
+
- Utilise `node:fs` (Node.js)
|
|
93
|
+
- Utilise `node:path` (Node.js)
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 📦 Inventaire des modules externes
|
|
98
|
+
|
|
99
|
+
| Module | Type |
|
|
100
|
+
| :--- | :--- |
|
|
101
|
+
| `../ai/analyzer.js` | Internal |
|
|
102
|
+
| `../commands/generateSummary.js` | Internal |
|
|
103
|
+
| `../commands/run.js` | Internal |
|
|
104
|
+
| `../exporters/html.js` | Internal |
|
|
105
|
+
| `commander` | External |
|
|
106
|
+
| `globby` | External |
|
|
107
|
+
| `node:fs` | Node.js |
|
|
108
|
+
| `node:path` | Node.js |
|
|
109
|
+
| `node:process` | Node.js |
|
|
110
|
+
| `node:readline/promises` | Node.js |
|
|
111
|
+
| `puppeteer` | External |
|
package/docs/report.html
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="fr" data-theme="dark">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>DocsToDev | Rapport Technique</title>
|
|
6
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500&family=Fira+Code:wght@400&display=swap" rel="stylesheet">
|
|
7
|
+
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
|
8
|
+
<style>
|
|
9
|
+
:root[data-theme="dark"] {
|
|
10
|
+
--bg: #0d1117; --card: #161b22; --text: #c9d1d9; --text-dim: #8b949e;
|
|
11
|
+
--accent: #58a6ff; --border: #30363d; --code-bg: rgba(110, 118, 129, 0.2);
|
|
12
|
+
--code-text: #ff7b72; --h-color: #f0f6fc;
|
|
13
|
+
}
|
|
14
|
+
:root[data-theme="light"] {
|
|
15
|
+
--bg: #ffffff; --card: #f8f9fa; --text: #24292f; --text-dim: #57606a;
|
|
16
|
+
--accent: #0969da; --border: #d0d7de; --code-bg: #afb8c133;
|
|
17
|
+
--code-text: #cf222e; --h-color: #1b1f24;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
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; }
|
|
21
|
+
.container { max-width: 1100px; margin: auto; }
|
|
22
|
+
|
|
23
|
+
.controls { position: sticky; top: 10px; display: flex; gap: 1rem; margin-bottom: 2rem; z-index: 100; }
|
|
24
|
+
#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); }
|
|
25
|
+
.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; }
|
|
26
|
+
.pdf-btn { background: #238636; color: white; border: none; }
|
|
27
|
+
|
|
28
|
+
h1 { font-weight: 500; font-size: 2.2rem; color: var(--accent); letter-spacing: -1px; }
|
|
29
|
+
h2 { font-weight: 400; color: var(--h-color); border-bottom: 1px solid var(--border); padding-bottom: 10px; margin-top: 3.5rem; }
|
|
30
|
+
|
|
31
|
+
.mermaid { background: var(--card); padding: 1.5rem; border-radius: 12px; border: 1px solid var(--border); margin: 1.5rem 0; overflow: auto; }
|
|
32
|
+
.component-card { background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 1.5rem; margin-bottom: 1.5rem; }
|
|
33
|
+
.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; }
|
|
34
|
+
|
|
35
|
+
.tree-line { font-family: 'Fira Code', monospace; font-size: 0.85rem; color: var(--text-dim); white-space: pre; line-height: 1.4; }
|
|
36
|
+
.branch { color: var(--accent); opacity: 0.7; }
|
|
37
|
+
|
|
38
|
+
.table-container { margin: 1.5rem 0; border-radius: 8px; border: 1px solid var(--border); overflow: hidden; }
|
|
39
|
+
table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
|
|
40
|
+
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); }
|
|
41
|
+
td { padding: 10px 12px; border-bottom: 1px solid var(--border); }
|
|
42
|
+
|
|
43
|
+
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; }
|
|
44
|
+
a { color: var(--accent); text-decoration: none; }
|
|
45
|
+
.list-item { margin-bottom: 8px; }
|
|
46
|
+
.list-item::before { content: "•"; color: var(--accent); margin-right: 12px; font-weight: bold; }
|
|
47
|
+
|
|
48
|
+
@media print { .controls { display: none; } body { padding: 0; } .container { max-width: 100%; border: none; } }
|
|
49
|
+
</style>
|
|
50
|
+
</head>
|
|
51
|
+
<body>
|
|
52
|
+
<div class="container">
|
|
53
|
+
<div class="controls">
|
|
54
|
+
<input type="text" id="search" placeholder="Rechercher par nom, rĂ´le, technologie...">
|
|
55
|
+
<button class="btn pdf-btn" onclick="window.print()">📥 Imprimer / PDF</button>
|
|
56
|
+
<button class="btn" onclick="toggleTheme()">🌓 Theme</button>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<h2>📊 Graphe des Dépendances</h2>
|
|
60
|
+
<div class="mermaid">
|
|
61
|
+
graph TD
|
|
62
|
+
index_ts --> run_js
|
|
63
|
+
index_ts --> generateSummary_js
|
|
64
|
+
run_ts --> html_js
|
|
65
|
+
run_ts --> analyzer_js
|
|
66
|
+
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
<div id="content-area"><h1>Rapport d'Analyse Technique DocsToDev</h1><p>> 📅 Généré le : 08/01/2026 19:36:56</p><h2>💡 Synthèse Métier (par MakazouIA)</h2><p>Voici les explications métier pour chaque fichier :</p><div class="list-item">Le fichier <code>src/index.ts</code> utilise les dépendances pour initialiser l'application et charger les configurations nécessaires.</div><div class="list-item">Le fichier <code>src/ai/analyzer.ts</code> utilise l'API Groq pour demander à l'IA de générer des descriptions métier claires à partir de données techniques brutes.</div><div class="list-item">Le fichier <code>src/cli/index.ts</code> utilise la bibliothèque Commander pour créer une interface de ligne de commande permettant aux utilisateurs d'interagir avec l'application.</div><div class="list-item">Le fichier <code>src/commands/classify.ts</code> utilise les informations de fichier pour déterminer le rôle métier de chaque fichier dans le projet.</div><div class="list-item">Le fichier <code>src/commands/generateSummary.ts</code> utilise les données de projet pour générer un résumé global du projet avec un ton humain et bilingue.</div><div class="list-item">Le fichier <code>src/commands/run.ts</code> utilise les dépendances pour analyser le code source, générer des rapports techniques et créer une représentation visuelle de la structure du projet.</div><div class="list-item">Le fichier <code>src/exporters/html.ts</code> utilise les données de rapport pour générer une version HTML du rapport technique, avec mise en forme et liens vers les parties pertinentes du projet.</div><p>En résumé, chaque fichier utilise ses dépendances pour accomplir une tâche spécifique dans le processus d'analyse et de documentation du projet.</p><h2>📂 Architecture des dossiers</h2><div class="tree-line"><span class="branch">├─</span> <a href="../package-lock.json">package-lock.json</a></div><div class="tree-line"><span class="branch">├─</span> <a href="../package.json">package.json</a></div><div class="tree-line"><span class="branch">├─</span> <a href="../src/ai/analyzer.ts">src/ai/analyzer.ts</a></div><div class="tree-line"><span class="branch">├─</span> <a href="../src/cli/index.ts">src/cli/index.ts</a></div><div class="tree-line"><span class="branch">├─</span> <a href="../src/commands/classify.ts">src/commands/classify.ts</a></div><div class="tree-line"><span class="branch">├─</span> <a href="../src/commands/generateSummary.ts">src/commands/generateSummary.ts</a></div><div class="tree-line"><span class="branch">├─</span> <a href="../src/commands/run.ts">src/commands/run.ts</a></div><div class="tree-line"><span class="branch">├─</span> <a href="../src/exporters/html.ts">src/exporters/html.ts</a></div><div class="tree-line"><span class="branch">├─</span> <a href="../src/index.ts">src/index.ts</a></div><div class="tree-line"><span class="branch">└─</span> <a href="../tsconfig.json">tsconfig.json</a></div><h2>🔬 Analyse détaillée des composants</h2><section class="component-card"><h3 class="comp-title">📄 <a href="../src/index.ts"><code>src/index.ts</code></a></h3><div class="list-item"><strong>Densité et maintenance :</strong> 1 lignes</div><p>---</p><section class="component-card"><h3 class="comp-title">📄 <a href="../src/ai/analyzer.ts"><code>src/ai/analyzer.ts</code></a></h3><div class="list-item"><strong>Densité et maintenance :</strong> 46 lignes</div><div class="list-item"><strong>Capacités offertes :</strong> <code>askAI</code></div><div class="list-item"><strong>Collaborations sollicitées :</strong></div><p>---</p><section class="component-card"><h3 class="comp-title">📄 <a href="../src/cli/index.ts"><code>src/cli/index.ts</code></a></h3><div class="list-item"><strong>Densité et maintenance :</strong> 70 lignes</div><div class="list-item"><strong>Collaborations sollicitées :</strong></div><div class="list-item">Utilise <code>commander</code> (External)</div><div class="list-item">Utilise <code>../commands/run.js</code> (Internal)</div><div class="list-item">Utilise <code>../commands/generateSummary.js</code> (Internal)</div><div class="list-item">Utilise <code>node:readline/promises</code> (Node.js)</div><div class="list-item">Utilise <code>node:process</code> (Node.js)</div><div class="list-item">Utilise <code>node:path</code> (Node.js)</div><p>---</p><section class="component-card"><h3 class="comp-title">📄 <a href="../src/commands/classify.ts"><code>src/commands/classify.ts</code></a></h3><div class="list-item"><strong>Densité et maintenance :</strong> 40 lignes</div><div class="list-item"><strong>Capacités offertes :</strong> <code>determineRole</code></div><div class="list-item"><strong>Collaborations sollicitées :</strong></div><div class="list-item">Utilise <code>node:path</code> (Node.js)</div><p>---</p><section class="component-card"><h3 class="comp-title">📄 <a href="../src/commands/generateSummary.ts"><code>src/commands/generateSummary.ts</code></a></h3><div class="list-item"><strong>Densité et maintenance :</strong> 60 lignes</div><div class="list-item"><strong>Capacités offertes :</strong> <code>generateSummary</code></div><div class="list-item"><strong>Collaborations sollicitées :</strong></div><div class="list-item">Utilise <code>node:fs</code> (Node.js)</div><div class="list-item">Utilise <code>node:path</code> (Node.js)</div><p>---</p><section class="component-card"><h3 class="comp-title">📄 <a href="../src/commands/run.ts"><code>src/commands/run.ts</code></a></h3><div class="list-item"><strong>Densité et maintenance :</strong> 156 lignes</div><div class="list-item"><strong>Capacités offertes :</strong> <code>runCommand</code></div><div class="list-item"><strong>Collaborations sollicitées :</strong></div><div class="list-item">Utilise <code>globby</code> (External)</div><div class="list-item">Utilise <code>node:fs</code> (Node.js)</div><div class="list-item">Utilise <code>node:path</code> (Node.js)</div><div class="list-item">Utilise <code>puppeteer</code> (External)</div><div class="list-item">Utilise <code>../exporters/html.js</code> (Internal)</div><div class="list-item">Utilise <code>../ai/analyzer.js</code> (Internal)</div><p>---</p><section class="component-card"><h3 class="comp-title">📄 <a href="../src/exporters/html.ts"><code>src/exporters/html.ts</code></a></h3><div class="list-item"><strong>Densité et maintenance :</strong> 142 lignes</div><div class="list-item"><strong>Capacités offertes :</strong> <code>exportToHTML</code></div><div class="list-item"><strong>Collaborations sollicitées :</strong></div><div class="list-item">Utilise <code>node:fs</code> (Node.js)</div><div class="list-item">Utilise <code>node:path</code> (Node.js)</div><p>---</p><h2>📦 Inventaire des modules externes</h2><div class="table-container"><table><tr><th>Module</th><th>Type</th></tr><tr><td><code>../ai/analyzer.js</code></td><td>Internal</td></tr><tr><td><code>../commands/generateSummary.js</code></td><td>Internal</td></tr><tr><td><code>../commands/run.js</code></td><td>Internal</td></tr><tr><td><code>../exporters/html.js</code></td><td>Internal</td></tr><tr><td><code>commander</code></td><td>External</td></tr><tr><td><code>globby</code></td><td>External</td></tr><tr><td><code>node:fs</code></td><td>Node.js</td></tr><tr><td><code>node:path</code></td><td>Node.js</td></tr><tr><td><code>node:process</code></td><td>Node.js</td></tr><tr><td><code>node:readline/promises</code></td><td>Node.js</td></tr><tr><td><code>puppeteer</code></td><td>External</td></tr></table></div></section></div>
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<script>
|
|
73
|
+
mermaid.initialize({ startOnLoad: true, theme: 'dark', securityLevel: 'loose' });
|
|
74
|
+
function toggleTheme() {
|
|
75
|
+
const html = document.documentElement;
|
|
76
|
+
const next = html.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
|
|
77
|
+
html.setAttribute('data-theme', next);
|
|
78
|
+
localStorage.setItem('docs-theme', next);
|
|
79
|
+
}
|
|
80
|
+
document.documentElement.setAttribute('data-theme', localStorage.getItem('docs-theme') || 'dark');
|
|
81
|
+
|
|
82
|
+
document.getElementById('search').addEventListener('input', (e) => {
|
|
83
|
+
const term = e.target.value.toLowerCase();
|
|
84
|
+
document.querySelectorAll('.component-card, .tree-line, .table-container').forEach(el => {
|
|
85
|
+
el.style.display = el.innerText.toLowerCase().includes(term) ? '' : 'none';
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
</script>
|
|
89
|
+
</body>
|
|
90
|
+
</html>
|
package/docs/report.pdf
ADDED
|
Binary file
|
package/docs/summary.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# 📊 Vue d'ensemble du Projet – DocsToDev
|
|
2
|
+
|
|
3
|
+
> 📅 **Rapport généré le :** 08/01/2026 19:37:19
|
|
4
|
+
|
|
5
|
+
## 🚀 État des lieux
|
|
6
|
+
Salut ! J'ai passé ton projet au peigne fin. Voici un résumé rapide de ce que j'ai trouvé :
|
|
7
|
+
- **Volume traité :** 10 fichiers analysés avec succès.
|
|
8
|
+
- **Diagnostic :** La structure est claire et l'analyse est complète. ✅
|
|
9
|
+
|
|
10
|
+
## đź§ Navigation Rapide
|
|
11
|
+
Pour aller plus loin, tu peux consulter les documents suivants :
|
|
12
|
+
- **[📂 Arborescence & Analyse](../docs/docs-to-dev.md)** : Pour comprendre la vocation de chaque fichier et les capacités du système.
|
|
13
|
+
- **[đź’» Code Source](../)** : Pour retourner explorer la racine de ton projet.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
*DocsToDev – Ton allié pour une documentation technique vivante et intelligente.*
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "docstodev",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Solution d’automatisation de documentation technique intelligente avec IA",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/cli/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"docs-to-dev": "./dist/cli/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "npm run build && node dist/cli/index.js run",
|
|
13
|
+
"test": "vitest"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"documentation",
|
|
17
|
+
"cli",
|
|
18
|
+
"ai",
|
|
19
|
+
"typescript",
|
|
20
|
+
"mermaid",
|
|
21
|
+
"pdf"
|
|
22
|
+
],
|
|
23
|
+
"author": "Chadrack Massamba",
|
|
24
|
+
"license": "ISC",
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^22.0.0",
|
|
27
|
+
"ts-node": "^10.9.2",
|
|
28
|
+
"tsx": "^4.19.0",
|
|
29
|
+
"typescript": "^5.7.0",
|
|
30
|
+
"vitest": "^3.0.0"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"chalk": "^5.4.1",
|
|
34
|
+
"commander": "^13.1.0",
|
|
35
|
+
"dotenv": "^16.4.7",
|
|
36
|
+
"globby": "^14.0.2",
|
|
37
|
+
"puppeteer": "^24.1.1"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Emplacement absolu : M:\workspace\extensions\docstodev\src\ai\analyzer.ts
|
|
2
|
+
|
|
3
|
+
import "dotenv/config"; // Pour lire GROQ_API_KEY dans ton .env
|
|
4
|
+
|
|
5
|
+
export async function askAI(technicalContext: string) {
|
|
6
|
+
const GROQ_API_KEY = process.env.GROQ_API_KEY;
|
|
7
|
+
|
|
8
|
+
if (!GROQ_API_KEY) {
|
|
9
|
+
return "⚠️ Erreur : Clé API Groq manquante dans le fichier .env";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const systemPrompt = `
|
|
13
|
+
Vous êtes MakazouIA, l'assistant IA de DocsToDev, créé par Chadrack Massamba (EsporDev).
|
|
14
|
+
Votre mission : Transformer des données techniques brutes en descriptions métier claires.
|
|
15
|
+
|
|
16
|
+
Instructions :
|
|
17
|
+
- Vous allez recevoir une liste de fichiers, leurs rĂ´les et leurs exports.
|
|
18
|
+
- Pour chaque fichier, rédigez UNE SEULE phrase concise expliquant sa responsabilité métier.
|
|
19
|
+
- Soyez pro, mais gardez votre touche amicale et votre pointe d'humour du Congo-Brazzaville.
|
|
20
|
+
- Ne mentionnez pas de code technique (pas de "il y a une fonction X"), expliquez le BUT du fichier.
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const resp = await fetch("https://api.groq.com/openai/v1/chat/completions", {
|
|
25
|
+
method: "POST",
|
|
26
|
+
headers: {
|
|
27
|
+
Authorization: `Bearer ${GROQ_API_KEY}`,
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
},
|
|
30
|
+
body: JSON.stringify({
|
|
31
|
+
model: "llama-3.3-70b-versatile",
|
|
32
|
+
messages: [
|
|
33
|
+
{ role: "system", content: systemPrompt },
|
|
34
|
+
{ role: "user", content: `Voici les données techniques du projet : \n${technicalContext}` }
|
|
35
|
+
],
|
|
36
|
+
temperature: 0.7,
|
|
37
|
+
}),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const data = await resp.json();
|
|
41
|
+
return data.choices?.[0]?.message?.content || "Désolé, je n'ai pas pu analyser ce fichier.";
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.error("Erreur IA:", error);
|
|
44
|
+
return "Erreur lors de la connexion Ă l'intelligence artificielle.";
|
|
45
|
+
}
|
|
46
|
+
}
|
package/src/cli/index.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Emplacement absolu : M:\workspace\extensions\docstodev\src\cli\index.ts
|
|
4
|
+
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
import { runCommand } from "../commands/run.js";
|
|
7
|
+
import { generateSummary } from "../commands/generateSummary.js";
|
|
8
|
+
import readline from "node:readline/promises";
|
|
9
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
|
|
12
|
+
const program = new Command();
|
|
13
|
+
|
|
14
|
+
// Configuration de base du CLI
|
|
15
|
+
program
|
|
16
|
+
.name("docs-to-dev")
|
|
17
|
+
.description("DocsToDev CLI - Analyse technique & Documentation intelligente")
|
|
18
|
+
.version("1.0.0");
|
|
19
|
+
|
|
20
|
+
program
|
|
21
|
+
.command("run")
|
|
22
|
+
.description("Lancer le cycle complet d'analyse et de documentation")
|
|
23
|
+
.option("-l, --lang <lang>", "Langue forcée du rapport (fr | en)")
|
|
24
|
+
.action(async (options) => {
|
|
25
|
+
let lang: "fr" | "en";
|
|
26
|
+
|
|
27
|
+
// --- 1. Gestion de la Langue ---
|
|
28
|
+
if (options.lang === "fr" || options.lang === "en") {
|
|
29
|
+
lang = options.lang;
|
|
30
|
+
} else {
|
|
31
|
+
const rl = readline.createInterface({ input, output });
|
|
32
|
+
console.log("\n🌍 Bienvenue dans DocsToDev / Welcome to DocsToDev");
|
|
33
|
+
|
|
34
|
+
let answer = "";
|
|
35
|
+
while (!["fr", "en"].includes(answer.toLowerCase())) {
|
|
36
|
+
answer = await rl.question("👉 Choisissez votre langue / Choose your language (fr/en) : ");
|
|
37
|
+
}
|
|
38
|
+
rl.close();
|
|
39
|
+
lang = answer.toLowerCase() as "fr" | "en";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// --- 2. Interface Utilisateur (Console) ---
|
|
43
|
+
const messages = {
|
|
44
|
+
fr: { start: "🚀 Démarrage de l'analyse approfondie...", success: "✨ Documentation générée avec succès dans /docs !" },
|
|
45
|
+
en: { start: "🚀 Starting deep analysis...", success: "✨ Documentation successfully generated in /docs!" }
|
|
46
|
+
}[lang];
|
|
47
|
+
|
|
48
|
+
console.log(`\n${messages.start} [${lang.toUpperCase()}]\n`);
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
// --- 3. Exécution du Moteur (runCommand) ---
|
|
52
|
+
// Analyse statique + MakazouIA + Export HTML
|
|
53
|
+
const fileCount = await runCommand(lang);
|
|
54
|
+
|
|
55
|
+
// --- 4. Génération du Résumé ---
|
|
56
|
+
generateSummary("docs", fileCount || 0, lang);
|
|
57
|
+
|
|
58
|
+
console.log(`\n${messages.success}`);
|
|
59
|
+
console.log(`đź“‚ Dossier : ${process.cwd()}${path.sep}docs\n`);
|
|
60
|
+
|
|
61
|
+
} catch (error) {
|
|
62
|
+
const errorMsg = lang === "fr"
|
|
63
|
+
? "❌ Une erreur est survenue lors de l'analyse :"
|
|
64
|
+
: "❌ An error occurred during analysis:";
|
|
65
|
+
console.error(errorMsg, error);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
program.parse(process.argv);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Emplacement absolu : M:\workspace\extensions\docstodev\src\commands\classify.ts
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
export function determineRole(filePath: string, content: string, lang: "fr" | "en" = "fr"): string {
|
|
5
|
+
const fileName = path.basename(filePath).toLowerCase();
|
|
6
|
+
const ext = path.extname(filePath);
|
|
7
|
+
|
|
8
|
+
const roles = {
|
|
9
|
+
fr: {
|
|
10
|
+
cli: "Lanceur CLI",
|
|
11
|
+
logic: "Logique Métier / Service",
|
|
12
|
+
ui: "Interface Utilisateur (UI)",
|
|
13
|
+
api: "Point d'Entrée API",
|
|
14
|
+
config: "Configuration Système",
|
|
15
|
+
unknown: "Inconnu"
|
|
16
|
+
},
|
|
17
|
+
en: {
|
|
18
|
+
cli: "CLI Entry Point",
|
|
19
|
+
logic: "Business Logic / Service",
|
|
20
|
+
ui: "User Interface (UI)",
|
|
21
|
+
api: "API Endpoint",
|
|
22
|
+
config: "System Configuration",
|
|
23
|
+
unknown: "Unknown"
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const t = roles[lang];
|
|
28
|
+
|
|
29
|
+
if (filePath.includes("cli") || fileName === "index.ts") return t.cli;
|
|
30
|
+
|
|
31
|
+
if (filePath.includes("commands") || content.includes("export function")) return t.logic;
|
|
32
|
+
|
|
33
|
+
if (content.includes("react") || ext === ".tsx") return t.ui;
|
|
34
|
+
|
|
35
|
+
if (content.includes("NextResponse") || filePath.includes("api/")) return t.api;
|
|
36
|
+
|
|
37
|
+
if (fileName.includes("config") || ext === ".json") return t.config;
|
|
38
|
+
|
|
39
|
+
return t.unknown;
|
|
40
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Emplacement absolu : M:\workspace\extensions\docstodev\src\commands\generateSummary.ts
|
|
2
|
+
|
|
3
|
+
import { writeFileSync, mkdirSync } from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Génère un résumé global du projet avec un ton humain et bilingue.
|
|
8
|
+
*/
|
|
9
|
+
export function generateSummary(docsDir: string, totalFiles: number, lang: "fr" | "en" = "fr") {
|
|
10
|
+
mkdirSync(docsDir, { recursive: true });
|
|
11
|
+
|
|
12
|
+
const dateStr = new Date().toLocaleString();
|
|
13
|
+
|
|
14
|
+
// Contenu bilingue avec un ton "Expert & Humain"
|
|
15
|
+
const content = lang === "fr"
|
|
16
|
+
? `# 📊 Vue d'ensemble du Projet – DocsToDev
|
|
17
|
+
|
|
18
|
+
> 📅 **Rapport généré le :** ${dateStr}
|
|
19
|
+
|
|
20
|
+
## 🚀 État des lieux
|
|
21
|
+
Salut ! J'ai passé ton projet au peigne fin. Voici un résumé rapide de ce que j'ai trouvé :
|
|
22
|
+
- **Volume traité :** ${totalFiles} fichiers analysés avec succès.
|
|
23
|
+
- **Diagnostic :** La structure est claire et l'analyse est complète. ✅
|
|
24
|
+
|
|
25
|
+
## đź§ Navigation Rapide
|
|
26
|
+
Pour aller plus loin, tu peux consulter les documents suivants :
|
|
27
|
+
- **[📂 Arborescence & Analyse](../docs/docs-to-dev.md)** : Pour comprendre la vocation de chaque fichier et les capacités du système.
|
|
28
|
+
- **[đź’» Code Source](../)** : Pour retourner explorer la racine de ton projet.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
*DocsToDev – Ton allié pour une documentation technique vivante et intelligente.*
|
|
32
|
+
`
|
|
33
|
+
: `# 📊 Project Overview – DocsToDev
|
|
34
|
+
|
|
35
|
+
> đź“… **Generated on:** ${dateStr}
|
|
36
|
+
|
|
37
|
+
## 🚀 Project Status
|
|
38
|
+
Hey! I've scanned your entire codebase. Here's a quick summary of the findings:
|
|
39
|
+
- **Volume processed:** ${totalFiles} files successfully analyzed.
|
|
40
|
+
- **Diagnosis:** The structure is clear and the analysis is complete. âś…
|
|
41
|
+
|
|
42
|
+
## đź§ Quick Navigation
|
|
43
|
+
To dive deeper, check out these documents:
|
|
44
|
+
- **[đź“‚ Tree & Analysis](../docs/docs-to-dev.md)**: Explore file purposes and system capabilities.
|
|
45
|
+
- **[đź’» Source Code](../)**: Head back to the project root.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
*DocsToDev – Your partner for living and intelligent technical documentation.*
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
const outputPath = path.join(docsDir, "summary.md");
|
|
52
|
+
writeFileSync(outputPath, content);
|
|
53
|
+
|
|
54
|
+
// Log de succès bilingue
|
|
55
|
+
const successMsg = lang === "fr"
|
|
56
|
+
? `📑 Résumé humain généré avec succès : ${outputPath}`
|
|
57
|
+
: `đź“‘ Human-friendly summary successfully generated: ${outputPath}`;
|
|
58
|
+
|
|
59
|
+
console.log(successMsg);
|
|
60
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// Emplacement absolu : M:\workspace\extensions\docstodev\src\commands\run.ts
|
|
2
|
+
import { globby } from "globby";
|
|
3
|
+
import { writeFileSync, readFileSync, existsSync, mkdirSync } from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import puppeteer from "puppeteer";
|
|
6
|
+
import { exportToHTML } from "../exporters/html.js";
|
|
7
|
+
import { askAI } from "../ai/analyzer.js";
|
|
8
|
+
|
|
9
|
+
type TreeNode = { [key: string]: TreeNode | null };
|
|
10
|
+
|
|
11
|
+
const i18n = {
|
|
12
|
+
fr: {
|
|
13
|
+
role: "Vocation du fichier",
|
|
14
|
+
density: "Densité et maintenance",
|
|
15
|
+
exports: "Capacités offertes",
|
|
16
|
+
imports: "Collaborations sollicitées",
|
|
17
|
+
structure: "Architecture des dossiers",
|
|
18
|
+
deps: "Inventaire des modules externes",
|
|
19
|
+
aiTitle: "Synthèse Métier (par MakazouIA)",
|
|
20
|
+
genAt: "Généré le",
|
|
21
|
+
reportTitle: "Rapport d'Analyse Technique DocsToDev"
|
|
22
|
+
},
|
|
23
|
+
en: {
|
|
24
|
+
role: "File Purpose",
|
|
25
|
+
density: "Density & Maintenance",
|
|
26
|
+
exports: "Capabilities offered",
|
|
27
|
+
imports: "External services",
|
|
28
|
+
structure: "Project Architecture",
|
|
29
|
+
deps: "External Modules Inventory",
|
|
30
|
+
aiTitle: "Business Insights (by MakazouIA)",
|
|
31
|
+
genAt: "Generated on",
|
|
32
|
+
reportTitle: "DocsToDev Technical Report"
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
function buildTree(files: string[]): TreeNode {
|
|
37
|
+
const root: TreeNode = {};
|
|
38
|
+
for (const file of files) {
|
|
39
|
+
const parts = file.split(path.sep);
|
|
40
|
+
let current = root;
|
|
41
|
+
for (const part of parts) {
|
|
42
|
+
if (!current[part]) current[part] = {};
|
|
43
|
+
current = current[part] as TreeNode;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return root;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function renderTree(tree: TreeNode, prefix = "", currentPath = ""): string {
|
|
50
|
+
const entries = Object.keys(tree).sort();
|
|
51
|
+
let output = "";
|
|
52
|
+
entries.forEach((key, index) => {
|
|
53
|
+
const isLast = index === entries.length - 1;
|
|
54
|
+
const connector = isLast ? "└─ " : "├─ ";
|
|
55
|
+
const child = tree[key];
|
|
56
|
+
const fullPath = currentPath ? `${currentPath}/${key}` : key;
|
|
57
|
+
const isFile = !child || Object.keys(child).length === 0;
|
|
58
|
+
const label = isFile ? `[${key}](../${fullPath.replace(/\\/g, '/')})` : `**${key}/**`;
|
|
59
|
+
output += `${prefix}${connector}${label}\n`;
|
|
60
|
+
if (child && Object.keys(child).length > 0) {
|
|
61
|
+
output += renderTree(child, prefix + (isLast ? " " : "│ "), fullPath);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return output;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export async function runCommand(language: "fr" | "en" = "fr"): Promise<number> {
|
|
68
|
+
const t = i18n[language];
|
|
69
|
+
console.log(language === "fr" ? "🚀 DocsToDev : Analyse Deep Scan & Graphe..." : "🚀 DocsToDev: Deep Scan & Graph analysis...");
|
|
70
|
+
|
|
71
|
+
const files = await globby(["**/*"], {
|
|
72
|
+
gitignore: true,
|
|
73
|
+
ignore: ["**/node_modules/**", "**/.git/**", "**/dist/**", "**/docs/**"]
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const docsDir = "docs";
|
|
77
|
+
if (!existsSync(docsDir)) mkdirSync(docsDir, { recursive: true });
|
|
78
|
+
|
|
79
|
+
let aiContext = `Analyse ces fichiers pour DocsToDev. Explique pourquoi ils utilisent leurs dépendances. Format: "Utilise [X] pour [Y]".\n\n`;
|
|
80
|
+
let detailContent = `## 🔬 Analyse détaillée des composants\n\n`;
|
|
81
|
+
let mermaidGraph = "";
|
|
82
|
+
const allDeps = new Map<string, string>();
|
|
83
|
+
|
|
84
|
+
for (const file of files) {
|
|
85
|
+
const ext = path.extname(file);
|
|
86
|
+
if (![".ts", ".js", ".tsx", ".jsx"].includes(ext)) continue;
|
|
87
|
+
|
|
88
|
+
const content = readFileSync(file, "utf-8");
|
|
89
|
+
const lines = content.split(/\r?\n/);
|
|
90
|
+
const fileNameSanitized = path.basename(file).replace(/\./g, '_');
|
|
91
|
+
|
|
92
|
+
const exports = lines
|
|
93
|
+
.filter(l => l.startsWith("export "))
|
|
94
|
+
.map(l => l.match(/(?:function|const|class|type|interface)\s+([a-zA-Z0-9_]+)/)?.[1])
|
|
95
|
+
.filter(Boolean) as string[];
|
|
96
|
+
|
|
97
|
+
const importLines = lines.filter(l => l.trim().startsWith("import "));
|
|
98
|
+
|
|
99
|
+
detailContent += `### đź“„ [\`${file}\`](../${file.replace(/\\/g, '/')})\n`;
|
|
100
|
+
detailContent += `• **${t.density} :** ${lines.length} lignes\n`;
|
|
101
|
+
if (exports.length > 0) detailContent += `• **${t.exports} :** ${exports.map(e => `\`${e}\``).join(", ")}\n`;
|
|
102
|
+
|
|
103
|
+
if (importLines.length > 0) {
|
|
104
|
+
detailContent += `• **${t.imports} :**\n`;
|
|
105
|
+
importLines.forEach(line => {
|
|
106
|
+
const match = line.match(/from ['"]([^'"]+)['"]/);
|
|
107
|
+
if (match?.[1]) {
|
|
108
|
+
const name = match[1];
|
|
109
|
+
const type = name.startsWith('.') ? 'Internal' : (name.startsWith('node:') ? 'Node.js' : 'External');
|
|
110
|
+
allDeps.set(name, type);
|
|
111
|
+
detailContent += ` - Utilise \`${name}\` (${type})\n`;
|
|
112
|
+
|
|
113
|
+
if (type === 'Internal') {
|
|
114
|
+
const targetName = path.basename(name).replace(/\./g, '_');
|
|
115
|
+
mermaidGraph += ` ${fileNameSanitized} --> ${targetName}\n`;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
detailContent += `\n---\n\n`;
|
|
121
|
+
aiContext += `FICHIER: ${file}\nEXPORTS: ${exports.join(",")}\nCODE:\n${lines.slice(0, 40).join("\n")}\n\n`;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const aiSummary = await askAI(aiContext) || "Synthèse IA indisponible.";
|
|
125
|
+
|
|
126
|
+
let finalMD = `# ${t.reportTitle}\n\n`;
|
|
127
|
+
finalMD += `> đź“… ${t.genAt} : ${new Date().toLocaleString()}\n\n`;
|
|
128
|
+
finalMD += `## đź’ˇ ${t.aiTitle}\n${aiSummary}\n\n`;
|
|
129
|
+
finalMD += `## đź“‚ ${t.structure}\n\n${renderTree(buildTree(files))}\n\n`;
|
|
130
|
+
finalMD += detailContent;
|
|
131
|
+
finalMD += `## 📦 ${t.deps}\n\n| Module | Type |\n| :--- | :--- |\n`;
|
|
132
|
+
Array.from(allDeps.entries()).sort().forEach(([n, ty]) => finalMD += `| \`${n}\` | ${ty} |\n`);
|
|
133
|
+
|
|
134
|
+
writeFileSync(path.join(docsDir, "docs-to-dev.md"), finalMD);
|
|
135
|
+
exportToHTML(docsDir, finalMD, mermaidGraph, language);
|
|
136
|
+
|
|
137
|
+
console.log("📄 Génération du PDF automatique...");
|
|
138
|
+
await generatePDF(path.join(docsDir, "report.html"), path.join(docsDir, "report.pdf"));
|
|
139
|
+
|
|
140
|
+
return files.length;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function generatePDF(htmlPath: string, outputPath: string) {
|
|
144
|
+
try {
|
|
145
|
+
const browser = await puppeteer.launch({ headless: true });
|
|
146
|
+
const page = await browser.newPage();
|
|
147
|
+
await page.goto(`file://${path.resolve(htmlPath)}`, { waitUntil: "networkidle0" });
|
|
148
|
+
await page.pdf({
|
|
149
|
+
path: outputPath,
|
|
150
|
+
format: 'A4',
|
|
151
|
+
printBackground: true,
|
|
152
|
+
margin: { top: '1cm', bottom: '1cm', left: '1cm', right: '1cm' }
|
|
153
|
+
});
|
|
154
|
+
await browser.close();
|
|
155
|
+
} catch (e) { console.error("Erreur PDF:", e); }
|
|
156
|
+
}
|