ether-code 0.1.8 → 0.2.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/LICENSE +1 -1
- package/README.md +27 -89
- package/cli/compiler.js +11 -25
- package/cli/ether.js +21 -187
- package/ether-compiler.js +190 -0
- package/ether-parser.js +3059 -0
- package/package.json +3 -2
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,130 +1,68 @@
|
|
|
1
1
|
# Ether
|
|
2
2
|
|
|
3
|
-
**Le langage intentionnel** -
|
|
4
|
-
|
|
5
|
-
Ether est un compilateur qui transforme du code écrit en langage naturel (français, anglais, espagnol, russe, chinois, japonais) en code exécutable dans les langages cibles : JavaScript, TypeScript, HTML, CSS, PHP, Python, Ruby, SQL, Node.js, React, GraphQL.
|
|
3
|
+
**Le langage intentionnel** - Écrivez du code comme vous pensez.
|
|
6
4
|
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
9
7
|
```bash
|
|
10
|
-
npm install -g ether-
|
|
8
|
+
npm install -g ether-code
|
|
11
9
|
```
|
|
12
10
|
|
|
13
11
|
## Utilisation
|
|
14
12
|
|
|
15
|
-
###
|
|
13
|
+
### Initialiser un projet
|
|
16
14
|
|
|
17
15
|
```bash
|
|
18
|
-
ether
|
|
16
|
+
ether init
|
|
19
17
|
```
|
|
20
18
|
|
|
21
|
-
###
|
|
19
|
+
### Compiler
|
|
22
20
|
|
|
23
21
|
```bash
|
|
24
|
-
ether
|
|
22
|
+
ether build
|
|
25
23
|
```
|
|
26
24
|
|
|
27
|
-
###
|
|
25
|
+
### Mode développement (watch)
|
|
28
26
|
|
|
29
27
|
```bash
|
|
30
|
-
ether
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Configuration
|
|
34
|
-
|
|
35
|
-
Créez un fichier `ether.config.json` à la racine de votre projet :
|
|
36
|
-
|
|
37
|
-
```json
|
|
38
|
-
{
|
|
39
|
-
"lang": "fr",
|
|
40
|
-
"src": "./src",
|
|
41
|
-
"out": "./dist",
|
|
42
|
-
"targets": ["js", "css", "html"]
|
|
43
|
-
}
|
|
28
|
+
ether dev
|
|
44
29
|
```
|
|
45
30
|
|
|
46
|
-
### Options
|
|
47
|
-
|
|
48
|
-
| Option | Description | Défaut |
|
|
49
|
-
|--------|-------------|--------|
|
|
50
|
-
| `lang` | Langue source (fr, en, es, ru, zh, ja) | `fr` |
|
|
51
|
-
| `src` | Dossier source | `./src` |
|
|
52
|
-
| `out` | Dossier de sortie | `./dist` |
|
|
53
|
-
| `targets` | Langages cibles | tous |
|
|
54
|
-
|
|
55
31
|
## Exemple
|
|
56
32
|
|
|
57
|
-
|
|
33
|
+
Créez un fichier `src/index.eth`:
|
|
58
34
|
|
|
59
|
-
```ether
|
|
60
|
-
// style.eth
|
|
61
|
-
sélecteur ".bouton"
|
|
62
|
-
couleur fond: bleu
|
|
63
|
-
couleur texte: blanc
|
|
64
|
-
marge: 1rem
|
|
65
|
-
bordure arrondie: 0.5rem
|
|
66
35
|
```
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
border-radius: 0.5rem;
|
|
76
|
-
}
|
|
36
|
+
// cible: html
|
|
37
|
+
|
|
38
|
+
document
|
|
39
|
+
tete
|
|
40
|
+
titre "Ma page"
|
|
41
|
+
corps
|
|
42
|
+
titre1 "Bienvenue"
|
|
43
|
+
paragraphe "Ether permet d'écrire du code naturellement."
|
|
77
44
|
```
|
|
78
45
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
```ether
|
|
82
|
-
// app.eth
|
|
83
|
-
fonction saluer avec nom
|
|
84
|
-
retourner "Bonjour, " + nom + "!"
|
|
85
|
-
|
|
86
|
-
afficher saluer("Monde")
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### Résultat JavaScript
|
|
90
|
-
|
|
91
|
-
```javascript
|
|
92
|
-
function saluer(nom) {
|
|
93
|
-
return "Bonjour, " + nom + "!";
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
console.log(saluer("Monde"));
|
|
97
|
-
```
|
|
46
|
+
Compilez avec `ether build` pour générer `dist/index.html`.
|
|
98
47
|
|
|
99
48
|
## Langages supportés
|
|
100
49
|
|
|
101
|
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
- 🇷🇺 Русский
|
|
106
|
-
- 🇨🇳 中文
|
|
107
|
-
- 🇯🇵 日本語
|
|
108
|
-
|
|
109
|
-
### Langages cibles
|
|
110
|
-
- JavaScript / TypeScript
|
|
111
|
-
- HTML / CSS
|
|
50
|
+
- HTML
|
|
51
|
+
- CSS
|
|
52
|
+
- JavaScript
|
|
53
|
+
- TypeScript
|
|
112
54
|
- PHP
|
|
113
55
|
- Python
|
|
114
56
|
- Ruby
|
|
115
57
|
- SQL
|
|
116
58
|
- Node.js
|
|
117
|
-
- React
|
|
59
|
+
- React
|
|
118
60
|
- GraphQL
|
|
119
61
|
|
|
120
|
-
##
|
|
121
|
-
|
|
122
|
-
Ether est un **langage intentionnel** : au lieu de forcer les humains à parler comme des machines, Ether permet aux machines de comprendre l'intention humaine.
|
|
62
|
+
## Documentation
|
|
123
63
|
|
|
124
|
-
-
|
|
125
|
-
- **Multilingue** : Programmez dans votre langue maternelle
|
|
126
|
-
- **Universel** : Un seul langage, tous les frameworks
|
|
64
|
+
https://ether-code.com/docs
|
|
127
65
|
|
|
128
|
-
##
|
|
66
|
+
## License
|
|
129
67
|
|
|
130
|
-
MIT
|
|
68
|
+
MIT
|
package/cli/compiler.js
CHANGED
|
@@ -66,7 +66,6 @@ class EtherCompiler {
|
|
|
66
66
|
...config
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
this.lexer = new EtherLexer()
|
|
70
69
|
this.generators = {}
|
|
71
70
|
this.parser = null
|
|
72
71
|
|
|
@@ -111,12 +110,9 @@ class EtherCompiler {
|
|
|
111
110
|
async compileFile(filePath) {
|
|
112
111
|
const content = fs.readFileSync(filePath, 'utf-8')
|
|
113
112
|
const fileName = path.basename(filePath, '.eth')
|
|
114
|
-
const dirName = path.dirname(filePath)
|
|
115
113
|
|
|
116
114
|
const target = this.detectTarget(content, filePath)
|
|
117
|
-
|
|
118
115
|
const ast = this.parse(content, target)
|
|
119
|
-
|
|
120
116
|
const code = this.generate(ast, target)
|
|
121
117
|
|
|
122
118
|
const extension = this.getExtension(target)
|
|
@@ -179,38 +175,34 @@ class EtherCompiler {
|
|
|
179
175
|
inferTargetFromContent(content) {
|
|
180
176
|
const patterns = {
|
|
181
177
|
html: [
|
|
178
|
+
/^document\b/im,
|
|
182
179
|
/^html\b/im,
|
|
183
|
-
/\b(
|
|
184
|
-
/\b(balise|élément|element|attribut)\b/i
|
|
180
|
+
/\b(page|entête|entete|corps|section|paragraphe|titre|lien|image|formulaire|bouton)\b/i
|
|
185
181
|
],
|
|
186
182
|
css: [
|
|
187
|
-
/\b(
|
|
188
|
-
|
|
189
|
-
|
|
183
|
+
/\b(fond|couleur|marge|bordure|police|largeur|hauteur)\s*:/i,
|
|
184
|
+
/^\s*\./m,
|
|
185
|
+
/^\s*#[\w-]+\s*$/m
|
|
190
186
|
],
|
|
191
187
|
js: [
|
|
192
188
|
/\b(fonction|variable|constante|si|sinon|pour|tant que|retourner)\b/i,
|
|
193
|
-
/\b(classe|méthode|constructeur)\b/i
|
|
194
|
-
/=>\s*\{/
|
|
189
|
+
/\b(classe|méthode|constructeur)\b/i
|
|
195
190
|
],
|
|
196
191
|
php: [
|
|
197
|
-
/\b(
|
|
192
|
+
/\b(<\?php|echo|namespace|utiliser)\b/i,
|
|
198
193
|
/\$\w+/
|
|
199
194
|
],
|
|
200
195
|
sql: [
|
|
201
|
-
/\b(sélectionner|insérer|mettre à jour|supprimer|créer
|
|
202
|
-
/\b(SELECT|INSERT|UPDATE|DELETE|CREATE|FROM|WHERE)\b/i
|
|
196
|
+
/\b(sélectionner|selectionner|insérer|mettre à jour|supprimer|créer|depuis|où)\b/i
|
|
203
197
|
],
|
|
204
198
|
python: [
|
|
205
|
-
/\b(def|
|
|
206
|
-
/:\s*$/m
|
|
199
|
+
/\b(définir|def|classe|importer)\b/i
|
|
207
200
|
],
|
|
208
201
|
react: [
|
|
209
|
-
/\b(composant|état|effet|props|rendu)\b/i
|
|
210
|
-
/<[\w]+[^>]*\/>/
|
|
202
|
+
/\b(composant|état|effet|props|rendu)\b/i
|
|
211
203
|
],
|
|
212
204
|
graphql: [
|
|
213
|
-
/\b(type|
|
|
205
|
+
/\b(type|requête|mutation|subscription|schema|entrée)\b/i
|
|
214
206
|
]
|
|
215
207
|
}
|
|
216
208
|
|
|
@@ -239,12 +231,6 @@ class EtherCompiler {
|
|
|
239
231
|
const content = fs.readFileSync(filePath, 'utf-8')
|
|
240
232
|
const target = this.detectTarget(content, filePath)
|
|
241
233
|
|
|
242
|
-
try {
|
|
243
|
-
this.lexer.tokenize(content)
|
|
244
|
-
} catch (err) {
|
|
245
|
-
throw new Error(`Erreur de lexer: ${err.message}`)
|
|
246
|
-
}
|
|
247
|
-
|
|
248
234
|
try {
|
|
249
235
|
this.parse(content, target)
|
|
250
236
|
} catch (err) {
|
package/cli/ether.js
CHANGED
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
const path = require('path')
|
|
5
|
-
const http = require('http')
|
|
6
5
|
const { EtherCompiler } = require('./compiler')
|
|
7
6
|
const { Watcher } = require('./watcher')
|
|
8
7
|
|
|
9
|
-
const VERSION = '0.
|
|
8
|
+
const VERSION = '0.2.0'
|
|
10
9
|
|
|
11
10
|
const COLORS = {
|
|
12
11
|
reset: '\x1b[0m',
|
|
@@ -63,7 +62,7 @@ ${COLORS.bright}UTILISATION${COLORS.reset}
|
|
|
63
62
|
${COLORS.bright}COMMANDES${COLORS.reset}
|
|
64
63
|
${COLORS.cyan}init${COLORS.reset} Initialiser un nouveau projet Ether
|
|
65
64
|
${COLORS.cyan}build${COLORS.reset} Compiler les fichiers .eth
|
|
66
|
-
${COLORS.cyan}dev${COLORS.reset} Mode développement (
|
|
65
|
+
${COLORS.cyan}dev${COLORS.reset} Mode développement (watch + compilation auto)
|
|
67
66
|
${COLORS.cyan}check${COLORS.reset} Vérifier la syntaxe sans compiler
|
|
68
67
|
${COLORS.cyan}help${COLORS.reset} Afficher cette aide
|
|
69
68
|
${COLORS.cyan}version${COLORS.reset} Afficher la version
|
|
@@ -71,7 +70,6 @@ ${COLORS.bright}COMMANDES${COLORS.reset}
|
|
|
71
70
|
${COLORS.bright}OPTIONS${COLORS.reset}
|
|
72
71
|
-c, --config Chemin vers le fichier de configuration
|
|
73
72
|
-o, --output Dossier de sortie
|
|
74
|
-
-p, --port Port du serveur de développement (défaut: 3000)
|
|
75
73
|
-w, --watch Surveiller les changements (alias de dev)
|
|
76
74
|
-v, --verbose Mode verbeux
|
|
77
75
|
-q, --quiet Mode silencieux
|
|
@@ -84,11 +82,11 @@ ${COLORS.bright}EXEMPLES${COLORS.reset}
|
|
|
84
82
|
${COLORS.dim}# Compiler le projet${COLORS.reset}
|
|
85
83
|
ether build
|
|
86
84
|
|
|
87
|
-
${COLORS.dim}# Mode développement
|
|
85
|
+
${COLORS.dim}# Mode développement${COLORS.reset}
|
|
88
86
|
ether dev
|
|
89
87
|
|
|
90
|
-
${COLORS.dim}#
|
|
91
|
-
ether
|
|
88
|
+
${COLORS.dim}# Compiler avec config personnalisée${COLORS.reset}
|
|
89
|
+
ether build -c ./mon-config.js
|
|
92
90
|
|
|
93
91
|
${COLORS.bright}DOCUMENTATION${COLORS.reset}
|
|
94
92
|
https://ether-code.com/docs
|
|
@@ -148,23 +146,11 @@ async function cmdInit() {
|
|
|
148
146
|
fs.mkdirSync(srcDir, { recursive: true })
|
|
149
147
|
logSuccess('Dossier src/ créé')
|
|
150
148
|
}
|
|
151
|
-
|
|
152
|
-
const
|
|
153
|
-
if (!fs.existsSync(
|
|
154
|
-
fs.mkdirSync(
|
|
155
|
-
logSuccess('Dossier
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const imagesDir = path.join(publicDir, 'images')
|
|
159
|
-
if (!fs.existsSync(imagesDir)) {
|
|
160
|
-
fs.mkdirSync(imagesDir, { recursive: true })
|
|
161
|
-
logSuccess('Dossier public/images/ créé')
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const videosDir = path.join(publicDir, 'videos')
|
|
165
|
-
if (!fs.existsSync(videosDir)) {
|
|
166
|
-
fs.mkdirSync(videosDir, { recursive: true })
|
|
167
|
-
logSuccess('Dossier public/videos/ créé')
|
|
149
|
+
|
|
150
|
+
const distDir = path.join(cwd, 'dist')
|
|
151
|
+
if (!fs.existsSync(distDir)) {
|
|
152
|
+
fs.mkdirSync(distDir, { recursive: true })
|
|
153
|
+
logSuccess('Dossier dist/ créé')
|
|
168
154
|
}
|
|
169
155
|
|
|
170
156
|
const configContent = `module.exports = {
|
|
@@ -202,42 +188,23 @@ async function cmdInit() {
|
|
|
202
188
|
logWarning('ether.config.js existe déjà')
|
|
203
189
|
}
|
|
204
190
|
|
|
205
|
-
const
|
|
206
|
-
const packageJson = {
|
|
207
|
-
name: projectName,
|
|
208
|
-
version: "1.0.0",
|
|
209
|
-
description: "Projet Ether",
|
|
210
|
-
scripts: {
|
|
211
|
-
dev: "ether dev",
|
|
212
|
-
build: "ether build",
|
|
213
|
-
check: "ether check"
|
|
214
|
-
},
|
|
215
|
-
keywords: ["ether"],
|
|
216
|
-
license: "MIT"
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const packagePath = path.join(cwd, 'package.json')
|
|
220
|
-
if (!fs.existsSync(packagePath)) {
|
|
221
|
-
fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2))
|
|
222
|
-
logSuccess('Fichier package.json créé')
|
|
223
|
-
} else {
|
|
224
|
-
logWarning('package.json existe déjà')
|
|
225
|
-
}
|
|
191
|
+
const exampleEth = `// cible: html
|
|
226
192
|
|
|
227
|
-
|
|
228
|
-
|
|
193
|
+
document
|
|
194
|
+
tete
|
|
229
195
|
titre "Ma première page Ether"
|
|
196
|
+
|
|
230
197
|
corps
|
|
231
198
|
entete
|
|
232
199
|
titre1 "Bienvenue sur Ether"
|
|
233
|
-
|
|
200
|
+
|
|
234
201
|
principal
|
|
235
|
-
section
|
|
236
|
-
titre2 "
|
|
237
|
-
paragraphe "
|
|
238
|
-
|
|
202
|
+
section
|
|
203
|
+
titre2 "Le langage intentionnel"
|
|
204
|
+
paragraphe "Ether permet d'écrire du code comme on pense."
|
|
205
|
+
|
|
239
206
|
pied
|
|
240
|
-
paragraphe "
|
|
207
|
+
paragraphe "Créé avec Ether"
|
|
241
208
|
`
|
|
242
209
|
|
|
243
210
|
const examplePath = path.join(srcDir, 'index.eth')
|
|
@@ -268,7 +235,6 @@ async function cmdBuild(options) {
|
|
|
268
235
|
const config = loadConfig(options.config)
|
|
269
236
|
const srcDir = path.resolve(process.cwd(), config.src)
|
|
270
237
|
const outDir = path.resolve(process.cwd(), options.output || config.out)
|
|
271
|
-
const publicDir = path.resolve(process.cwd(), config.public || 'public')
|
|
272
238
|
|
|
273
239
|
if (!fs.existsSync(srcDir)) {
|
|
274
240
|
logError(`Dossier source introuvable: ${srcDir}`)
|
|
@@ -279,13 +245,6 @@ async function cmdBuild(options) {
|
|
|
279
245
|
fs.mkdirSync(outDir, { recursive: true })
|
|
280
246
|
}
|
|
281
247
|
|
|
282
|
-
if (fs.existsSync(publicDir)) {
|
|
283
|
-
copyDir(publicDir, outDir)
|
|
284
|
-
if (!options.quiet) {
|
|
285
|
-
logSuccess('Dossier public/ copié vers dist/')
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
248
|
const compiler = new EtherCompiler(config)
|
|
290
249
|
|
|
291
250
|
const files = findEthFiles(srcDir)
|
|
@@ -345,7 +304,6 @@ async function cmdDev(options) {
|
|
|
345
304
|
const config = loadConfig(options.config)
|
|
346
305
|
const srcDir = path.resolve(process.cwd(), config.src)
|
|
347
306
|
const outDir = path.resolve(process.cwd(), options.output || config.out)
|
|
348
|
-
const port = options.port || config.port || 3000
|
|
349
307
|
|
|
350
308
|
if (!fs.existsSync(srcDir)) {
|
|
351
309
|
logError(`Dossier source introuvable: ${srcDir}`)
|
|
@@ -354,106 +312,9 @@ async function cmdDev(options) {
|
|
|
354
312
|
|
|
355
313
|
logInfo(`Surveillance de ${srcDir}`)
|
|
356
314
|
logInfo(`Sortie vers ${outDir}`)
|
|
357
|
-
console.log('')
|
|
358
315
|
|
|
359
316
|
await cmdBuild({ ...options, quiet: true })
|
|
360
317
|
|
|
361
|
-
const clients = []
|
|
362
|
-
|
|
363
|
-
const MIME_TYPES = {
|
|
364
|
-
'.html': 'text/html',
|
|
365
|
-
'.css': 'text/css',
|
|
366
|
-
'.js': 'application/javascript',
|
|
367
|
-
'.json': 'application/json',
|
|
368
|
-
'.png': 'image/png',
|
|
369
|
-
'.jpg': 'image/jpeg',
|
|
370
|
-
'.jpeg': 'image/jpeg',
|
|
371
|
-
'.gif': 'image/gif',
|
|
372
|
-
'.svg': 'image/svg+xml',
|
|
373
|
-
'.ico': 'image/x-icon',
|
|
374
|
-
'.webp': 'image/webp',
|
|
375
|
-
'.mp4': 'video/mp4',
|
|
376
|
-
'.webm': 'video/webm',
|
|
377
|
-
'.woff': 'font/woff',
|
|
378
|
-
'.woff2': 'font/woff2',
|
|
379
|
-
'.ttf': 'font/ttf'
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
const LIVE_RELOAD_SCRIPT = `
|
|
383
|
-
<script>
|
|
384
|
-
(function() {
|
|
385
|
-
const es = new EventSource('/__ether_reload');
|
|
386
|
-
es.onmessage = function(e) {
|
|
387
|
-
if (e.data === 'reload') {
|
|
388
|
-
window.location.reload();
|
|
389
|
-
}
|
|
390
|
-
};
|
|
391
|
-
es.onerror = function() {
|
|
392
|
-
es.close();
|
|
393
|
-
setTimeout(function() { window.location.reload(); }, 1000);
|
|
394
|
-
};
|
|
395
|
-
})();
|
|
396
|
-
</script>
|
|
397
|
-
</body>`
|
|
398
|
-
|
|
399
|
-
const server = http.createServer((req, res) => {
|
|
400
|
-
if (req.url === '/__ether_reload') {
|
|
401
|
-
res.writeHead(200, {
|
|
402
|
-
'Content-Type': 'text/event-stream',
|
|
403
|
-
'Cache-Control': 'no-cache',
|
|
404
|
-
'Connection': 'keep-alive',
|
|
405
|
-
'Access-Control-Allow-Origin': '*'
|
|
406
|
-
})
|
|
407
|
-
res.write('data: connected\n\n')
|
|
408
|
-
clients.push(res)
|
|
409
|
-
req.on('close', () => {
|
|
410
|
-
const index = clients.indexOf(res)
|
|
411
|
-
if (index > -1) clients.splice(index, 1)
|
|
412
|
-
})
|
|
413
|
-
return
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
let filePath = req.url === '/' ? '/index.html' : req.url
|
|
417
|
-
filePath = filePath.split('?')[0]
|
|
418
|
-
filePath = path.join(outDir, filePath)
|
|
419
|
-
|
|
420
|
-
const ext = path.extname(filePath).toLowerCase()
|
|
421
|
-
const contentType = MIME_TYPES[ext] || 'application/octet-stream'
|
|
422
|
-
|
|
423
|
-
fs.readFile(filePath, (err, content) => {
|
|
424
|
-
if (err) {
|
|
425
|
-
if (err.code === 'ENOENT') {
|
|
426
|
-
res.writeHead(404)
|
|
427
|
-
res.end('404 - Fichier non trouvé')
|
|
428
|
-
} else {
|
|
429
|
-
res.writeHead(500)
|
|
430
|
-
res.end('Erreur serveur')
|
|
431
|
-
}
|
|
432
|
-
return
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
if (ext === '.html') {
|
|
436
|
-
content = content.toString().replace('</body>', LIVE_RELOAD_SCRIPT)
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
res.writeHead(200, { 'Content-Type': contentType })
|
|
440
|
-
res.end(content)
|
|
441
|
-
})
|
|
442
|
-
})
|
|
443
|
-
|
|
444
|
-
server.listen(port, () => {
|
|
445
|
-
logSuccess(`Serveur démarré sur http://localhost:${port}`)
|
|
446
|
-
console.log('')
|
|
447
|
-
logInfo('En attente de modifications... (Ctrl+C pour arrêter)')
|
|
448
|
-
console.log('')
|
|
449
|
-
})
|
|
450
|
-
|
|
451
|
-
function notifyClients() {
|
|
452
|
-
clients.forEach(client => {
|
|
453
|
-
client.write('data: reload\n\n')
|
|
454
|
-
})
|
|
455
|
-
}
|
|
456
|
-
|
|
457
318
|
const watcher = new Watcher(srcDir, config.watch)
|
|
458
319
|
const compiler = new EtherCompiler(config)
|
|
459
320
|
|
|
@@ -477,8 +338,6 @@ async function cmdDev(options) {
|
|
|
477
338
|
fs.writeFileSync(outPath, output.content)
|
|
478
339
|
logSuccess(`→ ${output.path}`)
|
|
479
340
|
}
|
|
480
|
-
|
|
481
|
-
notifyClients()
|
|
482
341
|
} catch (err) {
|
|
483
342
|
logError(err.message)
|
|
484
343
|
}
|
|
@@ -504,8 +363,6 @@ async function cmdDev(options) {
|
|
|
504
363
|
fs.writeFileSync(outPath, output.content)
|
|
505
364
|
logSuccess(`→ ${output.path}`)
|
|
506
365
|
}
|
|
507
|
-
|
|
508
|
-
notifyClients()
|
|
509
366
|
} catch (err) {
|
|
510
367
|
logError(err.message)
|
|
511
368
|
}
|
|
@@ -520,8 +377,7 @@ async function cmdDev(options) {
|
|
|
520
377
|
|
|
521
378
|
process.on('SIGINT', () => {
|
|
522
379
|
console.log('')
|
|
523
|
-
logInfo('Arrêt du
|
|
524
|
-
server.close()
|
|
380
|
+
logInfo('Arrêt du mode développement')
|
|
525
381
|
watcher.stop()
|
|
526
382
|
process.exit(0)
|
|
527
383
|
})
|
|
@@ -596,31 +452,11 @@ function findEthFiles(dir) {
|
|
|
596
452
|
return files
|
|
597
453
|
}
|
|
598
454
|
|
|
599
|
-
function copyDir(src, dest) {
|
|
600
|
-
if (!fs.existsSync(dest)) {
|
|
601
|
-
fs.mkdirSync(dest, { recursive: true })
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
const entries = fs.readdirSync(src, { withFileTypes: true })
|
|
605
|
-
|
|
606
|
-
for (const entry of entries) {
|
|
607
|
-
const srcPath = path.join(src, entry.name)
|
|
608
|
-
const destPath = path.join(dest, entry.name)
|
|
609
|
-
|
|
610
|
-
if (entry.isDirectory()) {
|
|
611
|
-
copyDir(srcPath, destPath)
|
|
612
|
-
} else {
|
|
613
|
-
fs.copyFileSync(srcPath, destPath)
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
|
|
618
455
|
function parseArgs(args) {
|
|
619
456
|
const options = {
|
|
620
457
|
command: null,
|
|
621
458
|
config: null,
|
|
622
459
|
output: null,
|
|
623
|
-
port: null,
|
|
624
460
|
verbose: false,
|
|
625
461
|
quiet: false,
|
|
626
462
|
watch: false
|
|
@@ -634,8 +470,6 @@ function parseArgs(args) {
|
|
|
634
470
|
options.config = args[++i]
|
|
635
471
|
} else if (arg === '-o' || arg === '--output') {
|
|
636
472
|
options.output = args[++i]
|
|
637
|
-
} else if (arg === '-p' || arg === '--port') {
|
|
638
|
-
options.port = parseInt(args[++i], 10)
|
|
639
473
|
} else if (arg === '-v' || arg === '--verbose') {
|
|
640
474
|
options.verbose = true
|
|
641
475
|
} else if (arg === '-q' || arg === '--quiet') {
|