vantuz 3.3.3 β†’ 3.3.5

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 (3) hide show
  1. package/cli.js +169 -169
  2. package/config.js +686 -0
  3. package/package.json +88 -87
package/cli.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  /**
4
4
  * πŸ™ VANTUZ CLI v3.2
@@ -72,46 +72,46 @@ function saveConfigJson(config) {
72
72
  }
73
73
  }
74
74
 
75
- function clearScreen() {
76
- process.stdout.write('\x1Bc');
77
- }
78
-
79
- async function promptInput(question) {
80
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
81
- const answer = await new Promise(resolve => rl.question(question, resolve));
82
- rl.close();
83
- return answer.trim();
84
- }
85
-
86
- function normalizePhone(input) {
87
- if (!input) return '';
88
- const cleaned = input.replace(/[\s-]/g, '');
89
- return cleaned.startsWith('+') ? cleaned : `+${cleaned}`;
90
- }
91
-
92
- function loadOpenclawConfig(configPath) {
93
- try {
94
- if (fs.existsSync(configPath)) {
95
- return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
96
- }
97
- } catch (e) {
98
- console.log(c('red', `Gateway config okunamadΔ±: ${e.message}`));
99
- }
100
- return {};
101
- }
102
-
103
- function saveOpenclawConfig(configPath, config) {
104
- try {
105
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
106
- return true;
107
- } catch (e) {
108
- console.log(c('red', `Gateway config yazΔ±lamadΔ±: ${e.message}`));
109
- return false;
110
- }
111
- }
112
-
75
+ function clearScreen() {
76
+ process.stdout.write('\x1Bc');
77
+ }
78
+
79
+ async function promptInput(question) {
80
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
81
+ const answer = await new Promise(resolve => rl.question(question, resolve));
82
+ rl.close();
83
+ return answer.trim();
84
+ }
85
+
86
+ function normalizePhone(input) {
87
+ if (!input) return '';
88
+ const cleaned = input.replace(/[\s-]/g, '');
89
+ return cleaned.startsWith('+') ? cleaned : `+${cleaned}`;
90
+ }
91
+
92
+ function loadOpenclawConfig(configPath) {
93
+ try {
94
+ if (fs.existsSync(configPath)) {
95
+ return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
96
+ }
97
+ } catch (e) {
98
+ console.log(c('red', `Gateway config okunamadΔ±: ${e.message}`));
99
+ }
100
+ return {};
101
+ }
102
+
103
+ function saveOpenclawConfig(configPath, config) {
104
+ try {
105
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
106
+ return true;
107
+ } catch (e) {
108
+ console.log(c('red', `Gateway config yazΔ±lamadΔ±: ${e.message}`));
109
+ return false;
110
+ }
111
+ }
112
+
113
113
  function printHeader() {
114
- const version = JSON.parse(fs.readFileSync(new URL('./package.json', import.meta.url))).version;
114
+ const version = JSON.parse(fs.readFileSync(new URL('./package.json', import.meta.url), 'utf-8')).version;
115
115
  console.log(c('cyan', `
116
116
  β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
117
117
  β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ•β•β–ˆβ–ˆβ–ˆβ•”β•
@@ -121,7 +121,7 @@ function printHeader() {
121
121
  β•šβ•β•β•β• β•šβ•β• β•šβ•β•β•šβ•β• β•šβ•β•β•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β•β•β•β•β•β•
122
122
  `));
123
123
  console.log(c('magenta', ` Enterprise E-Commerce Management System v${version}`));
124
- console.log(c('dim', ' Powered by Vantuz Gateway'));
124
+ console.log(c('dim', ' Powered by nca'));
125
125
  console.log(c('dim', ' ----------------------------------------------------------\n'));
126
126
  }
127
127
 
@@ -141,7 +141,7 @@ async function showSpinner(text, duration = 1000) {
141
141
  // COMMANDS
142
142
  // ═══════════════════════════════════════════════════════════════════════════
143
143
 
144
- async function runTUI() {
144
+ async function runTUI() {
145
145
  clearScreen();
146
146
  printHeader();
147
147
 
@@ -161,7 +161,7 @@ async function runTUI() {
161
161
 
162
162
  console.log(`${c('green', '●')} Sistem Aktif ${c('dim', `(${status.connectedCount}/${status.totalPlatforms} Platform BağlΔ±)`)}`);
163
163
  console.log(`${c('blue', 'β„Ή')} AI SağlayΔ±cΔ±: ${c('bold', status.aiProvider || 'Gemini')}`);
164
- console.log(`${c('yellow', '⚑')} Komutlar: ${c('cyan', '/stok, /siparis, /rapor, /analiz, /durum, /temizle, /exit')}\n`);
164
+ console.log(`${c('yellow', '⚑')} Komutlar: ${c('cyan', '/stok, /siparis, /rapor, /analiz, /durum, /temizle, /exit')}\n`);
165
165
 
166
166
  const rl = readline.createInterface({
167
167
  input: process.stdin,
@@ -194,42 +194,42 @@ async function runTUI() {
194
194
  console.log(` ${c('cyan', '/temizle')} - EkranΔ± temizler`);
195
195
  console.log(` ${c('cyan', '/exit')} - Γ‡Δ±kış\n`);
196
196
  break;
197
- case '/stok':
198
- console.log(c('dim', 'Stok verileri Γ§ekiliyor...'));
199
- const stocks = await engine.getStock();
200
- if (stocks.length === 0) console.log(c('yellow', 'Bağlı platform bulunamadı.'));
201
- stocks.forEach(s => {
202
- console.log(`\n${s.icon} ${c('bold', s.platform.toUpperCase())}`);
203
- s.products.slice(0, 5).forEach(p => {
204
- console.log(` - ${p.title}: ${c('green', p.stock)} Adet | ${c('yellow', p.price)} TL`);
205
- });
206
- });
207
- break;
208
- case '/analiz':
209
- process.stdout.write(c('dim', 'Analiz hazΔ±rlanΔ±yor... '));
210
- const analysis = await engine.chat('satış ve stok analiz raporu hazırla');
211
- process.stdout.write('\r' + ' '.repeat(30) + '\r');
212
- console.log(`\n${analysis}\n`);
213
- break;
214
- case '/siparis':
215
- console.log(c('dim', 'Siparişler çekiliyor...'));
216
- const orders = await engine.getOrders({ size: 50, allStatuses: true });
217
- const activeOrders = Array.isArray(orders)
218
- ? orders.filter(o => ['Created', 'Picking', 'UnPacked'].includes(String(o.status || o.shipmentPackageStatus || o.orderStatus)))
219
- : [];
220
- const visible = activeOrders.slice(0, 5);
221
- if (!Array.isArray(orders) || visible.length === 0) {
222
- console.log(c('yellow', 'Son sipariş bulunamadı.'));
223
- break;
224
- }
225
- visible.forEach(o => {
226
- const names = Array.isArray(o.lines)
227
- ? o.lines.map(l => l?.productName || l?.name).filter(Boolean)
228
- : [];
229
- const namePart = names.length > 0 ? ` | ${names.join(', ')}` : '';
230
- console.log(`${o._icon} [#${o.orderNumber || o.id}] ${c('bold', o.customerName || 'Müşteri')}: ${c('green', o.totalPrice ?? o.totalAmount ?? o.total ?? 'β€”')} TL (${o._platform})${namePart}`);
231
- });
232
- break;
197
+ case '/stok':
198
+ console.log(c('dim', 'Stok verileri Γ§ekiliyor...'));
199
+ const stocks = await engine.getStock();
200
+ if (stocks.length === 0) console.log(c('yellow', 'Bağlı platform bulunamadı.'));
201
+ stocks.forEach(s => {
202
+ console.log(`\n${s.icon} ${c('bold', s.platform.toUpperCase())}`);
203
+ s.products.slice(0, 5).forEach(p => {
204
+ console.log(` - ${p.title}: ${c('green', p.stock)} Adet | ${c('yellow', p.price)} TL`);
205
+ });
206
+ });
207
+ break;
208
+ case '/analiz':
209
+ process.stdout.write(c('dim', 'Analiz hazΔ±rlanΔ±yor... '));
210
+ const analysis = await engine.chat('satış ve stok analiz raporu hazırla');
211
+ process.stdout.write('\r' + ' '.repeat(30) + '\r');
212
+ console.log(`\n${analysis}\n`);
213
+ break;
214
+ case '/siparis':
215
+ console.log(c('dim', 'Siparişler çekiliyor...'));
216
+ const orders = await engine.getOrders({ size: 50, allStatuses: true });
217
+ const activeOrders = Array.isArray(orders)
218
+ ? orders.filter(o => ['Created', 'Picking', 'UnPacked'].includes(String(o.status || o.shipmentPackageStatus || o.orderStatus)))
219
+ : [];
220
+ const visible = activeOrders.slice(0, 5);
221
+ if (!Array.isArray(orders) || visible.length === 0) {
222
+ console.log(c('yellow', 'Son sipariş bulunamadı.'));
223
+ break;
224
+ }
225
+ visible.forEach(o => {
226
+ const names = Array.isArray(o.lines)
227
+ ? o.lines.map(l => l?.productName || l?.name).filter(Boolean)
228
+ : [];
229
+ const namePart = names.length > 0 ? ` | ${names.join(', ')}` : '';
230
+ console.log(`${o._icon} [#${o.orderNumber || o.id}] ${c('bold', o.customerName || 'Müşteri')}: ${c('green', o.totalPrice ?? o.totalAmount ?? o.total ?? 'β€”')} TL (${o._platform})${namePart}`);
231
+ });
232
+ break;
233
233
  case '/durum':
234
234
  const s = engine.getStatus();
235
235
  console.log(c('yellow', '\n── Sistem Durumu ──'));
@@ -242,12 +242,12 @@ async function runTUI() {
242
242
  default:
243
243
  console.log(c('red', `[HATA] Bilinmeyen komut: ${cmd}. /help yazΔ±n.`));
244
244
  }
245
- } else {
246
- process.stdout.write(c('dim', 'Düşünüyor... '));
247
- const response = await engine.handleMessage(input, { channel: 'local', from: 'local' });
248
- process.stdout.write('\r' + ' '.repeat(20) + '\r');
249
- console.log(`\n${c('cyan', 'πŸ™ Vantuz:')}\n${response}\n`);
250
- }
245
+ } else {
246
+ process.stdout.write(c('dim', 'Düşünüyor... '));
247
+ const response = await engine.handleMessage(input, { channel: 'local', from: 'local' });
248
+ process.stdout.write('\r' + ' '.repeat(20) + '\r');
249
+ console.log(`\n${c('cyan', 'πŸ™ Vantuz:')}\n${response}\n`);
250
+ }
251
251
  } catch (e) {
252
252
  console.log(c('red', `\n[HATA] ${e.message}`));
253
253
  }
@@ -324,7 +324,7 @@ async function runLogs(args) {
324
324
  console.log(getLogs(n));
325
325
  }
326
326
 
327
- async function runGateway(args) {
327
+ async function runGateway(args) {
328
328
  const sub = args[1]?.toLowerCase();
329
329
  const gw = await getGateway();
330
330
  const info = gw.getInfo();
@@ -340,8 +340,8 @@ async function runGateway(args) {
340
340
  console.log('');
341
341
 
342
342
  if (!info.connected) {
343
- console.log(c('dim', ' Gateway başlatmak için: vantuz gateway run'));
344
- console.log(c('dim', ' Veya: start.bat\n'));
343
+ console.log(c('dim', ' Gateway başlatmak için: vantuz gateway run'));
344
+ console.log(c('dim', ' Veya: start.bat\n'));
345
345
  }
346
346
  return;
347
347
  }
@@ -375,18 +375,18 @@ async function runGateway(args) {
375
375
  return;
376
376
  }
377
377
 
378
- if (sub === 'run' || sub === 'start') {
379
- console.log(c('cyan', 'Gateway başlatılıyor...'));
380
- const result = await gw.start();
381
- if (result.success) {
382
- console.log(c('green', 'βœ” Gateway arka planda başlatΔ±ldΔ±.'));
383
- console.log(c('dim', 'BirkaΓ§ saniye iΓ§inde hazΔ±r olacak.'));
384
- console.log(c('dim', 'Kontrol iΓ§in: vantuz gateway status'));
385
- } else {
386
- console.log(c('red', result.error || 'Gateway başlatılamadı'));
387
- }
388
- return;
389
- }
378
+ if (sub === 'run' || sub === 'start') {
379
+ console.log(c('cyan', 'Gateway başlatılıyor...'));
380
+ const result = await gw.start();
381
+ if (result.success) {
382
+ console.log(c('green', 'βœ” Gateway arka planda başlatΔ±ldΔ±.'));
383
+ console.log(c('dim', 'BirkaΓ§ saniye iΓ§inde hazΔ±r olacak.'));
384
+ console.log(c('dim', 'Kontrol iΓ§in: vantuz gateway status'));
385
+ } else {
386
+ console.log(c('red', result.error || 'Gateway başlatılamadı'));
387
+ }
388
+ return;
389
+ }
390
390
 
391
391
  console.log(c('red', 'KullanΔ±m: vantuz gateway [status|health|models|run]'));
392
392
  }
@@ -436,72 +436,72 @@ async function runDoctor() {
436
436
  console.log('');
437
437
  }
438
438
 
439
- async function runChannels(args) {
440
- const sub = args[1]?.toLowerCase();
441
- if (sub === 'login') {
442
- printHeader();
443
- console.log(c('yellow', '── WhatsApp Login ──\n'));
444
-
445
- const openclawDir = path.join(os.homedir(), '.openclaw');
446
- const configPath = path.join(openclawDir, 'openclaw.json');
447
-
448
- if (!fs.existsSync(openclawDir)) {
449
- fs.mkdirSync(openclawDir, { recursive: true });
450
- }
451
-
452
- const rawPhone = await promptInput('WhatsApp numaranΔ±z (E.164, ΓΆrn: +905551112233): ');
453
- const phone = normalizePhone(rawPhone);
454
- if (!phone || phone === '+') {
455
- console.log(c('red', 'GeΓ§erli bir numara girilmedi.'));
456
- process.exitCode = 2;
457
- return;
458
- }
459
-
460
- const config = loadOpenclawConfig(configPath);
461
- if (!config.channels) config.channels = {};
462
- if (!config.channels.whatsapp) config.channels.whatsapp = {};
463
-
464
- if (!config.channels.whatsapp.dmPolicy) {
465
- config.channels.whatsapp.dmPolicy = 'allowlist';
466
- }
467
-
468
- const allowFrom = Array.isArray(config.channels.whatsapp.allowFrom)
469
- ? config.channels.whatsapp.allowFrom
470
- : [];
471
- if (!allowFrom.includes(phone)) {
472
- allowFrom.push(phone);
473
- }
474
- config.channels.whatsapp.allowFrom = allowFrom;
475
-
476
- const saved = saveOpenclawConfig(configPath, config);
477
- if (!saved) {
478
- process.exitCode = 1;
479
- return;
480
- }
481
-
482
- console.log(c('green', 'βœ” Gateway config gΓΌncellendi.'));
483
- console.log(c('dim', 'Şimdi QR için login başlatılıyor...\n'));
484
-
485
- try {
486
- const { spawn } = await import('child_process');
487
- const child = spawn('openclaw', ['channels', 'login'], {
488
- stdio: 'inherit',
489
- shell: true
490
- });
491
- await new Promise((resolve, reject) => {
492
- child.on('exit', code => (code === 0 ? resolve() : reject(new Error(`gateway exit ${code}`))));
493
- child.on('error', reject);
494
- });
495
- console.log(c('green', '\nβœ” QR eşleştirme tamamlandΔ±.'));
496
- console.log(c('dim', 'Gateway başlatmak için: vantuz gateway run'));
497
- } catch (e) {
498
- console.log(c('red', `Login çalıştırılamadı: ${e.message}`));
499
- }
500
- return;
501
- }
502
-
503
- printHeader();
504
- console.log(c('yellow', '── Δ°letişim KanallarΔ± ──\n'));
439
+ async function runChannels(args) {
440
+ const sub = args[1]?.toLowerCase();
441
+ if (sub === 'login') {
442
+ printHeader();
443
+ console.log(c('yellow', '── WhatsApp Login ──\n'));
444
+
445
+ const openclawDir = path.join(os.homedir(), '.openclaw');
446
+ const configPath = path.join(openclawDir, 'openclaw.json');
447
+
448
+ if (!fs.existsSync(openclawDir)) {
449
+ fs.mkdirSync(openclawDir, { recursive: true });
450
+ }
451
+
452
+ const rawPhone = await promptInput('WhatsApp numaranΔ±z (E.164, ΓΆrn: +905551112233): ');
453
+ const phone = normalizePhone(rawPhone);
454
+ if (!phone || phone === '+') {
455
+ console.log(c('red', 'GeΓ§erli bir numara girilmedi.'));
456
+ process.exitCode = 2;
457
+ return;
458
+ }
459
+
460
+ const config = loadOpenclawConfig(configPath);
461
+ if (!config.channels) config.channels = {};
462
+ if (!config.channels.whatsapp) config.channels.whatsapp = {};
463
+
464
+ if (!config.channels.whatsapp.dmPolicy) {
465
+ config.channels.whatsapp.dmPolicy = 'allowlist';
466
+ }
467
+
468
+ const allowFrom = Array.isArray(config.channels.whatsapp.allowFrom)
469
+ ? config.channels.whatsapp.allowFrom
470
+ : [];
471
+ if (!allowFrom.includes(phone)) {
472
+ allowFrom.push(phone);
473
+ }
474
+ config.channels.whatsapp.allowFrom = allowFrom;
475
+
476
+ const saved = saveOpenclawConfig(configPath, config);
477
+ if (!saved) {
478
+ process.exitCode = 1;
479
+ return;
480
+ }
481
+
482
+ console.log(c('green', 'βœ” Gateway config gΓΌncellendi.'));
483
+ console.log(c('dim', 'Şimdi QR için login başlatılıyor...\n'));
484
+
485
+ try {
486
+ const { spawn } = await import('child_process');
487
+ const child = spawn('openclaw', ['channels', 'login'], {
488
+ stdio: 'inherit',
489
+ shell: true
490
+ });
491
+ await new Promise((resolve, reject) => {
492
+ child.on('exit', code => (code === 0 ? resolve() : reject(new Error(`gateway exit ${code}`))));
493
+ child.on('error', reject);
494
+ });
495
+ console.log(c('green', '\nβœ” QR eşleştirme tamamlandΔ±.'));
496
+ console.log(c('dim', 'Gateway başlatmak için: vantuz gateway run'));
497
+ } catch (e) {
498
+ console.log(c('red', `Login çalıştırılamadı: ${e.message}`));
499
+ }
500
+ return;
501
+ }
502
+
503
+ printHeader();
504
+ console.log(c('yellow', '── Δ°letişim KanallarΔ± ──\n'));
505
505
 
506
506
  const engine = await getEngine();
507
507
  const status = engine.getStatus();
@@ -573,9 +573,9 @@ async function main() {
573
573
  console.log(` ${c('cyan', 'vantuz status')} - Durum kontrolΓΌ`);
574
574
  console.log(` ${c('cyan', 'vantuz gateway')} - Gateway yΓΆnetimi`);
575
575
  console.log(` ${c('cyan', 'vantuz doctor')} - Sistem sağlΔ±k kontrolΓΌ`);
576
- console.log(` ${c('cyan', 'vantuz channels')} - İletişim kanalları`);
577
- console.log(` ${c('cyan', 'vantuz channels login')} - WhatsApp QR login`);
578
- console.log(` ${c('cyan', 'vantuz config')} - AyarlarΔ± gΓΆster/gΓΌncelle`);
576
+ console.log(` ${c('cyan', 'vantuz channels')} - İletişim kanalları`);
577
+ console.log(` ${c('cyan', 'vantuz channels login')} - WhatsApp QR login`);
578
+ console.log(` ${c('cyan', 'vantuz config')} - AyarlarΔ± gΓΆster/gΓΌncelle`);
579
579
  console.log(` ${c('cyan', 'vantuz logs')} - LoglarΔ± gΓΆster`);
580
580
  console.log(`\nKurulum ve başlangΔ±Γ§ ayarlarΔ± iΓ§in: ${c('cyan', 'vantuz config init')}`);
581
581
  process.exitCode = command ? 2 : 0;
package/config.js ADDED
@@ -0,0 +1,686 @@
1
+
2
+
3
+ /**
4
+ * VANTUZ - Profesyonel Kurulum SihirbazΔ±
5
+ * v3.2.7 - Gateway Entegrasyonlu
6
+ */
7
+
8
+ import fs from 'fs';
9
+ import path from 'path';
10
+ import os from 'os';
11
+ import readline from 'readline';
12
+ import { fileURLToPath, pathToFileURL } from 'url';
13
+ import { PROVIDER_CONFIG } from './core/ai-provider.js'; // Import PROVIDER_CONFIG
14
+
15
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
16
+ const VANTUZ_HOME = path.join(os.homedir(), '.vantuz');
17
+ const CONFIG_PATH = path.join(VANTUZ_HOME, '.env');
18
+
19
+ // Enhanced Colors with background support
20
+ const colors = {
21
+ reset: '\x1b[0m',
22
+ bold: '\x1b[1m',
23
+ dim: '\x1b[2m',
24
+ italic: '\x1b[3m',
25
+ underscore: '\x1b[4m',
26
+
27
+ // Foreground colors
28
+ black: '\x1b[30m',
29
+ red: '\x1b[31m',
30
+ green: '\x1b[32m',
31
+ yellow: '\x1b[33m',
32
+ blue: '\x1b[34m',
33
+ magenta: '\x1b[35m',
34
+ cyan: '\x1b[36m',
35
+ white: '\x1b[37m',
36
+
37
+ // Bright foreground colors
38
+ brightBlack: '\x1b[90m',
39
+ brightRed: '\x1b[91m',
40
+ brightGreen: '\x1b[92m',
41
+ brightYellow: '\x1b[93m',
42
+ brightBlue: '\x1b[94m',
43
+ brightMagenta: '\x1b[95m',
44
+ brightCyan: '\x1b[96m',
45
+ brightWhite: '\x1b[97m',
46
+
47
+ // Background colors
48
+ bgBlack: '\x1b[40m',
49
+ bgRed: '\x1b[41m',
50
+ bgGreen: '\x1b[42m',
51
+ bgYellow: '\x1b[43m',
52
+ bgBlue: '\x1b[44m',
53
+ bgMagenta: '\x1b[45m',
54
+ bgCyan: '\x1b[46m',
55
+ bgWhite: '\x1b[47m'
56
+ };
57
+
58
+ const c = (color, text) => `${colors[color]}${text}${colors.reset}`;
59
+ const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
60
+
61
+ // Enhanced box drawing characters
62
+ const box = {
63
+ topLeft: 'β•”',
64
+ topRight: 'β•—',
65
+ bottomLeft: 'β•š',
66
+ bottomRight: '╝',
67
+ horizontal: '═',
68
+ vertical: 'β•‘',
69
+ leftT: 'β• ',
70
+ rightT: 'β•£',
71
+ topT: '╦',
72
+ bottomT: 'β•©',
73
+ cross: '╬'
74
+ };
75
+
76
+ const LOGO = `
77
+ ${colors.cyan}${colors.bold}
78
+ ╦ ╦╔═╗╔╗╔╔╦╗╦ ╦╔═╗ ╔═╗╦
79
+ β•šβ•—β•”β•β• β•β•£β•‘β•‘β•‘ β•‘ β•‘ ║╔═╝ ╠═╣║
80
+ β•šβ• β•© β•©β•β•šβ• β•© β•šβ•β•β•šβ•β• β•© β•©β•©
81
+ ${colors.reset}
82
+ ${colors.brightCyan} Enterprise E-Ticaret YΓΆnetimi${colors.reset}
83
+ `;
84
+
85
+ const createBox = (title, content, width = 65) => {
86
+ const lines = content.split('\n');
87
+ let result = '';
88
+
89
+ // Top border with title
90
+ result += c('brightCyan', box.topLeft + box.horizontal.repeat(3));
91
+ result += c('bold', ` ${title} `);
92
+ result += c('brightCyan', box.horizontal.repeat(width - title.length - 5) + box.topRight) + '\n';
93
+
94
+ // Content
95
+ lines.forEach(line => {
96
+ const padding = ' '.repeat(Math.max(0, width - line.length - 2));
97
+ result += c('brightCyan', box.vertical) + ' ' + line + padding + ' ' + c('brightCyan', box.vertical) + '\n';
98
+ });
99
+
100
+ // Bottom border
101
+ result += c('brightCyan', box.bottomLeft + box.horizontal.repeat(width) + box.bottomRight) + '\n';
102
+
103
+ return result;
104
+ };
105
+
106
+ const WELCOME_BOX = createBox('HOŞ GELDİNİZ', `
107
+ Bu sihirbaz kurulumu tamamlamanΔ±za yardΔ±mcΔ± olacak:
108
+
109
+ ${c('brightGreen', 'βœ“')} AI Servis SeΓ§imi
110
+ ${c('brightGreen', 'βœ“')} Pazaryeri BağlantΔ±larΔ±
111
+ ${c('brightGreen', 'βœ“')} Δ°letişim KanallarΔ±
112
+ ${c('brightGreen', 'βœ“')} Gateway YapΔ±landΔ±rmasΔ±
113
+ `);
114
+
115
+ class Configurator {
116
+ constructor() {
117
+ this.envVars = Configurator.loadEnvFile();
118
+ this.step = 0;
119
+ this.rl = readline.createInterface({
120
+ input: process.stdin,
121
+ output: process.stdout,
122
+ crlfDelay: Infinity
123
+ });
124
+ this.platforms = []; // Initialize platforms array
125
+ }
126
+
127
+ async _loadPlatformMetadata() {
128
+ const platformFiles = await fs.promises.readdir(path.join(__dirname, 'platforms'));
129
+ const dynamicPlatforms = [];
130
+
131
+ for (const file of platformFiles) {
132
+ if (file.endsWith('.js') && !file.startsWith('_')) { // Exclude helper files
133
+ const platformPath = path.join(__dirname, 'platforms', file);
134
+ try {
135
+ // Dynamic import for ES Modules
136
+ const platformModule = await import(pathToFileURL(platformPath).href);
137
+ // Check if module.exports is present (CommonJS) or default export (ESM)
138
+ const platform = platformModule.default || platformModule;
139
+
140
+ if (platform.name && platform.requiredFields) {
141
+ dynamicPlatforms.push({
142
+ id: file.replace('.js', ''),
143
+ name: platform.name,
144
+ icon: platform.icon || 'πŸ›’', // Default icon if not specified
145
+ description: platform.description || '',
146
+ requiredFields: platform.requiredFields
147
+ });
148
+ }
149
+ } catch (error) {
150
+ console.warn(this.warningMessage(`Platform dosyasını yüklerken hata oluştu: ${file} - ${error.message}`));
151
+ }
152
+ }
153
+ }
154
+ // Sort platforms alphabetically by name
155
+ this.platforms = dynamicPlatforms.sort((a, b) => a.name.localeCompare(b.name));
156
+ }
157
+
158
+ static loadEnvFile() {
159
+ const env = {};
160
+ try {
161
+ if (fs.existsSync(CONFIG_PATH)) {
162
+ const content = fs.readFileSync(CONFIG_PATH, 'utf-8');
163
+ content.split('\n').forEach(line => {
164
+ const match = line.match(/^([^=]+)=(.*)$/);
165
+ if (match) env[match[1].trim()] = match[2].trim();
166
+ });
167
+ }
168
+ } catch (e) {
169
+ console.error(c('red', `βœ— Config yΓΌkleme hatasΔ±: ${e.message}`));
170
+ }
171
+ return env;
172
+ }
173
+
174
+ async step_EIAConfig() {
175
+ this.printHeader('E-TΔ°CARET YΓ–NETΔ°M AJANSI (EIA) YAPILANDIRMASI', 'πŸ“Š');
176
+
177
+ console.log(c('brightWhite', 'EIA\'nın e-ticaret operasyonlarınızı optimize etmesi için kritik bilgiler sağlayın.\n'));
178
+ console.log(this.infoMessage('Bu bilgiler, EIA\'nΔ±n pazar analizi ve stratejik kararlarΔ±nda kullanΔ±lacaktΔ±r.'));
179
+
180
+ await sleep(200);
181
+
182
+ const currentCompetitorUrls = this.envVars.EIA_COMPETITOR_URLS || '';
183
+ console.log(this.createInputBox('Rakip ÜrΓΌn URL\'leri', 'VirgΓΌlle ayΔ±rarak birden fazla rakip ΓΌrΓΌn veya kategori URL\'si girebilirsiniz. (Γ–rn: https://rakip.com/urun1, https://rakip.com/kategori)'));
184
+ const competitorUrls = await this.prompt('', currentCompetitorUrls);
185
+
186
+ // Basic validation for URLs
187
+ const urls = competitorUrls.split(',').map(url => url.trim()).filter(url => url !== '');
188
+ const invalidUrls = urls.filter(url => url && (!url.startsWith('http://') && !url.startsWith('https://')));
189
+
190
+ if (competitorUrls && invalidUrls.length === 0) {
191
+ this.envVars.EIA_COMPETITOR_URLS = competitorUrls.trim();
192
+ console.log(this.successMessage('Rakip URL\'leri kaydedildi/gΓΌncellendi. EIA, bu kaynaklarΔ± izleyecektir.'));
193
+ } else if (competitorUrls && invalidUrls.length > 0) {
194
+ console.log(this.errorMessage(`GeΓ§ersiz URL(ler) tespit edildi: ${invalidUrls.join(', ')}. LΓΌtfen geΓ§erli URL'ler girin.`));
195
+ // Do not save invalid URLs, keep previous if any
196
+ if (currentCompetitorUrls) { // If there were previous valid URLs, keep them.
197
+ this.envVars.EIA_COMPETITOR_URLS = currentCompetitorUrls;
198
+ } else { // If there were no previous valid URLs, clear it.
199
+ delete this.envVars.EIA_COMPETITOR_URLS;
200
+ }
201
+ await sleep(2000); // Give user time to read error
202
+ }
203
+ else { // If competitorUrls is empty
204
+ if (this.envVars.EIA_COMPETITOR_URLS) {
205
+ delete this.envVars.EIA_COMPETITOR_URLS;
206
+ console.log(this.infoMessage('Rakip URL\'leri temizlendi. EIA, rakip analizi yapmayacaktΔ±r.'));
207
+ } else {
208
+ console.log(this.infoMessage('Rakip URL\'leri girilmedi. EIA, rakip analizi yapmayacaktΔ±r.'));
209
+ }
210
+ }
211
+
212
+ const currentProfitMargin = this.envVars.EIA_TARGET_PROFIT_MARGIN ? String(this.envVars.EIA_TARGET_PROFIT_MARGIN) : '15';
213
+ console.log(this.createInputBox('Hedef Kar MarjΔ± (%)', 'ÜrΓΌnleriniz iΓ§in ulaşmak istediğiniz ortalama kar marjΔ± hedefi. (Γ–rnek: 15)'));
214
+ const profitMargin = await this.prompt('', currentProfitMargin);
215
+
216
+ if (profitMargin && !isNaN(parseFloat(profitMargin)) && parseFloat(profitMargin) >= 0) {
217
+ this.envVars.EIA_TARGET_PROFIT_MARGIN = parseFloat(profitMargin);
218
+ console.log(this.successMessage('Hedef Kar MarjΔ± kaydedildi/gΓΌncellendi. EIA, fiyatlandΔ±rma ΓΆnerilerinde bu marjΔ± dikkate alacaktΔ±r.'));
219
+ } else {
220
+ if (this.envVars.EIA_TARGET_PROFIT_MARGIN) {
221
+ delete this.envVars.EIA_TARGET_PROFIT_MARGIN;
222
+ console.log(this.infoMessage('Hedef Kar MarjΔ± temizlendi. EIA, varsayΔ±lan bir kar marjΔ± kullanabilir.'));
223
+ } else {
224
+ this.envVars.EIA_TARGET_PROFIT_MARGIN = 15; // Default if invalid and no previous value
225
+ console.log(this.infoMessage('GeΓ§ersiz kar marjΔ± girildi, varsayΔ±lan %15 kullanΔ±lacaktΔ±r.'));
226
+ }
227
+ }
228
+ await sleep(1000);
229
+ }
230
+
231
+ clear() {
232
+ console.clear();
233
+ }
234
+
235
+ async showLogo() {
236
+ this.clear();
237
+ console.log(LOGO);
238
+ await sleep(500);
239
+ }
240
+
241
+ async runFullOnboarding() {
242
+ try {
243
+ await this.showLogo();
244
+ await this.showWelcome();
245
+ console.log(c('brightGreen', '⚑ Geliştirici Modu: Lisans kontrolü atlandı.\n'));
246
+ await this._loadPlatformMetadata(); // Load platform data
247
+ await this.step1_AIProvider();
248
+ await this.step2_Platforms();
249
+ await this.step3_Channels();
250
+ await this.step4_Gateway();
251
+ await this.step_EIAConfig();
252
+ await this.step5_Save();
253
+ await this.showSuccess();
254
+ } catch (error) {
255
+ console.error('\n' + this.errorMessage(`Beklenmeyen Hata: ${error.message}`));
256
+ } finally {
257
+ this.close();
258
+ }
259
+ }
260
+
261
+ async run() {
262
+ try {
263
+ await this.showLogo();
264
+ await this._loadPlatformMetadata(); // Load platform data
265
+
266
+ while (true) {
267
+ this.printHeader('VANTUZ YAPILANDIRMA MENÜSÜ', 'βš™οΈ');
268
+
269
+ console.log(c('brightWhite', 'Lütfen yapılandırmak istediğiniz alanı seçin:\n'));
270
+
271
+ console.log(this.menuItem('1', 'πŸ€– Yapay Zeka Servisi', 'AI Provider'));
272
+ console.log(this.menuItem('2', 'πŸ›’ Pazaryeri EntegrasyonlarΔ±', 'Platforms'));
273
+ console.log(this.menuItem('3', 'πŸ’¬ Δ°letişim KanallarΔ±', 'Channels'));
274
+ console.log(this.menuItem('4', '🌐 Vantuz Gateway', 'Gateway Configuration'));
275
+ console.log(this.menuItem('5', 'πŸ“Š E-Ticaret YΓΆnetim AjansΔ±', 'EIA'));
276
+ console.log('');
277
+ console.log(this.menuItem('A', 'πŸš€ TΓΌmΓΌnΓΌ YapΔ±landΔ±r', 'Full Onboarding', 'dim'));
278
+ console.log(this.menuItem('S', 'πŸ’Ύ Kaydet ve Γ‡Δ±k', 'Save & Exit', 'dim'));
279
+ console.log(this.menuItem('İ', '❌ İptal Et', 'Cancel without saving', 'dim'));
280
+ console.log('');
281
+
282
+ const choice = await this.prompt(c('brightYellow', '❯ Seçiminiz (1-5, A, S, İ)'));
283
+
284
+ switch (choice.toLowerCase()) {
285
+ case '1': await this.step1_AIProvider(); break;
286
+ case '2': await this.step2_Platforms(); break;
287
+ case '3': await this.step3_Channels(); break;
288
+ case '4': await this.step4_Gateway(); break;
289
+ case '5': await this.step_EIAConfig(); break;
290
+ case 'a': await this.runFullOnboarding(); return;
291
+ case 's':
292
+ await this.step5_Save();
293
+ await this.showSuccess();
294
+ return;
295
+ case 'i':
296
+ case 'Δ°':
297
+ console.log(this.warningMessage('Yapılandırma iptal edildi. Değişiklikler kaydedilmedi.'));
298
+ return;
299
+ default:
300
+ console.log(this.errorMessage('GeΓ§ersiz seΓ§im. LΓΌtfen tekrar deneyin.'));
301
+ await sleep(1000);
302
+ }
303
+ }
304
+ } catch (error) {
305
+ console.error('\n' + this.errorMessage(`Beklenmeyen Hata: ${error.message}`));
306
+ } finally {
307
+ this.close();
308
+ }
309
+ }
310
+
311
+ close() {
312
+ if (this.rl) {
313
+ this.rl.close();
314
+ this.rl = null;
315
+ }
316
+ }
317
+
318
+ printHeader(title, icon = '') {
319
+ this.clear();
320
+ console.log(LOGO);
321
+ console.log('');
322
+ const fullTitle = icon ? `${icon} ${title}` : title;
323
+ console.log(c('bold', c('brightWhite', fullTitle)));
324
+ console.log(c('brightCyan', '─'.repeat(65)));
325
+ console.log('');
326
+ }
327
+
328
+ async showWelcome() {
329
+ console.log(WELCOME_BOX);
330
+ await this.prompt(c('dim', 'β–Ά Devam etmek iΓ§in Enter\'a basΔ±n...'));
331
+ }
332
+
333
+ menuItem(key, title, subtitle = '', style = 'normal') {
334
+ const keyStyle = style === 'dim' ? 'dim' : 'brightYellow';
335
+ const titleStyle = style === 'dim' ? 'dim' : 'brightWhite';
336
+ const subtitleStyle = 'dim';
337
+
338
+ let line = ` ${c(keyStyle, c('bold', key))}. ${c(titleStyle, title)}`;
339
+ if (subtitle) {
340
+ line += ` ${c(subtitleStyle, `(${subtitle})`)}`;
341
+ }
342
+ return line;
343
+ }
344
+
345
+ createInputBox(label, hint = '') {
346
+ let output = '\n' + c('brightCyan', 'β”Œβ”€ ') + c('bold', label);
347
+ if (hint) {
348
+ output += ' ' + c('dim', `(${hint})`);
349
+ }
350
+ output += '\n' + c('brightCyan', 'β”‚ ');
351
+ return output;
352
+ }
353
+
354
+ successMessage(text) {
355
+ return '\n' + c('brightGreen', 'βœ“ ') + c('green', text) + '\n';
356
+ }
357
+
358
+ errorMessage(text) {
359
+ return c('brightRed', 'βœ— ') + c('red', text);
360
+ }
361
+
362
+ warningMessage(text) {
363
+ return '\n' + c('brightYellow', '⚠ ') + c('yellow', text) + '\n';
364
+ }
365
+
366
+ infoMessage(text) {
367
+ return '\n' + c('brightBlue', 'β„Ή ') + c('blue', text) + '\n';
368
+ }
369
+
370
+ // ADIM 1: AI PROVIDER
371
+ async step1_AIProvider() {
372
+ this.printHeader('YAPAY ZEKA SERVΔ°SΔ°', 'πŸ€–');
373
+
374
+ console.log(c('brightWhite', 'KullanΔ±lacak AI modelini seΓ§in:\n'));
375
+
376
+ // Dynamically generate menu items from PROVIDER_CONFIG
377
+ const providerKeys = Object.keys(PROVIDER_CONFIG);
378
+ const providerOptions = providerKeys.map((key, index) => {
379
+ const providerInfo = PROVIDER_CONFIG[key];
380
+ const label = providerInfo.config_label || key.charAt(0).toUpperCase() + key.slice(1);
381
+ const description = providerInfo.config_description || '';
382
+ const icon = providerInfo.config_icon || '';
383
+ return {
384
+ choice: String(index + 1),
385
+ label: `${icon} ${label}`,
386
+ description: description,
387
+ envKey: providerInfo.envKey // Store the actual env key
388
+ };
389
+ });
390
+
391
+ providerOptions.forEach(option => {
392
+ console.log(this.menuItem(option.choice, option.label, option.description));
393
+ });
394
+ console.log(this.menuItem('S', 'Atla', 'Daha sonra ayarla', 'dim'));
395
+ console.log('');
396
+
397
+ await sleep(200);
398
+
399
+ let currentAIChoice = '';
400
+ for (const option of providerOptions) {
401
+ if (this.envVars[option.envKey]) {
402
+ currentAIChoice = option.choice;
403
+ break;
404
+ }
405
+ }
406
+ if (!currentAIChoice && this.envVars.GEMINI_API_KEY) { // Fallback to Gemini if no other is set but Gemini is.
407
+ currentAIChoice = providerOptions.find(opt => opt.envKey === 'GEMINI_API_KEY')?.choice || '';
408
+ }
409
+ if (!currentAIChoice) currentAIChoice = '1'; // Default to first option if nothing is set
410
+
411
+ const choice = await this.prompt(c('brightYellow', '❯ Seçiminiz (1-' + providerOptions.length + ' veya S)'), currentAIChoice);
412
+
413
+ if (choice.toLowerCase() === 's') {
414
+ console.log(this.warningMessage('AI yapΔ±landΔ±rmasΔ± geΓ§ildi'));
415
+ await sleep(1000);
416
+ return;
417
+ }
418
+
419
+ const selectedOption = providerOptions.find(option => option.choice === choice);
420
+
421
+ if (!selectedOption) {
422
+ console.log(this.errorMessage('GeΓ§ersiz seΓ§im. LΓΌtfen tekrar deneyin.'));
423
+ await sleep(1000);
424
+ return;
425
+ }
426
+
427
+ console.log(this.successMessage(`${selectedOption.label.trim()} seΓ§ildi`));
428
+
429
+ const currentKey = this.envVars[selectedOption.envKey] || '';
430
+ console.log(this.createInputBox(`${selectedOption.label.trim()} API Key`, 'Mevcut değeri değiştirmek için yeni değer girin'));
431
+ const key = await this.prompt('', currentKey);
432
+
433
+ if (key && key.trim()) {
434
+ this.envVars[selectedOption.envKey] = key.trim();
435
+ // Clear other AI keys if one is selected
436
+ providerOptions.forEach(option => {
437
+ if (option.envKey !== selectedOption.envKey && this.envVars[option.envKey]) {
438
+ delete this.envVars[option.envKey];
439
+ }
440
+ });
441
+ console.log(this.successMessage('API anahtarΔ± kaydedildi'));
442
+ } else {
443
+ if (this.envVars[selectedOption.envKey]) {
444
+ delete this.envVars[selectedOption.envKey];
445
+ console.log(this.infoMessage('API anahtarΔ± temizlendi'));
446
+ } else {
447
+ console.log(this.infoMessage('API anahtarΔ± girilmedi, daha sonra ekleyebilirsiniz'));
448
+ }
449
+ }
450
+ await sleep(1000);
451
+ }
452
+
453
+ // ADIM 2: PAZARYERLERΔ°
454
+ async step2_Platforms() {
455
+ this.printHeader('PAZARYERΔ° ENTEGRASYONLARI', 'πŸ›’');
456
+
457
+ console.log(c('brightWhite', 'Hangi pazaryerini yapΔ±landΔ±rmak istersiniz?\n'));
458
+
459
+ // Dynamically generate menu items from this.platforms
460
+ this.platforms.forEach((platform, index) => {
461
+ console.log(this.menuItem(String(index + 1), `${platform.icon} ${platform.name}`, platform.description));
462
+ });
463
+ console.log(this.menuItem('S', 'Atla', 'TΓΌmΓΌnΓΌ geΓ§', 'dim'));
464
+ console.log('');
465
+
466
+ await sleep(200);
467
+ const choice = await this.prompt(c('brightYellow', '❯ Seçiminiz (1-' + this.platforms.length + ' veya S)'));
468
+
469
+ if (choice.toLowerCase() === 's') {
470
+ console.log(this.warningMessage('Pazaryeri yapΔ±landΔ±rmasΔ± geΓ§ildi'));
471
+ return;
472
+ }
473
+
474
+ const selectedPlatform = this.platforms[parseInt(choice) - 1];
475
+
476
+ if (!selectedPlatform) {
477
+ console.log(this.errorMessage('GeΓ§ersiz seΓ§im. LΓΌtfen tekrar deneyin.'));
478
+ await sleep(1000);
479
+ return;
480
+ }
481
+
482
+ console.log(this.successMessage(`${selectedPlatform.icon} ${selectedPlatform.name} seΓ§ildi`));
483
+ console.log(c('dim', 'Mevcut değerleri değiştirmek için yeni değer girin veya boş bırakın\n'));
484
+
485
+ let allFieldsProvided = true;
486
+ for (const field of selectedPlatform.requiredFields) {
487
+ const currentVal = this.envVars[field.env] || '';
488
+ console.log(this.createInputBox(field.label));
489
+ const value = await this.prompt('', currentVal);
490
+
491
+ if (value && value.trim()) {
492
+ this.envVars[field.env] = value.trim();
493
+ } else {
494
+ // If a required field is left empty, consider it not fully configured
495
+ allFieldsProvided = false;
496
+ delete this.envVars[field.env]; // Clear it if left empty
497
+ }
498
+ }
499
+
500
+ if (allFieldsProvided) {
501
+ console.log(this.successMessage(`${selectedPlatform.name} bilgileri alΔ±ndΔ±/gΓΌncellendi`));
502
+ // Clear keys for other platforms to ensure only one platform's config is active if not multiple
503
+ // This logic might need refinement if multiple platforms can be configured simultaneously.
504
+ // For now, assuming mutually exclusive configuration.
505
+ this.platforms.forEach(platform => {
506
+ if (platform.id !== selectedPlatform.id) {
507
+ platform.requiredFields.forEach(field => {
508
+ if (this.envVars[field.env]) {
509
+ delete this.envVars[field.env];
510
+ }
511
+ });
512
+ }
513
+ });
514
+ } else {
515
+ console.log(this.infoMessage(`${selectedPlatform.name} bilgileri eksik, kaydedilmedi/temizlenmedi`));
516
+ }
517
+ await sleep(1000);
518
+ }
519
+
520
+ // ADIM 3: KANALLAR
521
+ async step3_Channels() {
522
+ this.printHeader('Δ°LETİŞİM KANALLARI', 'πŸ’¬');
523
+
524
+ console.log(c('brightWhite', 'Hangi iletişim kanalını yapılandırmak istersiniz?\n'));
525
+
526
+ console.log(this.menuItem('1', 'Telegram Bot', 'AnlΔ±k bildirimler ve sohbet iΓ§in'));
527
+ console.log(this.menuItem('2', 'WhatsApp', 'Gateway ΓΌzerinden yΓΆnetilir'));
528
+ console.log(this.menuItem('S', 'Atla', 'Daha sonra ayarla', 'dim'));
529
+ console.log('');
530
+
531
+ await sleep(200);
532
+ const choice = await this.prompt(c('brightYellow', '❯ Seçiminiz (1-2 veya S)'));
533
+
534
+ if (choice.toLowerCase() === 's') {
535
+ console.log(this.warningMessage('İletişim kanalları yapılandırması geçildi'));
536
+ await sleep(1000);
537
+ return;
538
+ }
539
+
540
+ if (choice === '1') { // Configure Telegram
541
+ console.log('\n' + c('bold', 'Telegram Bot YapΔ±landΔ±rmasΔ±'));
542
+ console.log(c('dim', 'Mevcut değeri değiştirmek için yeni değer girin veya boş bırakın\n'));
543
+
544
+ const currentTelegramToken = this.envVars.TELEGRAM_BOT_TOKEN || '';
545
+ console.log(this.createInputBox('Telegram Bot Token', 'BotFather\'dan alΔ±nan token'));
546
+ const token = await this.prompt('', currentTelegramToken);
547
+
548
+ if (token && token.trim()) {
549
+ this.envVars.TELEGRAM_BOT_TOKEN = token.trim();
550
+ console.log(this.successMessage('Telegram token alΔ±ndΔ±/gΓΌncellendi'));
551
+ } else {
552
+ delete this.envVars.TELEGRAM_BOT_TOKEN;
553
+ console.log(this.infoMessage('Telegram token temizlendi'));
554
+ }
555
+ await sleep(1000);
556
+ } else if (choice === '2') { // Information about WhatsApp
557
+ this.printHeader('WhatsApp Kurulum Bilgisi', 'πŸ’¬');
558
+ console.log(this.infoMessage('WhatsApp entegrasyonu Vantuz Gateway üzerinden sağlanır.'));
559
+ console.log(c('brightWhite', 'Gateway\'inizi yapılandırdıktan ve başlattıktan sonra, Gateway arayüzünden WhatsApp kanalını etkinleştirebilirsiniz.\n'));
560
+ console.log(c('dim', ' Gateway durumunu kontrol etmek iΓ§in: ') + c('brightCyan', 'vantuz gateway status'));
561
+ console.log(c('dim', ' Gateway\'i başlatmak için: ') + c('brightCyan', 'start.bat') + '\n');
562
+ await this.prompt(c('dim', 'β–Ά Devam etmek iΓ§in Enter\'a basΔ±n...'));
563
+ } else {
564
+ console.log(this.errorMessage('GeΓ§ersiz seΓ§im. LΓΌtfen tekrar deneyin.'));
565
+ await sleep(1000);
566
+ return;
567
+ }
568
+ }
569
+
570
+ // ADIM 4: VANTUZ GATEWAY
571
+ async step4_Gateway() {
572
+ this.printHeader('VANTUZ GATEWAY', '🌐');
573
+
574
+ console.log(c('brightWhite', 'Vantuz Gateway, AI ve kanal yΓΆnetimini gΓΌΓ§lendirir.\n'));
575
+
576
+ const setupChoice = await this.prompt('Gateway durumunu kontrol etmek ve yapΔ±landΔ±rmak ister misiniz? (e/H)', 'e');
577
+
578
+ if (setupChoice.toLowerCase() === 'h') {
579
+ console.log(this.warningMessage('Gateway yapΔ±landΔ±rmasΔ± geΓ§ildi'));
580
+ await sleep(1000);
581
+ return;
582
+ }
583
+
584
+ // Dynamically import getGateway to avoid circular dependency if not already imported
585
+ const { getGateway } = await import('./core/gateway.js');
586
+ const gateway = await getGateway();
587
+ const info = gateway.getInfo();
588
+
589
+ console.log(c('brightYellow', '\n── Gateway Mevcut Durumu ──'));
590
+ console.log(` URL: ${c('cyan', info.url)}`);
591
+ console.log(` Durum: ${info.connected ? c('brightGreen', '● BağlΔ±') : c('brightRed', 'β—‹ BağlΔ± Değil')}`);
592
+ console.log(` Token: ${info.hasToken ? c('brightGreen', 'βœ” YapΔ±landΔ±rΔ±lmış') : c('brightRed', '✘ Eksik/GeΓ§ersiz')}`);
593
+ console.log(` Config: ${info.configFound ? c('brightGreen', 'βœ” Bulundu (gateway config)') : c('brightRed', '✘ BulunamadΔ± (gateway config)')}`);
594
+ if (info.version) console.log(` SΓΌrΓΌm: ${c('dim', info.version)}`);
595
+ console.log('');
596
+
597
+ if (!info.configFound || !info.hasToken || !info.connected) {
598
+ console.log(this.warningMessage('Gateway tam olarak yapılandırılmamış veya çalışmıyor gibi gârünüyor.'));
599
+ console.log(c('brightWhite', 'Lütfen Gateway\'i başlatmak ve tam olarak yapılandırmak için `start.bat` dosyasını çalıştırın.\n'));
600
+ console.log(c('dim', ' `start.bat` komutu gerekli dosyaları oluşturacak ve Gateway\'i başlatacaktır.'));
601
+ console.log(c('dim', ' Daha sonra durumu tekrar kontrol etmek iΓ§in: ') + c('brightCyan', 'vantuz gateway status'));
602
+ } else {
603
+ console.log(this.successMessage('Gateway başarılı bir şekilde yapılandırılmış ve çalışıyor gârünüyor.'));
604
+ console.log(c('brightWhite', 'Durumunu kontrol etmek için dilediğiniz zaman `vantuz gateway status` komutunu kullanabilirsiniz.\n'));
605
+ }
606
+ await this.prompt(c('dim', 'β–Ά Devam etmek iΓ§in Enter\'a basΔ±n...'));
607
+ }
608
+
609
+ // KAYDET
610
+ async step5_Save() {
611
+ this.printHeader('AYARLAR KAYDEDΔ°LΔ°YOR', 'πŸ’Ύ');
612
+
613
+ console.log(c('brightWhite', 'Yapılandırma dosyası oluşturuluyor...\n'));
614
+
615
+ if (!fs.existsSync(VANTUZ_HOME)) {
616
+ fs.mkdirSync(VANTUZ_HOME, { recursive: true });
617
+ }
618
+
619
+ let envContent = '# Vantuz AI YapΔ±landΔ±rmasΔ±\n';
620
+ envContent += `# Oluşturulma Tarihi: ${new Date().toISOString()}\n\n`;
621
+
622
+ for (const [key, value] of Object.entries(this.envVars)) {
623
+ if (value) {
624
+ envContent += `${key}=${value}\n`;
625
+ }
626
+ }
627
+
628
+ fs.writeFileSync(CONFIG_PATH, envContent);
629
+ console.log(this.successMessage(`Dosya kaydedildi: ${CONFIG_PATH}`));
630
+ await sleep(500);
631
+
632
+ ['logs', 'data', 'cache'].forEach(dir => {
633
+ const p = path.join(VANTUZ_HOME, dir);
634
+ if (!fs.existsSync(p)) fs.mkdirSync(p, { recursive: true });
635
+ });
636
+ console.log(this.successMessage('Veri klasârleri oluşturuldu'));
637
+ await sleep(1000);
638
+ }
639
+
640
+ async showSuccess() {
641
+ this.clear();
642
+ console.log('\n');
643
+
644
+ const successBox = `
645
+ ${colors.brightGreen}${box.topLeft}${box.horizontal.repeat(63)}${box.topRight}
646
+ ${box.vertical}${' '.repeat(17)}KURULUM BAŞARIYLA TAMAMLANDI${' '.repeat(17)}${box.vertical}
647
+ ${box.bottomLeft}${box.horizontal.repeat(63)}${box.bottomRight}${colors.reset}
648
+ `;
649
+
650
+ console.log(successBox);
651
+ console.log(c('brightWhite', '\nVantuz AI kullanΔ±ma hazΔ±rdΔ±r! πŸŽ‰\n'));
652
+
653
+ console.log(c('bold', 'Başlamak için şu komutları kullanabilirsiniz:\n'));
654
+ console.log(c('brightCyan', ' vantuz tui') + c('dim', ' - Sohbet arayüzünü başlatır'));
655
+ console.log(c('brightCyan', ' vantuz status') + c('dim', ' - Sistem durumunu gΓΆsterir'));
656
+ console.log(c('brightCyan', ' vantuz gateway') + c('dim', ' - Gateway durumunu gΓΆsterir'));
657
+ console.log(c('brightCyan', ' vantuz doctor') + c('dim', ' - Sistem sağlık kontrolü'));
658
+ console.log('\n');
659
+
660
+ await this.prompt(c('dim', 'β–Ά Γ‡Δ±kmak iΓ§in Enter\'a basΔ±n...'));
661
+ }
662
+
663
+ async promptWithRetry(question, defaultValue = '', allowEmpty = false) {
664
+ while (true) {
665
+ const answer = await this.prompt(question, defaultValue);
666
+ if (answer) return answer;
667
+ if (allowEmpty) return '';
668
+
669
+ console.log(this.warningMessage('Boş giriş algılandı. Lütfen değeri girin (veya iptal için "iptal" yazın)'));
670
+ const check = await this.prompt('Tekrar denensin mi? (E/h): ');
671
+ if (check.toLowerCase() === 'h' || check.toLowerCase() === 'iptal') return '';
672
+ await sleep(200);
673
+ }
674
+ }
675
+
676
+ prompt(question, defaultValue = '') {
677
+ const displayQuestion = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
678
+ return new Promise((resolve) => {
679
+ this.rl.question(displayQuestion, (answer) => {
680
+ resolve(answer.trim() || defaultValue);
681
+ });
682
+ });
683
+ }
684
+ }
685
+
686
+ export { Configurator };
package/package.json CHANGED
@@ -1,87 +1,88 @@
1
- ο»Ώ{
2
- "name": "vantuz",
3
- "version": "3.3.3",
4
- "description": "Yapay Zeka Destekli E-Ticaret YΓΆnetim Platformu - 7 Pazaryeri + WhatsApp/Telegram",
5
- "type": "module",
6
- "main": "cli.js",
7
- "bin": {
8
- "vantuz": "cli.js",
9
- "vantuz-onboard": "onboard.js"
10
- },
11
- "scripts": {
12
- "start": "node cli.js tui",
13
- "tui": "node cli.js tui",
14
- "config": "node cli.js config",
15
- "status": "node cli.js status",
16
- "postinstall": "echo \u0027Vantuz kuruldu! Baslatmak icin: npx vantuz-onboard\u0027",
17
- "test": "node --test",
18
- "lint": "eslint plugins/"
19
- },
20
- "keywords": [
21
- "ecommerce",
22
- "e-ticaret",
23
- "trendyol",
24
- "hepsiburada",
25
- "amazon",
26
- "n11",
27
- "ciceksepeti",
28
- "pttavm",
29
- "pazarama",
30
- "marketplace",
31
- "pazaryeri",
32
- "ai",
33
- "yapay-zeka",
34
- "repricer",
35
- "fiyatlama",
36
- "whatsapp",
37
- "telegram",
38
- "enterprise",
39
- "gateway",
40
- "management",
41
- "cli"
42
- ],
43
- "author": "Vantuz",
44
- "license": "SEE LICENSE IN LICENSE",
45
- "repository": {
46
- "type": "git",
47
- "url": "git+https://github.com/cokdalazimdegil/vantuz.git"
48
- },
49
- "homepage": "https://nuricanavsar.com/public/vantuz",
50
- "bugs": {
51
- "url": "https://github.com/cokdalazimdegil/vantuz/issues"
52
- },
53
- "dependencies": {
54
- "axios": "^1.13.5",
55
- "cors": "^2.8.6",
56
- "cron": "^4.4.0",
57
- "dotenv": "^16.0.0",
58
- "express": "^5.2.1",
59
- "openclaw": "^0.0.1",
60
- "playwright": "^1.58.2",
61
- "sqlite": "^5.1.1",
62
- "sqlite3": "^5.0.2",
63
- "xml2js": "^0.6.2"
64
- },
65
- "devDependencies": {
66
- "eslint": "^8.0.0"
67
- },
68
- "os": [
69
- "darwin",
70
- "linux",
71
- "win32"
72
- ],
73
- "engines": {
74
- "node": "\u003e=18.0.0"
75
- },
76
- "files": [
77
- "cli.js",
78
- "onboard.js",
79
- "core",
80
- "server",
81
- "platforms",
82
- "plugins",
83
- "start.bat",
84
- "LICENSE",
85
- "README.md"
86
- ]
87
- }
1
+ {
2
+ "name": "vantuz",
3
+ "version": "3.3.5",
4
+ "description": "Yapay Zeka Destekli E-Ticaret YΓΆnetim Platformu - 7 Pazaryeri + WhatsApp/Telegram",
5
+ "type": "module",
6
+ "main": "cli.js",
7
+ "bin": {
8
+ "vantuz": "cli.js",
9
+ "vantuz-onboard": "onboard.js"
10
+ },
11
+ "scripts": {
12
+ "start": "node cli.js tui",
13
+ "tui": "node cli.js tui",
14
+ "config": "node cli.js config",
15
+ "status": "node cli.js status",
16
+ "postinstall": "echo \u0027Vantuz kuruldu! Baslatmak icin: npx vantuz-onboard\u0027",
17
+ "test": "node --test",
18
+ "lint": "eslint plugins/"
19
+ },
20
+ "keywords": [
21
+ "ecommerce",
22
+ "e-ticaret",
23
+ "trendyol",
24
+ "hepsiburada",
25
+ "amazon",
26
+ "n11",
27
+ "ciceksepeti",
28
+ "pttavm",
29
+ "pazarama",
30
+ "marketplace",
31
+ "pazaryeri",
32
+ "ai",
33
+ "yapay-zeka",
34
+ "repricer",
35
+ "fiyatlama",
36
+ "whatsapp",
37
+ "telegram",
38
+ "enterprise",
39
+ "gateway",
40
+ "management",
41
+ "cli"
42
+ ],
43
+ "author": "Vantuz",
44
+ "license": "SEE LICENSE IN LICENSE",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "git+https://github.com/cokdalazimdegil/vantuz.git"
48
+ },
49
+ "homepage": "https://nuricanavsar.com/public/vantuz",
50
+ "bugs": {
51
+ "url": "https://github.com/cokdalazimdegil/vantuz/issues"
52
+ },
53
+ "dependencies": {
54
+ "axios": "^1.13.5",
55
+ "cors": "^2.8.6",
56
+ "cron": "^4.4.0",
57
+ "dotenv": "^16.0.0",
58
+ "express": "^5.2.1",
59
+ "openclaw": "^0.0.1",
60
+ "playwright": "^1.58.2",
61
+ "sqlite": "^5.1.1",
62
+ "sqlite3": "^5.0.2",
63
+ "xml2js": "^0.6.2"
64
+ },
65
+ "devDependencies": {
66
+ "eslint": "^8.0.0"
67
+ },
68
+ "os": [
69
+ "darwin",
70
+ "linux",
71
+ "win32"
72
+ ],
73
+ "engines": {
74
+ "node": "\u003e=18.0.0"
75
+ },
76
+ "files": [
77
+ "cli.js",
78
+ "onboard.js",
79
+ "config.js",
80
+ "core",
81
+ "server",
82
+ "platforms",
83
+ "plugins",
84
+ "start.bat",
85
+ "LICENSE",
86
+ "README.md"
87
+ ]
88
+ }