ether-code 0.2.7 → 0.2.8

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.
Files changed (2) hide show
  1. package/cli/ether.js +233 -868
  2. package/package.json +1 -1
package/cli/ether.js CHANGED
@@ -6,7 +6,7 @@ const http = require('http')
6
6
  const { EtherCompiler } = require('./compiler')
7
7
  const { Watcher } = require('./watcher')
8
8
 
9
- const VERSION = '0.2.7'
9
+ const VERSION = '0.2.8'
10
10
 
11
11
  const COLORS = {
12
12
  reset: '\x1b[0m',
@@ -20,163 +20,131 @@ const COLORS = {
20
20
  cyan: '\x1b[36m'
21
21
  }
22
22
 
23
- function log(msg, color = '') {
24
- console.log(`${color}${msg}${COLORS.reset}`)
23
+ const MIME_TYPES = {
24
+ '.html': 'text/html',
25
+ '.css': 'text/css',
26
+ '.js': 'application/javascript',
27
+ '.json': 'application/json',
28
+ '.png': 'image/png',
29
+ '.jpg': 'image/jpeg',
30
+ '.jpeg': 'image/jpeg',
31
+ '.gif': 'image/gif',
32
+ '.svg': 'image/svg+xml',
33
+ '.ico': 'image/x-icon',
34
+ '.woff': 'font/woff',
35
+ '.woff2': 'font/woff2',
36
+ '.ttf': 'font/ttf',
37
+ '.eot': 'application/vnd.ms-fontobject'
38
+ }
39
+
40
+ function log(msg, color) {
41
+ console.log((color || '') + msg + COLORS.reset)
25
42
  }
26
43
 
27
44
  function logSuccess(msg) {
28
- log(`✓ ${msg}`, COLORS.green)
45
+ console.log(COLORS.green + '✓ ' + msg + COLORS.reset)
29
46
  }
30
47
 
31
48
  function logError(msg) {
32
- log(`✗ ${msg}`, COLORS.red)
49
+ console.log(COLORS.red + '✗ ' + msg + COLORS.reset)
33
50
  }
34
51
 
35
52
  function logInfo(msg) {
36
- log(`ℹ ${msg}`, COLORS.cyan)
53
+ console.log(COLORS.cyan + 'ℹ ' + msg + COLORS.reset)
37
54
  }
38
55
 
39
56
  function logWarning(msg) {
40
- log(`⚠ ${msg}`, COLORS.yellow)
57
+ console.log(COLORS.yellow + '⚠ ' + msg + COLORS.reset)
41
58
  }
42
59
 
43
60
  function showBanner() {
44
- console.log(`
45
- ${COLORS.cyan}${COLORS.bright}
46
- ███████╗████████╗██╗ ██╗███████╗██████╗
47
- ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔══██╗
48
- █████╗ ██║ ███████║█████╗ ██████╔╝
49
- ██╔══╝ ██║ ██╔══██║██╔══╝ ██╔══██╗
50
- ███████╗ ██║ ██║ ██║███████╗██║ ██║
51
- ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
52
- ${COLORS.reset}
53
- ${COLORS.dim}Le langage intentionnel - v${VERSION}${COLORS.reset}
54
- `)
61
+ console.log(COLORS.cyan + COLORS.bright)
62
+ console.log(' ███████╗████████╗██╗ ██╗███████╗██████╗ ')
63
+ console.log(' ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔══██╗')
64
+ console.log(' █████╗ ██║ ███████║█████╗ ██████╔╝')
65
+ console.log(' ██╔══╝ ██║ ██╔══██║██╔══╝ ██╔══██╗')
66
+ console.log(' ███████╗ ██║ ██║ ██║███████╗██║ ██║')
67
+ console.log(' ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝')
68
+ console.log(COLORS.reset)
69
+ console.log(' ' + COLORS.dim + 'Le langage intentionnel - v' + VERSION + COLORS.reset)
55
70
  }
56
71
 
57
72
  function showHelp() {
58
73
  showBanner()
59
- console.log(`
60
- ${COLORS.bright}UTILISATION${COLORS.reset}
61
- ether <commande> [options]
62
-
63
- ${COLORS.bright}COMMANDES${COLORS.reset}
64
- ${COLORS.cyan}init${COLORS.reset} Initialiser un nouveau projet Ether
65
- ${COLORS.cyan}build${COLORS.reset} Compiler les fichiers .eth
66
- ${COLORS.cyan}dev${COLORS.reset} Mode développement (watch + serveur + live-reload)
67
- ${COLORS.cyan}check${COLORS.reset} Vérifier la syntaxe sans compiler
68
- ${COLORS.cyan}help${COLORS.reset} Afficher cette aide
69
- ${COLORS.cyan}version${COLORS.reset} Afficher la version
70
-
71
- ${COLORS.bright}OPTIONS${COLORS.reset}
72
- -c, --config Chemin vers le fichier de configuration
73
- -o, --output Dossier de sortie
74
- -p, --port Port du serveur (défaut: 3000)
75
- -w, --watch Surveiller les changements (alias de dev)
76
- -v, --verbose Mode verbeux
77
- -q, --quiet Mode silencieux
78
- --no-color Désactiver les couleurs
79
- --no-server Désactiver le serveur en mode dev
80
-
81
- ${COLORS.bright}EXEMPLES${COLORS.reset}
82
- ${COLORS.dim}# Initialiser un projet${COLORS.reset}
83
- ether init
84
-
85
- ${COLORS.dim}# Compiler le projet${COLORS.reset}
86
- ether build
87
-
88
- ${COLORS.dim}# Mode développement avec serveur${COLORS.reset}
89
- ether dev
90
-
91
- ${COLORS.dim}# Mode développement sur port 8080${COLORS.reset}
92
- ether dev -p 8080
93
-
94
- ${COLORS.bright}DOCUMENTATION${COLORS.reset}
95
- https://ether-code.com/docs
96
- `)
97
- }
98
-
99
- function showVersion() {
100
- console.log(`Ether v${VERSION}`)
74
+ console.log('')
75
+ console.log(COLORS.bright + 'UTILISATION' + COLORS.reset)
76
+ console.log(' ether <commande> [options]')
77
+ console.log('')
78
+ console.log(COLORS.bright + 'COMMANDES' + COLORS.reset)
79
+ console.log(' ' + COLORS.cyan + 'init' + COLORS.reset + ' Initialiser un nouveau projet Ether')
80
+ console.log(' ' + COLORS.cyan + 'build' + COLORS.reset + ' Compiler les fichiers .eth')
81
+ console.log(' ' + COLORS.cyan + 'dev' + COLORS.reset + ' Mode développement avec serveur')
82
+ console.log(' ' + COLORS.cyan + 'help' + COLORS.reset + ' Afficher cette aide')
83
+ console.log(' ' + COLORS.cyan + 'version' + COLORS.reset + ' Afficher la version')
84
+ console.log('')
85
+ console.log(COLORS.bright + 'OPTIONS' + COLORS.reset)
86
+ console.log(' -o, --output Dossier de sortie')
87
+ console.log(' -p, --port Port du serveur (défaut: 3000)')
88
+ console.log(' -v, --verbose Mode verbeux')
89
+ console.log('')
90
+ console.log(COLORS.bright + 'EXEMPLES' + COLORS.reset)
91
+ console.log(' ether init')
92
+ console.log(' ether build')
93
+ console.log(' ether dev')
94
+ console.log(' ether dev -p 8080')
101
95
  }
102
96
 
103
97
  function loadConfig(configPath) {
104
98
  const defaultConfig = {
105
- src: './src',
106
- out: './dist',
107
- targets: {},
108
- i18n: 'fr',
99
+ src: 'src',
100
+ out: 'dist',
109
101
  port: 3000,
110
- watch: {
111
- ignored: ['node_modules', '.git', 'dist']
112
- }
102
+ lang: 'fr'
113
103
  }
114
-
115
- const configFile = configPath || path.join(process.cwd(), 'ether.config.js')
116
104
 
117
- if (fs.existsSync(configFile)) {
118
- try {
119
- const userConfig = require(configFile)
120
- return { ...defaultConfig, ...userConfig }
121
- } catch (err) {
122
- logError(`Erreur de configuration: ${err.message}`)
123
- return defaultConfig
124
- }
125
- }
105
+ const configFile = configPath || 'ether.config.js'
106
+ const fullPath = path.resolve(process.cwd(), configFile)
126
107
 
127
- const jsonConfig = path.join(process.cwd(), 'ether.config.json')
128
- if (fs.existsSync(jsonConfig)) {
108
+ if (fs.existsSync(fullPath)) {
129
109
  try {
130
- const content = fs.readFileSync(jsonConfig, 'utf-8')
131
- const userConfig = JSON.parse(content)
132
- return { ...defaultConfig, ...userConfig }
133
- } catch (err) {
134
- logError(`Erreur de configuration: ${err.message}`)
110
+ const userConfig = require(fullPath)
111
+ return Object.assign({}, defaultConfig, userConfig)
112
+ } catch (e) {
135
113
  return defaultConfig
136
114
  }
137
115
  }
138
-
116
+
139
117
  return defaultConfig
140
118
  }
141
119
 
142
- const MIME_TYPES = {
143
- '.html': 'text/html',
144
- '.css': 'text/css',
145
- '.js': 'application/javascript',
146
- '.json': 'application/json',
147
- '.png': 'image/png',
148
- '.jpg': 'image/jpeg',
149
- '.jpeg': 'image/jpeg',
150
- '.gif': 'image/gif',
151
- '.svg': 'image/svg+xml',
152
- '.ico': 'image/x-icon',
153
- '.woff': 'font/woff',
154
- '.woff2': 'font/woff2',
155
- '.ttf': 'font/ttf',
156
- '.eot': 'application/vnd.ms-fontobject'
157
- }
158
-
159
- const LIVE_RELOAD_SCRIPT = `
160
- <script>
161
- (function() {
162
- var source = new EventSource('/__ether_live_reload');
163
- source.onmessage = function(e) {
164
- if (e.data === 'reload') {
165
- window.location.reload();
120
+ function findEthFiles(dir) {
121
+ const files = []
122
+
123
+ function scan(directory) {
124
+ const items = fs.readdirSync(directory)
125
+ for (let i = 0; i < items.length; i++) {
126
+ const item = items[i]
127
+ const fullPath = path.join(directory, item)
128
+ const stat = fs.statSync(fullPath)
129
+ if (stat.isDirectory()) {
130
+ scan(fullPath)
131
+ } else if (item.endsWith('.eth')) {
132
+ files.push(fullPath)
133
+ }
166
134
  }
167
- };
168
- source.onerror = function() {
169
- console.log('[Ether] Connexion au serveur perdue, tentative de reconnexion...');
170
- };
171
- })();
172
- </script>
173
- `
135
+ }
136
+
137
+ scan(dir)
138
+ return files
139
+ }
174
140
 
175
- function createDevServer(outDir, port) {
141
+ function startServer(outDir, port) {
176
142
  const clients = []
177
143
 
178
- const server = http.createServer((req, res) => {
179
- if (req.url === '/__ether_live_reload') {
144
+ const liveReloadScript = '<script>(function(){var es=new EventSource("/__ether_reload");es.onmessage=function(e){if(e.data==="reload")location.reload()};})();</script>'
145
+
146
+ const server = http.createServer(function(req, res) {
147
+ if (req.url === '/__ether_reload') {
180
148
  res.writeHead(200, {
181
149
  'Content-Type': 'text/event-stream',
182
150
  'Cache-Control': 'no-cache',
@@ -185,21 +153,15 @@ function createDevServer(outDir, port) {
185
153
  })
186
154
  res.write('data: connected\n\n')
187
155
  clients.push(res)
188
- req.on('close', () => {
189
- const index = clients.indexOf(res)
190
- if (index !== -1) clients.splice(index, 1)
156
+ req.on('close', function() {
157
+ const idx = clients.indexOf(res)
158
+ if (idx !== -1) clients.splice(idx, 1)
191
159
  })
192
160
  return
193
161
  }
194
162
 
195
- let filePath = path.join(outDir, req.url === '/' ? 'index.html' : req.url)
196
-
197
- if (!filePath.includes('.') && !filePath.endsWith('/')) {
198
- const htmlPath = filePath + '.html'
199
- if (fs.existsSync(htmlPath)) {
200
- filePath = htmlPath
201
- }
202
- }
163
+ const urlPath = req.url.split('?')[0]
164
+ let filePath = path.join(outDir, urlPath === '/' ? 'index.html' : urlPath)
203
165
 
204
166
  if (fs.existsSync(filePath) && fs.statSync(filePath).isDirectory()) {
205
167
  filePath = path.join(filePath, 'index.html')
@@ -207,553 +169,107 @@ function createDevServer(outDir, port) {
207
169
 
208
170
  if (!fs.existsSync(filePath)) {
209
171
  res.writeHead(404, { 'Content-Type': 'text/html' })
210
- res.end(`
211
- <!DOCTYPE html>
212
- <html>
213
- <head><title>404 - Non trouvé</title></head>
214
- <body style="font-family: system-ui; padding: 40px; text-align: center;">
215
- <h1>404</h1>
216
- <p>Fichier non trouvé: ${req.url}</p>
217
- <p style="color: #666;">Serveur Ether Dev</p>
218
- </body>
219
- </html>
220
- `)
172
+ res.end('<h1>404 - Non trouve</h1><p>' + req.url + '</p>')
221
173
  return
222
174
  }
223
175
 
224
176
  const ext = path.extname(filePath).toLowerCase()
225
- const mimeType = MIME_TYPES[ext] || 'application/octet-stream'
177
+ const mime = MIME_TYPES[ext] || 'application/octet-stream'
226
178
 
227
- fs.readFile(filePath, (err, content) => {
179
+ fs.readFile(filePath, function(err, content) {
228
180
  if (err) {
229
181
  res.writeHead(500)
230
- res.end(`Erreur serveur: ${err.message}`)
182
+ res.end('Erreur: ' + err.message)
231
183
  return
232
184
  }
233
185
 
234
186
  if (ext === '.html') {
235
187
  let html = content.toString()
236
- if (html.includes('</body>')) {
237
- html = html.replace('</body>', `${LIVE_RELOAD_SCRIPT}</body>`)
238
- } else if (html.includes('</html>')) {
239
- html = html.replace('</html>', `${LIVE_RELOAD_SCRIPT}</html>`)
188
+ if (html.indexOf('</body>') !== -1) {
189
+ html = html.replace('</body>', liveReloadScript + '</body>')
240
190
  } else {
241
- html += LIVE_RELOAD_SCRIPT
191
+ html = html + liveReloadScript
242
192
  }
243
193
  content = html
244
194
  }
245
195
 
246
- res.writeHead(200, { 'Content-Type': mimeType })
196
+ res.writeHead(200, { 'Content-Type': mime })
247
197
  res.end(content)
248
198
  })
249
199
  })
250
200
 
251
- server.listen(port, '127.0.0.1', () => {
252
- logSuccess(`Serveur démarré sur ${COLORS.cyan}http://localhost:${port}${COLORS.reset}`)
253
- })
254
-
255
- server.on('error', (err) => {
201
+ server.on('error', function(err) {
256
202
  if (err.code === 'EADDRINUSE') {
257
- logError(`Le port ${port} est déjà utilisé. Essayez: ether dev -p ${port + 1}`)
203
+ logError('Port ' + port + ' deja utilise')
258
204
  } else {
259
- logError(`Erreur serveur: ${err.message}`)
205
+ logError('Erreur serveur: ' + err.message)
260
206
  }
261
207
  process.exit(1)
262
208
  })
263
209
 
210
+ server.listen(port, function() {
211
+ logSuccess('Serveur demarre sur http://localhost:' + port)
212
+ })
213
+
264
214
  return {
265
- server,
266
- reload: () => {
267
- clients.forEach(client => {
268
- client.write('data: reload\n\n')
269
- })
270
- },
271
- close: () => {
272
- clients.forEach(client => client.end())
273
- server.close()
215
+ reload: function() {
216
+ for (let i = 0; i < clients.length; i++) {
217
+ clients[i].write('data: reload\n\n')
218
+ }
274
219
  }
275
220
  }
276
221
  }
277
222
 
278
- async function cmdInit() {
223
+ function cmdInit() {
279
224
  showBanner()
280
- logInfo('Initialisation du projet Ether...')
281
-
282
- const cwd = process.cwd()
283
-
284
- const srcDir = path.join(cwd, 'src')
285
- if (!fs.existsSync(srcDir)) {
286
- fs.mkdirSync(srcDir, { recursive: true })
287
- logSuccess('Dossier src/ créé')
288
- }
225
+ console.log('')
289
226
 
290
- const distDir = path.join(cwd, 'dist')
291
- if (!fs.existsSync(distDir)) {
292
- fs.mkdirSync(distDir, { recursive: true })
293
- logSuccess('Dossier dist/ créé')
294
- }
295
-
296
- const publicDir = path.join(cwd, 'public')
297
- if (!fs.existsSync(publicDir)) {
298
- fs.mkdirSync(publicDir, { recursive: true })
299
- logSuccess('Dossier public/ créé')
300
- }
301
-
227
+ const projectDir = process.cwd()
228
+ const srcDir = path.join(projectDir, 'src')
229
+ const distDir = path.join(projectDir, 'dist')
230
+ const publicDir = path.join(projectDir, 'public')
302
231
  const imagesDir = path.join(publicDir, 'images')
303
- if (!fs.existsSync(imagesDir)) {
304
- fs.mkdirSync(imagesDir, { recursive: true })
305
- logSuccess('Dossier public/images/ créé')
306
- }
307
-
308
232
  const videosDir = path.join(publicDir, 'videos')
309
- if (!fs.existsSync(videosDir)) {
310
- fs.mkdirSync(videosDir, { recursive: true })
311
- logSuccess('Dossier public/videos/ créé')
312
- }
313
-
314
- const projectName = path.basename(cwd)
315
- const packageJsonPath = path.join(cwd, 'package.json')
316
- if (!fs.existsSync(packageJsonPath)) {
317
- const packageJson = {
318
- name: projectName.toLowerCase().replace(/[^a-z0-9-]/g, '-'),
319
- version: '1.0.0',
320
- description: 'Projet Ether',
321
- main: 'dist/index.html',
322
- scripts: {
323
- dev: 'ether dev',
324
- build: 'ether build'
325
- },
326
- keywords: ['ether'],
327
- author: '',
328
- license: 'MIT'
329
- }
330
- fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))
331
- logSuccess('Fichier package.json créé')
332
- }
333
-
334
- const configContent = `module.exports = {
335
- src: './src',
336
- out: './dist',
337
-
338
- i18n: 'fr',
339
- port: 3000,
340
233
 
341
- targets: {
342
- css: {
343
- extension: '.css',
344
- minify: false
345
- },
346
- html: {
347
- extension: '.html',
348
- minify: false
349
- },
350
- js: {
351
- extension: '.js',
352
- minify: false
353
- }
354
- },
234
+ if (!fs.existsSync(srcDir)) fs.mkdirSync(srcDir, { recursive: true })
235
+ if (!fs.existsSync(distDir)) fs.mkdirSync(distDir, { recursive: true })
236
+ if (!fs.existsSync(publicDir)) fs.mkdirSync(publicDir, { recursive: true })
237
+ if (!fs.existsSync(imagesDir)) fs.mkdirSync(imagesDir, { recursive: true })
238
+ if (!fs.existsSync(videosDir)) fs.mkdirSync(videosDir, { recursive: true })
355
239
 
356
- watch: {
357
- ignored: ['node_modules', '.git', 'dist']
358
- }
359
- }
360
- `
361
-
362
- const configPath = path.join(cwd, 'ether.config.js')
363
- if (!fs.existsSync(configPath)) {
364
- fs.writeFileSync(configPath, configContent)
365
- logSuccess('Fichier ether.config.js créé')
366
- } else {
367
- logWarning('ether.config.js existe déjà')
368
- }
369
-
370
- const exampleHtml = `// cible: html
371
-
372
- document
373
- tete
374
- meta charset: "UTF-8"
375
- meta name: "viewport", content: "width=device-width, initial-scale=1.0"
376
- titre "Ether - Le langage intentionnel"
377
- lien rel: "stylesheet", href: "styles.css"
240
+ const configContent = 'module.exports = {\n src: "src",\n out: "dist",\n port: 3000,\n lang: "fr"\n}\n'
378
241
 
379
- corps
380
- entete classe: "hero"
381
- nav classe: "navbar"
382
- div classe: "logo"
383
- span classe: "logo-icon"
384
- "◈"
385
- span "Ether"
386
- liste-non-ordonnee classe: "nav-links"
387
- element-liste
388
- lien href: "#features"
389
- "Fonctionnalités"
390
- element-liste
391
- lien href: "#examples"
392
- "Exemples"
393
- element-liste
394
- lien href: "#docs"
395
- "Documentation"
396
-
397
- div classe: "hero-content"
398
- titre1 classe: "hero-title"
399
- "Écrivez du code"
400
- saut-ligne
401
- span classe: "gradient-text"
402
- "comme vous pensez"
403
- paragraphe classe: "hero-subtitle"
404
- "Ether est un langage intentionnel qui compile vers HTML, CSS, JavaScript et plus encore. Naturel, intuitif, puissant."
405
- div classe: "hero-buttons"
406
- lien href: "#start", classe: "btn btn-primary"
407
- "Commencer"
408
- lien href: "#learn", classe: "btn btn-secondary"
409
- "En savoir plus"
410
-
411
- principal
412
- section id: "features", classe: "features"
413
- titre2 classe: "section-title"
414
- "Pourquoi Ether ?"
415
- div classe: "features-grid"
416
- article classe: "feature-card"
417
- div classe: "feature-icon"
418
- "🎯"
419
- titre3 "Intuitif"
420
- paragraphe "Écrivez du code en langage naturel. Plus besoin de mémoriser des syntaxes complexes."
421
- article classe: "feature-card"
422
- div classe: "feature-icon"
423
- "⚡"
424
- titre3 "Rapide"
425
- paragraphe "Compilation instantanée avec rechargement automatique en mode développement."
426
- article classe: "feature-card"
427
- div classe: "feature-icon"
428
- "🌍"
429
- titre3 "Multilingue"
430
- paragraphe "Codez en français, anglais, espagnol et plus. Votre langue, votre code."
431
- article classe: "feature-card"
432
- div classe: "feature-icon"
433
- "🔧"
434
- titre3 "Flexible"
435
- paragraphe "Compile vers HTML, CSS, JS, PHP, Python, SQL et bien d'autres langages."
436
-
437
- section id: "examples", classe: "examples"
438
- titre2 classe: "section-title"
439
- "Simple et élégant"
440
- div classe: "code-comparison"
441
- div classe: "code-block"
442
- div classe: "code-header"
443
- "Ether"
444
- pre
445
- code
446
- "document\\n corps\\n titre1 \\"Bonjour\\"\\n paragraphe \\"Le monde\\""
447
- div classe: "code-arrow"
448
- "→"
449
- div classe: "code-block"
450
- div classe: "code-header"
451
- "HTML"
452
- pre
453
- code
454
- "&lt;!DOCTYPE html&gt;\\n&lt;html&gt;\\n &lt;body&gt;\\n &lt;h1&gt;Bonjour&lt;/h1&gt;\\n &lt;p&gt;Le monde&lt;/p&gt;\\n &lt;/body&gt;\\n&lt;/html&gt;"
455
-
456
- pied classe: "footer"
457
- paragraphe
458
- "Créé avec"
459
- span classe: "heart"
460
- " ♥ "
461
- "par la communauté Ether"
462
- paragraphe classe: "copyright"
463
- "© 2025 Ether. MIT License."
464
-
465
- script src: "app.js"
466
- `
467
-
468
- const exampleCss = `// cible: css
469
-
470
- racine
471
- couleur-primaire: "#6366f1"
472
- couleur-secondaire: "#8b5cf6"
473
- couleur-accent: "#06b6d4"
474
- couleur-fond: "#0f0f23"
475
- couleur-surface: "#1a1a2e"
476
- couleur-texte: "#e2e8f0"
477
- couleur-texte-pale: "#94a3b8"
478
-
479
- *
480
- marge: 0
481
- remplissage: 0
482
- modele-boite: border-box
483
-
484
- corps
485
- famille-police: "system-ui", "-apple-system", "sans-serif"
486
- couleur-fond: var(--couleur-fond)
487
- couleur: var(--couleur-texte)
488
- hauteur-ligne: 1.6
489
-
490
- .hero
491
- min-hauteur: 100vh
492
- fond: "linear-gradient(135deg, var(--couleur-fond) 0%, var(--couleur-surface) 100%)"
493
- position: relative
494
- debordement: cache
495
-
496
- .navbar
497
- affichage: flex
498
- justifier-contenu: space-between
499
- aligner-elements: center
500
- remplissage: "1.5rem 5%"
501
- position: fixed
502
- largeur: 100%
503
- haut: 0
504
- z-index: 100
505
- fond: "rgba(15, 15, 35, 0.9)"
506
- flou-fond: "10px"
507
-
508
- .logo
509
- affichage: flex
510
- aligner-elements: center
511
- espace: "0.5rem"
512
- taille-police: "1.5rem"
513
- poids-police: 700
514
-
515
- .logo-icon
516
- taille-police: "2rem"
517
- couleur: var(--couleur-primaire)
518
-
519
- .nav-links
520
- affichage: flex
521
- liste-style: none
522
- espace: "2rem"
523
-
524
- .nav-links lien
525
- couleur: var(--couleur-texte-pale)
526
- decoration-texte: none
527
- transition: "couleur 0.3s"
528
- au survol
529
- couleur: var(--couleur-primaire)
530
-
531
- .hero-content
532
- texte-aligne: center
533
- remplissage: "12rem 5% 5rem"
534
- max-largeur: "800px"
535
- marge: "0 auto"
536
-
537
- .hero-title
538
- taille-police: "3.5rem"
539
- poids-police: 800
540
- marge-bas: "1.5rem"
541
- hauteur-ligne: 1.2
542
-
543
- .gradient-text
544
- fond: "linear-gradient(90deg, var(--couleur-primaire), var(--couleur-accent))"
545
- decoupe-fond: text
546
- couleur: transparent
547
-
548
- .hero-subtitle
549
- taille-police: "1.25rem"
550
- couleur: var(--couleur-texte-pale)
551
- marge-bas: "2.5rem"
552
- max-largeur: "600px"
553
- marge-gauche: auto
554
- marge-droite: auto
555
-
556
- .hero-buttons
557
- affichage: flex
558
- espace: "1rem"
559
- justifier-contenu: center
560
-
561
- .btn
562
- remplissage: "0.875rem 2rem"
563
- rayon-bordure: "0.5rem"
564
- taille-police: "1rem"
565
- poids-police: 600
566
- decoration-texte: none
567
- transition: "transform 0.2s, box-shadow 0.2s"
568
- au survol
569
- transformation: "translateY(-2px)"
570
-
571
- .btn-primary
572
- fond: "linear-gradient(90deg, var(--couleur-primaire), var(--couleur-secondaire))"
573
- couleur: white
574
- au survol
575
- ombre-boite: "0 10px 30px rgba(99, 102, 241, 0.4)"
576
-
577
- .btn-secondary
578
- fond: transparent
579
- couleur: var(--couleur-texte)
580
- bordure: "2px solid var(--couleur-primaire)"
581
- au survol
582
- fond: "rgba(99, 102, 241, 0.1)"
583
-
584
- .features
585
- remplissage: "6rem 5%"
586
-
587
- .section-title
588
- texte-aligne: center
589
- taille-police: "2.5rem"
590
- marge-bas: "3rem"
591
-
592
- .features-grid
593
- affichage: grid
594
- colonnes-grille: "repeat(auto-fit, minmax(250px, 1fr))"
595
- espace: "2rem"
596
- max-largeur: "1200px"
597
- marge: "0 auto"
598
-
599
- .feature-card
600
- fond: var(--couleur-surface)
601
- remplissage: "2rem"
602
- rayon-bordure: "1rem"
603
- texte-aligne: center
604
- transition: "transform 0.3s"
605
- au survol
606
- transformation: "translateY(-5px)"
242
+ const indexContent = '// cible: html\n\ndocument\n tete\n meta charset: "UTF-8"\n meta name: "viewport", content: "width=device-width, initial-scale=1.0"\n titre "Mon projet Ether"\n lien rel: "stylesheet", href: "styles.css"\n corps\n entete classe: "header"\n titre1 "Bienvenue"\n principal classe: "main"\n paragraphe "Mon premier projet Ether!"\n pied classe: "footer"\n paragraphe "Cree avec Ether"\n'
607
243
 
608
- .feature-icon
609
- taille-police: "3rem"
610
- marge-bas: "1rem"
244
+ const stylesContent = '// cible: css\n\n.header\n fond: bleu\n couleur: blanc\n padding: 2rem\n texte aligne: centre\n\n.main\n padding: 2rem\n\n.footer\n fond: gris fonce\n couleur: blanc\n padding: 1rem\n texte aligne: centre\n'
611
245
 
612
- .feature-card titre3
613
- marge-bas: "0.75rem"
614
- taille-police: "1.25rem"
246
+ const appContent = '// cible: js\n\nconsole.log("Ether ready!")\n'
615
247
 
616
- .feature-card paragraphe
617
- couleur: var(--couleur-texte-pale)
248
+ const packageContent = '{\n "name": "mon-projet-ether",\n "version": "1.0.0",\n "scripts": {\n "dev": "ether dev",\n "build": "ether build"\n }\n}\n'
618
249
 
619
- .examples
620
- remplissage: "6rem 5%"
621
- fond: var(--couleur-surface)
622
-
623
- .code-comparison
624
- affichage: flex
625
- aligner-elements: center
626
- justifier-contenu: center
627
- espace: "2rem"
628
- flex-wrap: wrap
629
- max-largeur: "1000px"
630
- marge: "0 auto"
631
-
632
- .code-block
633
- fond: var(--couleur-fond)
634
- rayon-bordure: "0.75rem"
635
- debordement: cache
636
- min-largeur: "300px"
637
-
638
- .code-header
639
- fond: "rgba(99, 102, 241, 0.2)"
640
- remplissage: "0.75rem 1rem"
641
- poids-police: 600
642
- couleur: var(--couleur-primaire)
643
-
644
- .code-block pre
645
- remplissage: "1.5rem"
646
- marge: 0
647
-
648
- .code-block code
649
- famille-police: "Fira Code", "Monaco", monospace
650
- taille-police: "0.9rem"
651
- blanc: pre
652
-
653
- .code-arrow
654
- taille-police: "2rem"
655
- couleur: var(--couleur-primaire)
656
-
657
- .footer
658
- texte-aligne: center
659
- remplissage: "3rem 5%"
660
- fond: var(--couleur-fond)
661
-
662
- .heart
663
- couleur: "#ef4444"
664
-
665
- .copyright
666
- marge-haut: "0.5rem"
667
- couleur: var(--couleur-texte-pale)
668
- taille-police: "0.875rem"
669
-
670
- @media (max-largeur: 768px)
671
- .hero-title
672
- taille-police: "2.5rem"
673
- .nav-links
674
- affichage: none
675
- .code-arrow
676
- transformation: "rotate(90deg)"
677
- `
678
-
679
- const exampleJs = `// cible: js
680
-
681
- constante annee = nouveau Date().getFullYear()
682
-
683
- fonction initialiser()
684
- constante copyright = document.querySelector(".copyright")
685
- si copyright
686
- copyright.textContent = "© " + annee + " Ether. MIT License."
687
-
688
- constante liens = document.querySelectorAll("a[href^='#']")
689
- pour chaque lien dans liens
690
- lien.addEventListener "click", fonction(e)
691
- e.preventDefault()
692
- constante cible = document.querySelector(this.getAttribute("href"))
693
- si cible
694
- cible.scrollIntoView({ behavior: "smooth" })
695
-
696
- document.addEventListener "DOMContentLoaded", initialiser
697
- `
698
-
699
- const examplePath = path.join(srcDir, 'index.eth')
700
- if (!fs.existsSync(examplePath)) {
701
- fs.writeFileSync(examplePath, exampleHtml)
702
- logSuccess('Fichier src/index.eth créé')
703
- }
704
-
705
- const cssPath = path.join(srcDir, 'styles.eth')
706
- if (!fs.existsSync(cssPath)) {
707
- fs.writeFileSync(cssPath, exampleCss)
708
- logSuccess('Fichier src/styles.eth créé')
709
- }
250
+ fs.writeFileSync(path.join(projectDir, 'ether.config.js'), configContent)
251
+ fs.writeFileSync(path.join(srcDir, 'index.eth'), indexContent)
252
+ fs.writeFileSync(path.join(srcDir, 'styles.eth'), stylesContent)
253
+ fs.writeFileSync(path.join(srcDir, 'app.eth'), appContent)
254
+ fs.writeFileSync(path.join(projectDir, 'package.json'), packageContent)
710
255
 
711
- const jsPath = path.join(srcDir, 'app.eth')
712
- if (!fs.existsSync(jsPath)) {
713
- fs.writeFileSync(jsPath, exampleJs)
714
- logSuccess('Fichier src/app.eth créé')
715
- }
716
-
717
- const logoSvg = `<?xml version="1.0" encoding="UTF-8"?>
718
- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 499 500">
719
- <defs>
720
- <linearGradient id="g1" gradientUnits="userSpaceOnUse" x1="1.106" y1="250.0527" x2="498.8623" y2="250.0527">
721
- <stop offset="0" style="stop-color:#03AFC6"/><stop offset="0.5126" style="stop-color:#31BAD3"/><stop offset="1" style="stop-color:#3EC4DD"/>
722
- </linearGradient>
723
- <linearGradient id="g2" gradientUnits="userSpaceOnUse" x1="56.332" y1="250.0532" x2="470.3037" y2="250.0532">
724
- <stop offset="0" style="stop-color:#4758A7"/><stop offset="0.2597" style="stop-color:#6F53A2"/><stop offset="0.5939" style="stop-color:#924A9D"/><stop offset="0.8518" style="stop-color:#A64399"/><stop offset="1" style="stop-color:#AE4097"/>
725
- </linearGradient>
726
- <linearGradient id="g3" gradientUnits="userSpaceOnUse" x1="144.1313" y1="289.1055" x2="448.2786" y2="147.2793">
727
- <stop offset="0" style="stop-color:#5E6AB2"/><stop offset="0.1138" style="stop-color:#5A77B7"/><stop offset="0.4161" style="stop-color:#4D96C8"/><stop offset="0.6753" style="stop-color:#3DADD5"/><stop offset="0.8782" style="stop-color:#30BBDD"/><stop offset="1" style="stop-color:#24C1E1"/>
728
- </linearGradient>
729
- <linearGradient id="g4" gradientUnits="userSpaceOnUse" x1="223.2749" y1="258.8877" x2="387.1369" y2="182.4776">
730
- <stop offset="0" style="stop-color:#5E6AB2"/><stop offset="0.1138" style="stop-color:#5A77B7"/><stop offset="0.4161" style="stop-color:#4D96C8"/><stop offset="0.6753" style="stop-color:#3DADD5"/><stop offset="0.8782" style="stop-color:#30BBDD"/><stop offset="1" style="stop-color:#24C1E1"/>
731
- </linearGradient>
732
- </defs>
733
- <path fill="url(#g1)" d="M5.381,238.563c-5.468-13.48-5.838-18.365-0.256-29.006c5.582-10.641,129.113-178.821,157.852-196.679C191.716-4.979,414.415,0.938,431.034,1.795c16.621,0.856,39.463,3.869,45.858,10.234c6.395,6.365,10.242,8.502,12.175,17.908c1.932,9.406,7.304,45.665,8.664,91.185c1.362,45.521,1.822,152.92-0.505,186.578c-2.325,33.658-1.465,47.184-14.553,67.173c-13.089,19.987-218.044,111.611-232.689,117.413c-14.646,5.801-35.404,16.623-62.205-6.569C160.979,462.526,5.381,238.563,5.381,238.563z"/>
734
- <path fill="url(#g2)" d="M291.136,436.653c-7.71,3.354-52.39,24.228-61.917,23.915c-10.871-0.359-16.045-4.679-36.578-31.196C157.484,383.969,67.434,258.436,60.702,243.983c-5.766-12.377-6.472-19.474,1.826-32.931c8.299-13.456,105.229-151.605,117.666-160.906c12.648-9.458,23.041-10.032,35.5-10.188c55.329-0.694,152.766-0.725,225.992,1.368c16.294,0.466,24.063,11.799,24.653,21.583c5.707,94.576,6.6,150.435-6.481,266.374c-3.107,27.537-16.15,39.634-36.553,49.895C402.604,389.586,301.741,432.036,291.136,436.653z"/>
735
- <path fill="url(#g3)" d="M397.598,278.148c2.596,0.083,3.073,1.179,3.474,1.965c0.642,1.265,0.51,3.642-0.264,5.969c-0.545,1.638-10.225,33.388-13.646,43.11c-1.364,3.871-2.896,4.9-5.702,6.357c-2.692,1.396-132.598,52.559-143.222,56.099c-6.013,2.006-6.541,0.742-9.292-1.695c-2.749-2.437-107.08-151.266-109.972-155.301c-2.893-4.034-1.419-6.227-0.711-7.854c1.636-3.759,78.848-110.176,84.417-116.574c5.57-6.398,8.097-8.37,12.46-11.03c2.771-1.689,5.406-3.374,11.53-3.739c12.276-0.731,183.793-0.426,192.787,0.333c4.049,0.342,7.233,1.441,6.384,6.319c-0.853,4.879-9.874,46.584-8.671,43.199c1.204-3.385-1.01,5.33-8.432,5.348c-7.422,0.02-153.731,0-157.729,0.039c-6.107,0.06-6.991,0.443-7.952,1.426c-2.176,2.226-54.269,71.788-57.427,75.836c-3.157,4.048-2.247,5.316,1.448,9.065c3.695,3.748,69.606,62.824,69.606,62.824s-10.604-21.547-8.459-21.547"/>
736
- <path fill="url(#g4)" d="M213.282,235.909c14.12-20.019,28.129-36.342,31.945-40.798c5.362-6.26,5.762-5.197,8.629-5.197c2.869,0,132.714,0.003,132.714,0.003s2.916-0.469,4.863,1.864c1.029,1.235-0.298,5.654-0.298,5.654l-9.552,40.332c0,0-1.318,5.72-6.366,5.649C334.696,242.847,208.748,250.903,213.282,235.909"/>
737
- </svg>`
738
-
739
- const logoPath = path.join(imagesDir, 'Logo_Ether.svg')
740
- if (!fs.existsSync(logoPath)) {
741
- fs.writeFileSync(logoPath, logoSvg)
742
- logSuccess('Fichier public/images/Logo_Ether.svg créé')
743
- }
744
-
256
+ logSuccess('Projet initialise!')
745
257
  console.log('')
746
- logSuccess('Projet initialisé avec succès!')
747
- console.log('')
748
- logInfo('Prochaines étapes:')
749
- console.log(` 1. Lancer ${COLORS.cyan}ether dev${COLORS.reset} pour le mode développement`)
750
- console.log(` 2. Éditer les fichiers dans ${COLORS.cyan}src/${COLORS.reset}`)
258
+ logInfo('Structure creee:')
259
+ console.log(' src/index.eth')
260
+ console.log(' src/styles.eth')
261
+ console.log(' src/app.eth')
262
+ console.log(' public/images/')
263
+ console.log(' public/videos/')
264
+ console.log(' ether.config.js')
265
+ console.log(' package.json')
751
266
  console.log('')
267
+ logInfo('Commandes:')
268
+ console.log(' ether build Compiler')
269
+ console.log(' ether dev Serveur de developpement')
752
270
  }
753
271
 
754
- async function cmdBuild(options) {
755
- const startTime = Date.now()
756
-
272
+ function cmdBuild(options) {
757
273
  if (!options.quiet) {
758
274
  showBanner()
759
275
  logInfo('Compilation en cours...')
@@ -765,7 +281,7 @@ async function cmdBuild(options) {
765
281
  const outDir = path.resolve(process.cwd(), options.output || config.out)
766
282
 
767
283
  if (!fs.existsSync(srcDir)) {
768
- logError(`Dossier source introuvable: ${srcDir}`)
284
+ logError('Dossier source introuvable: ' + srcDir)
769
285
  process.exit(1)
770
286
  }
771
287
 
@@ -774,61 +290,58 @@ async function cmdBuild(options) {
774
290
  }
775
291
 
776
292
  const compiler = new EtherCompiler(config)
777
-
778
293
  const files = findEthFiles(srcDir)
779
294
 
780
295
  if (files.length === 0) {
781
- logWarning('Aucun fichier .eth trouvé')
296
+ logWarning('Aucun fichier .eth trouve')
782
297
  return
783
298
  }
784
299
 
785
300
  let successCount = 0
786
301
  let errorCount = 0
787
302
 
788
- for (const file of files) {
303
+ for (let i = 0; i < files.length; i++) {
304
+ const file = files[i]
789
305
  try {
790
306
  const relativePath = path.relative(srcDir, file)
791
- const result = await compiler.compileFile(file)
307
+ const result = compiler.compileFile(file)
792
308
 
793
- for (const output of result.outputs) {
794
- const outPath = path.join(outDir, output.path)
795
- const outDirPath = path.dirname(outPath)
796
-
797
- if (!fs.existsSync(outDirPath)) {
798
- fs.mkdirSync(outDirPath, { recursive: true })
799
- }
800
-
801
- fs.writeFileSync(outPath, output.content)
802
-
803
- if (options.verbose) {
804
- logSuccess(`${relativePath} → ${output.path}`)
309
+ if (result && result.outputs) {
310
+ for (let j = 0; j < result.outputs.length; j++) {
311
+ const output = result.outputs[j]
312
+ const outPath = path.join(outDir, output.path)
313
+ const outDirPath = path.dirname(outPath)
314
+
315
+ if (!fs.existsSync(outDirPath)) {
316
+ fs.mkdirSync(outDirPath, { recursive: true })
317
+ }
318
+
319
+ fs.writeFileSync(outPath, output.content)
320
+
321
+ if (options.verbose) {
322
+ logSuccess(relativePath + ' -> ' + output.path)
323
+ }
805
324
  }
806
325
  }
807
326
 
808
327
  successCount++
809
328
  } catch (err) {
810
329
  errorCount++
811
- logError(`${path.relative(srcDir, file)}: ${err.message}`)
812
-
813
- if (options.verbose) {
814
- console.error(err.stack)
815
- }
330
+ logError(path.relative(srcDir, file) + ': ' + err.message)
816
331
  }
817
332
  }
818
333
 
819
- const duration = Date.now() - startTime
820
-
821
334
  if (!options.quiet) {
822
335
  console.log('')
823
336
  if (errorCount === 0) {
824
- logSuccess(`${successCount} fichier(s) compilé(s) en ${duration}ms`)
337
+ logSuccess(successCount + ' fichier(s) compile(s)')
825
338
  } else {
826
- logWarning(`${successCount} succès, ${errorCount} erreur(s) en ${duration}ms`)
339
+ logWarning(successCount + ' succes, ' + errorCount + ' erreur(s)')
827
340
  }
828
341
  }
829
342
  }
830
343
 
831
- async function cmdDev(options) {
344
+ function cmdDev(options) {
832
345
  showBanner()
833
346
 
834
347
  const config = loadConfig(options.config)
@@ -837,7 +350,7 @@ async function cmdDev(options) {
837
350
  const port = options.port || config.port || 3000
838
351
 
839
352
  if (!fs.existsSync(srcDir)) {
840
- logError(`Dossier source introuvable: ${srcDir}`)
353
+ logError('Dossier source introuvable: ' + srcDir)
841
354
  process.exit(1)
842
355
  }
843
356
 
@@ -845,260 +358,112 @@ async function cmdDev(options) {
845
358
  fs.mkdirSync(outDir, { recursive: true })
846
359
  }
847
360
 
848
- logInfo(`Surveillance de ${srcDir}`)
849
- logInfo(`Sortie vers ${outDir}`)
361
+ logInfo('Surveillance de ' + srcDir)
362
+ logInfo('Sortie vers ' + outDir)
850
363
  console.log('')
851
364
 
852
- let devServer = null
853
- if (!options.noServer) {
854
- devServer = createDevServer(outDir, port)
855
- }
365
+ const devServer = startServer(outDir, port)
856
366
 
857
- console.log('')
858
367
  logInfo('Compilation initiale...')
859
-
860
- try {
861
- await cmdBuild({ ...options, quiet: true })
862
- logSuccess('Compilation terminée')
863
- } catch (err) {
864
- logWarning(`Erreur de compilation: ${err.message}`)
865
- }
866
-
867
- console.log('')
868
- logInfo('En attente de modifications... (Ctrl+C pour arrêter)')
368
+ cmdBuild(Object.assign({}, options, { quiet: true }))
369
+ logSuccess('Compilation terminee')
869
370
  console.log('')
371
+ logInfo('En attente de modifications... (Ctrl+C pour arreter)')
870
372
 
871
- const watcher = new Watcher(srcDir, config.watch)
872
373
  const compiler = new EtherCompiler(config)
374
+ const watcher = new Watcher(srcDir, config.watch)
873
375
 
874
- watcher.on('change', async (filePath) => {
875
- if (!filePath.endsWith('.eth')) return
876
-
877
- const relativePath = path.relative(srcDir, filePath)
878
- logInfo(`Modification: ${relativePath}`)
879
-
880
- try {
881
- const result = await compiler.compileFile(filePath)
882
-
883
- for (const output of result.outputs) {
884
- const outPath = path.join(outDir, output.path)
885
- const outDirPath = path.dirname(outPath)
886
-
887
- if (!fs.existsSync(outDirPath)) {
888
- fs.mkdirSync(outDirPath, { recursive: true })
889
- }
890
-
891
- fs.writeFileSync(outPath, output.content)
892
- logSuccess(`→ ${output.path}`)
893
- }
894
-
895
- if (devServer) {
896
- devServer.reload()
897
- }
898
- } catch (err) {
899
- logError(err.message)
900
- }
901
- })
902
-
903
- watcher.on('add', async (filePath) => {
376
+ watcher.on('change', function(filePath) {
904
377
  if (!filePath.endsWith('.eth')) return
905
378
 
906
379
  const relativePath = path.relative(srcDir, filePath)
907
- logInfo(`Nouveau fichier: ${relativePath}`)
380
+ logInfo('Modification: ' + relativePath)
908
381
 
909
382
  try {
910
- const result = await compiler.compileFile(filePath)
383
+ const result = compiler.compileFile(filePath)
911
384
 
912
- for (const output of result.outputs) {
913
- const outPath = path.join(outDir, output.path)
914
- const outDirPath = path.dirname(outPath)
915
-
916
- if (!fs.existsSync(outDirPath)) {
917
- fs.mkdirSync(outDirPath, { recursive: true })
385
+ if (result && result.outputs) {
386
+ for (let i = 0; i < result.outputs.length; i++) {
387
+ const output = result.outputs[i]
388
+ const outPath = path.join(outDir, output.path)
389
+ const outDirPath = path.dirname(outPath)
390
+
391
+ if (!fs.existsSync(outDirPath)) {
392
+ fs.mkdirSync(outDirPath, { recursive: true })
393
+ }
394
+
395
+ fs.writeFileSync(outPath, output.content)
396
+ logSuccess('-> ' + output.path)
918
397
  }
919
-
920
- fs.writeFileSync(outPath, output.content)
921
- logSuccess(`→ ${output.path}`)
922
398
  }
923
399
 
924
- if (devServer) {
925
- devServer.reload()
926
- }
400
+ devServer.reload()
927
401
  } catch (err) {
928
402
  logError(err.message)
929
403
  }
930
404
  })
931
405
 
932
- watcher.on('unlink', (filePath) => {
933
- if (!filePath.endsWith('.eth')) return
934
- logWarning(`Fichier supprimé: ${path.relative(srcDir, filePath)}`)
935
- })
936
-
937
406
  watcher.start()
938
-
939
- process.on('SIGINT', () => {
940
- console.log('')
941
- logInfo('Arrêt du mode développement')
942
- watcher.stop()
943
- if (devServer) {
944
- devServer.close()
945
- }
946
- process.exit(0)
947
- })
948
- }
949
-
950
- async function cmdCheck(options) {
951
- showBanner()
952
- logInfo('Vérification de la syntaxe...')
953
- console.log('')
954
-
955
- const config = loadConfig(options.config)
956
- const srcDir = path.resolve(process.cwd(), config.src)
957
-
958
- if (!fs.existsSync(srcDir)) {
959
- logError(`Dossier source introuvable: ${srcDir}`)
960
- process.exit(1)
961
- }
962
-
963
- const compiler = new EtherCompiler(config)
964
- const files = findEthFiles(srcDir)
965
-
966
- if (files.length === 0) {
967
- logWarning('Aucun fichier .eth trouvé')
968
- return
969
- }
970
-
971
- let validCount = 0
972
- let errorCount = 0
973
-
974
- for (const file of files) {
975
- const relativePath = path.relative(srcDir, file)
976
-
977
- try {
978
- await compiler.check(file)
979
- logSuccess(relativePath)
980
- validCount++
981
- } catch (err) {
982
- logError(`${relativePath}: ${err.message}`)
983
- errorCount++
984
- }
985
- }
986
-
987
- console.log('')
988
- if (errorCount === 0) {
989
- logSuccess(`${validCount} fichier(s) valide(s)`)
990
- } else {
991
- logError(`${errorCount} erreur(s) sur ${files.length} fichier(s)`)
992
- process.exit(1)
993
- }
994
- }
995
-
996
- function findEthFiles(dir) {
997
- const files = []
998
-
999
- function scan(currentDir) {
1000
- const entries = fs.readdirSync(currentDir, { withFileTypes: true })
1001
-
1002
- for (const entry of entries) {
1003
- const fullPath = path.join(currentDir, entry.name)
1004
-
1005
- if (entry.isDirectory()) {
1006
- if (!['node_modules', '.git', 'dist'].includes(entry.name)) {
1007
- scan(fullPath)
1008
- }
1009
- } else if (entry.name.endsWith('.eth')) {
1010
- files.push(fullPath)
1011
- }
1012
- }
1013
- }
1014
-
1015
- scan(dir)
1016
- return files
1017
407
  }
1018
408
 
1019
409
  function parseArgs(args) {
1020
- const options = {
1021
- command: null,
1022
- config: null,
1023
- output: null,
1024
- port: null,
1025
- verbose: false,
1026
- quiet: false,
1027
- watch: false,
1028
- noServer: false
1029
- }
410
+ const options = {}
411
+ let command = null
1030
412
 
1031
- let i = 0
1032
- while (i < args.length) {
413
+ for (let i = 0; i < args.length; i++) {
1033
414
  const arg = args[i]
1034
415
 
1035
- if (arg === '-c' || arg === '--config') {
1036
- options.config = args[++i]
416
+ if (arg === '-p' || arg === '--port') {
417
+ options.port = parseInt(args[++i], 10)
1037
418
  } else if (arg === '-o' || arg === '--output') {
1038
419
  options.output = args[++i]
1039
- } else if (arg === '-p' || arg === '--port') {
1040
- options.port = parseInt(args[++i], 10)
420
+ } else if (arg === '-c' || arg === '--config') {
421
+ options.config = args[++i]
1041
422
  } else if (arg === '-v' || arg === '--verbose') {
1042
423
  options.verbose = true
1043
424
  } else if (arg === '-q' || arg === '--quiet') {
1044
425
  options.quiet = true
1045
- } else if (arg === '-w' || arg === '--watch') {
1046
- options.watch = true
1047
- } else if (arg === '--no-color') {
1048
- for (const key in COLORS) {
1049
- COLORS[key] = ''
1050
- }
1051
- } else if (arg === '--no-server') {
1052
- options.noServer = true
1053
- } else if (!arg.startsWith('-')) {
1054
- if (!options.command) {
1055
- options.command = arg
1056
- }
426
+ } else if (!arg.startsWith('-') && !command) {
427
+ command = arg
1057
428
  }
1058
-
1059
- i++
1060
429
  }
1061
430
 
1062
- return options
431
+ return { command: command, options: options }
1063
432
  }
1064
433
 
1065
- async function main() {
434
+ function main() {
1066
435
  const args = process.argv.slice(2)
1067
- const options = parseArgs(args)
436
+ const parsed = parseArgs(args)
437
+ const command = parsed.command
438
+ const options = parsed.options
439
+
440
+ if (!command || command === 'help' || command === '--help' || command === '-h') {
441
+ showHelp()
442
+ return
443
+ }
444
+
445
+ if (command === 'version' || command === '--version' || command === '-V') {
446
+ console.log('Ether v' + VERSION)
447
+ return
448
+ }
449
+
450
+ if (command === 'init') {
451
+ cmdInit()
452
+ return
453
+ }
1068
454
 
1069
- if (options.watch && !options.command) {
1070
- options.command = 'dev'
455
+ if (command === 'build') {
456
+ cmdBuild(options)
457
+ return
1071
458
  }
1072
459
 
1073
- switch (options.command) {
1074
- case 'init':
1075
- await cmdInit()
1076
- break
1077
- case 'build':
1078
- await cmdBuild(options)
1079
- break
1080
- case 'dev':
1081
- case 'watch':
1082
- await cmdDev(options)
1083
- break
1084
- case 'check':
1085
- await cmdCheck(options)
1086
- break
1087
- case 'version':
1088
- case '-V':
1089
- case '--version':
1090
- showVersion()
1091
- break
1092
- case 'help':
1093
- case '-h':
1094
- case '--help':
1095
- default:
1096
- showHelp()
1097
- break
460
+ if (command === 'dev' || command === 'watch') {
461
+ cmdDev(options)
462
+ return
1098
463
  }
464
+
465
+ logError('Commande inconnue: ' + command)
466
+ console.log('Tapez "ether help" pour voir les commandes disponibles')
1099
467
  }
1100
468
 
1101
- main().catch(err => {
1102
- logError(err.message)
1103
- process.exit(1)
1104
- })
469
+ main()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ether-code",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "description": "Ether - Le langage intentionnel",
5
5
  "main": "cli/compiler.js",
6
6
  "bin": {