vantuz 3.3.2 → 3.3.4

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 (4) hide show
  1. package/config.js +686 -0
  2. package/onboard.js +11 -0
  3. package/package.json +90 -84
  4. package/start.bat +33 -0
package/config.js ADDED
@@ -0,0 +1,686 @@
1
+ #!/usr/bin/env node
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/onboard.js ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Configurator } from './config.js';
4
+
5
+ try {
6
+ const configurator = new Configurator();
7
+ await configurator.run();
8
+ } catch (e) {
9
+ console.error('[HATA] Onboarding basarisiz:', e?.message || e);
10
+ process.exitCode = 1;
11
+ }
package/package.json CHANGED
@@ -1,85 +1,91 @@
1
- {
2
- "name": "vantuz",
3
- "version": "3.3.2",
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
- },
10
- "scripts": {
11
- "start": "node cli.js tui",
12
- "tui": "node cli.js tui",
13
- "config": "node cli.js config",
14
- "status": "node cli.js status",
15
- "postinstall": "echo '🐙 Vantuz kuruldu! Başlatmak için: npx vantuz-onboard'",
16
- "test": "node --test",
17
- "lint": "eslint plugins/"
18
- },
19
- "keywords": [
20
- "ecommerce",
21
- "e-ticaret",
22
- "trendyol",
23
- "hepsiburada",
24
- "amazon",
25
- "n11",
26
- "ciceksepeti",
27
- "pttavm",
28
- "pazarama",
29
- "marketplace",
30
- "pazaryeri",
31
- "ai",
32
- "yapay-zeka",
33
- "repricer",
34
- "fiyatlama",
35
- "whatsapp",
36
- "telegram",
37
- "enterprise",
38
- "gateway",
39
- "management",
40
- "cli"
41
- ],
42
- "author": "Vantuz",
43
- "license": "SEE LICENSE IN LICENSE",
44
- "repository": {
45
- "type": "git",
46
- "url": "git+https://github.com/nuricanavsar/vantuz.git"
47
- },
48
- "homepage": "https://vantuz.ai",
49
- "bugs": {
50
- "url": "https://github.com/nuricanavsar/vantuz/issues"
51
- },
52
- "dependencies": {
53
- "axios": "^1.13.5",
54
- "cors": "^2.8.6",
55
- "cron": "^4.4.0",
56
- "dotenv": "^16.0.0",
57
- "express": "^5.2.1",
58
- "openclaw": "^0.0.1",
59
- "playwright": "^1.58.2",
60
- "sqlite": "^5.1.1",
61
- "sqlite3": "^5.0.2",
62
- "xml2js": "^0.6.2"
63
- },
64
- "devDependencies": {
65
- "eslint": "^8.0.0"
66
- },
67
- "os": [
68
- "darwin",
69
- "linux",
70
- "win32"
71
- ],
72
- "engines": {
73
- "node": ">=18.0.0"
74
- },
75
- "files": [
76
- "cli.js",
77
- "onboard.js",
78
- "core",
79
- "server",
80
- "platforms",
81
- "plugins",
82
- "LICENSE",
83
- "README.md"
84
- ]
1
+ {
2
+ "name": "vantuz",
3
+ "version": "3.3.4",
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
+ ]
85
88
  }
89
+
90
+
91
+
package/start.bat ADDED
@@ -0,0 +1,33 @@
1
+ @echo off
2
+ title Vantuz Gateway & Engine
3
+ color 0b
4
+
5
+ echo.
6
+ echo V A N T U Z A I
7
+ echo -----------------
8
+ echo System Starting...
9
+ echo.
10
+
11
+ :: 1. Vantuz Gateway Başlat (Arka planda)
12
+ if exist ".openclaw\gateway.cmd" (
13
+ echo [INFO] Starting Vantuz Gateway...
14
+ start /min "Vantuz Gateway" cmd /c ".openclaw\gateway.cmd"
15
+ ) else (
16
+ echo [WARN] Gateway logic not found. Skipping...
17
+ )
18
+
19
+ :: 2. Bekle (Gateway'in açılması için)
20
+ timeout /t 3 >nul
21
+
22
+ :: 3. Vantuz Sunucusunu Başlat (Arka planda)
23
+ echo [INFO] Starting Vantuz API Server...
24
+ start /min "Vantuz Server" node server/app.js
25
+
26
+ :: 4. CLI Arayüzünü Başlat
27
+ echo [INFO] Launching CLI...
28
+ timeout /t 2 >nul
29
+ node cli.js tui
30
+
31
+ echo.
32
+ echo [INFO] System shutdown.
33
+ pause