@artilingo/artiframe-cli 2.0.4 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/LICENSE +660 -660
  2. package/README.md +64 -118
  3. package/bin/artiframe.js +0 -0
  4. package/bin/artiframe.php +0 -0
  5. package/core-stubs/app/ApiAuthControl.php +76 -0
  6. package/core-stubs/app/ApiControl.php +81 -35
  7. package/core-stubs/app/AuthControl.php +39 -0
  8. package/core-stubs/app/Database.php +36 -35
  9. package/core-stubs/app/DotEnv.php +19 -1
  10. package/core-stubs/app/ViewControl.php +47 -1
  11. package/core-stubs/bin/SQLMethod.php +261 -0
  12. package/core-stubs/bin/SystemMethod.php +115 -74
  13. package/core-stubs/bin/ViewMethod.php +19 -5
  14. package/core-stubs/docs/de.html +4325 -4347
  15. package/core-stubs/docs/en.html +4325 -4347
  16. package/core-stubs/docs/es.html +4325 -4347
  17. package/core-stubs/docs/fr.html +4325 -4347
  18. package/core-stubs/docs/tr.html +117 -46
  19. package/core-stubs/public/403.php +52 -0
  20. package/core-stubs/public/assets/css/components/header.css +174 -0
  21. package/core-stubs/public/assets/css/components/mobilenav.css +198 -0
  22. package/core-stubs/public/assets/css/components/sidebar.css +184 -0
  23. package/core-stubs/public/assets/css/root/app.css +975 -38
  24. package/core-stubs/public/assets/css/root/root.css +64 -0
  25. package/core-stubs/public/assets/js/components/header.js +380 -0
  26. package/core-stubs/public/assets/js/components/mobilenav.js +97 -0
  27. package/core-stubs/public/assets/js/components/theme-modal.js +74 -0
  28. package/core-stubs/public/assets/js/root/app.js +1870 -0
  29. package/core-stubs/public/includes/footer.php +4 -5
  30. package/core-stubs/public/includes/head-auth.php +65 -0
  31. package/core-stubs/public/includes/head.php +56 -17
  32. package/core-stubs/public/includes/header.php +135 -1
  33. package/core-stubs/public/includes/mobilenav.php +75 -3
  34. package/core-stubs/public/includes/sidebar.php +186 -1
  35. package/core-stubs/public/includes/theme-modal.php +1 -0
  36. package/db-studio/debug.log +3 -0
  37. package/db-studio/index.html +1755 -0
  38. package/db-studio/launcher.html +102 -0
  39. package/db-studio/launcher.js +180 -0
  40. package/db-studio/logo.svg +22 -0
  41. package/db-studio/main.js +568 -0
  42. package/db-studio/package-lock.json +1034 -0
  43. package/db-studio/package.json +16 -0
  44. package/db-studio/preload.js +29 -0
  45. package/devops-studio/api-inspector.js +222 -0
  46. package/devops-studio/index.html +1892 -0
  47. package/devops-studio/logo.svg +22 -0
  48. package/devops-studio/main.js +67 -0
  49. package/devops-studio/make-wizard.js +635 -0
  50. package/devops-studio/package-lock.json +871 -0
  51. package/devops-studio/package.json +12 -0
  52. package/package.json +5 -2
  53. package/scripts/postinstall.js +44 -8
  54. package/server-studio/.json-404-guard +1 -0
  55. package/server-studio/index.html +283 -0
  56. package/server-studio/logo.svg +22 -0
  57. package/server-studio/main.js +133 -0
  58. package/server-studio/package-lock.json +1179 -0
  59. package/server-studio/package.json +15 -0
  60. package/server-studio/router.php +99 -0
  61. package/src/App.php +29 -0
  62. package/src/Commands/AddCommand.php +26 -9
  63. package/src/Commands/DbExportCommand.php +131 -0
  64. package/src/Commands/DbStartCommand.php +46 -0
  65. package/src/Commands/DevopsCommand.php +35 -0
  66. package/src/Commands/GoCommand.php +48 -48
  67. package/src/Commands/ListCommand.php +68 -68
  68. package/src/Commands/MakeApiCommand.php +6 -1
  69. package/src/Commands/MakeViewCommand.php +25 -2
  70. package/src/Commands/NewProjectCommand.php +16 -11
  71. package/src/Commands/OptimizeCommand.php +61 -0
  72. package/src/Commands/RemoveCommand.php +35 -7
  73. package/src/Commands/ServeCommand.php +46 -91
  74. package/src/Commands/ShowCommand.php +24 -24
  75. package/src/Commands/UpgradeCommand.php +39 -10
  76. package/stubs/make/api-switch-case.stub +1 -1
  77. package/stubs/make/auth-api-standart.stub +20 -0
  78. package/stubs/make/auth-api-switch-case.stub +38 -0
  79. package/stubs/make/auth-view.stub +26 -0
  80. package/stubs/make/class.stub +10 -2
  81. package/stubs/make/view.stub +3 -0
  82. package/stubs/service/image.stub +334 -334
  83. package/stubs/service/iyzico.stub +637 -637
  84. package/stubs/service/jwt.stub +312 -312
  85. package/stubs/service/phpmailer.stub +143 -143
  86. package/stubs/service/pusher.stub +232 -232
  87. package/stubs/service/qrcode.stub +169 -169
  88. package/stubs/service/redis.stub +361 -361
  89. package/stubs/service/s3.stub +377 -377
  90. package/stubs/service/stripe.stub +526 -526
  91. package/stubs/service/twilio.stub +361 -361
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "artiframe-server-studio",
3
+ "version": "1.0.0",
4
+ "description": "ArtiFrame Real-time Server Dashboard",
5
+ "main": "main.js",
6
+ "scripts": {
7
+ "start": "electron ."
8
+ },
9
+ "dependencies": {
10
+ "qrcode": "^1.5.3"
11
+ },
12
+ "devDependencies": {
13
+ "electron": "^28.2.0"
14
+ }
15
+ }
@@ -0,0 +1,99 @@
1
+ <?php
2
+ $uri = urldecode(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
3
+ $projectRoot = getenv('ARTIFRAME_PROJECT_ROOT');
4
+ $publicDir = $projectRoot . '/public';
5
+ $requestedFile = $publicDir . $uri;
6
+
7
+ $resolvedFile = 'public/index.php';
8
+ $isStatic = false;
9
+
10
+ if ($uri !== '/' && file_exists($requestedFile) && !is_dir($requestedFile)) {
11
+ $resolvedFile = 'public' . $uri;
12
+ $isStatic = true;
13
+ }
14
+
15
+ $globalErrorMessage = null;
16
+
17
+ // Function to send log to Electron
18
+ function sendLogToElectron($statusCode = null) {
19
+ $loggerPort = getenv('ARTIFRAME_STUDIO_LOGGER_PORT');
20
+ if (!$loggerPort) return;
21
+
22
+ global $uri, $resolvedFile, $globalErrorMessage, $startTime;
23
+
24
+ if ($statusCode === null) {
25
+ $statusCode = http_response_code() ?: 200;
26
+ $error = error_get_last();
27
+ if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR])) {
28
+ $statusCode = 500;
29
+ if (!$globalErrorMessage) {
30
+ $globalErrorMessage = $error['message'] . ' in ' . $error['file'] . ':' . $error['line'];
31
+ }
32
+ }
33
+ }
34
+
35
+ $parsedParams = [];
36
+ foreach ($_GET as $k => $v) {
37
+ $val = is_array($v) ? 'Array' : $v;
38
+ $parsedParams[] = '$_GET[\'' . $k . '\'] = ' . $val;
39
+ }
40
+
41
+ $log = [
42
+ 'time' => date('H:i:s'),
43
+ 'method' => strtoupper($_SERVER['REQUEST_METHOD']),
44
+ 'url' => $_SERVER['REQUEST_URI'],
45
+ 'resolvedFile' => $resolvedFile,
46
+ 'params' => implode(', ', $parsedParams),
47
+ 'statusCode' => $statusCode,
48
+ 'errorMessage' => $globalErrorMessage,
49
+ 'duration' => isset($startTime) ? round((microtime(true) - $startTime) * 1000) . 'ms' : '0ms',
50
+ 'memory' => round(memory_get_peak_usage(true) / 1024 / 1024, 2) . ' MB'
51
+ ];
52
+
53
+ $payload = json_encode($log);
54
+ $options = [
55
+ 'http' => [
56
+ 'method' => 'POST',
57
+ 'header' => "Content-Type: application/json\r\n",
58
+ 'content' => $payload,
59
+ 'timeout' => 0.5
60
+ ]
61
+ ];
62
+ $context = stream_context_create($options);
63
+ @file_get_contents("http://127.0.0.1:{$loggerPort}", false, $context);
64
+ }
65
+
66
+ // Register shutdown to guarantee logging even on fatals
67
+ register_shutdown_function('sendLogToElectron');
68
+
69
+ if ($isStatic) {
70
+ return false;
71
+ }
72
+
73
+ // Intercept output to capture status code for index.php execution
74
+ ob_start();
75
+
76
+ $_SERVER['SCRIPT_NAME'] = '/index.php';
77
+ $_SERVER['SCRIPT_FILENAME'] = $publicDir . '/index.php';
78
+ chdir($publicDir);
79
+
80
+ try {
81
+ require $publicDir . '/index.php';
82
+ } catch (\Throwable $e) {
83
+ $globalErrorMessage = $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine();
84
+ echo "<h1>500 Internal Server Error</h1>";
85
+ echo "<pre>" . $globalErrorMessage . "\n" . $e->getTraceAsString() . "</pre>";
86
+ http_response_code(500);
87
+ }
88
+
89
+ $output = ob_get_clean();
90
+ $statusCode = http_response_code() ?: 200;
91
+
92
+ // Apply JSON 404 Guard if needed
93
+ $isJson404GuardActive = file_exists(__DIR__ . '/.json-404-guard');
94
+ if ($statusCode === 404 && $isJson404GuardActive) {
95
+ header('Content-Type: application/json');
96
+ $output = json_encode(['error' => 'Not Found', 'message' => 'JSON 404 Guard is active.', 'code' => 404]);
97
+ }
98
+
99
+ echo $output;
package/src/App.php CHANGED
@@ -230,6 +230,28 @@ class App
230
230
  break;
231
231
 
232
232
 
233
+ case 'optimize':
234
+ (new \ArtiFrame\Cli\Commands\OptimizeCommand($this->translator))->execute($commandArgs);
235
+ break;
236
+
237
+ case 'db:start':
238
+ (new \ArtiFrame\Cli\Commands\DbStartCommand($this->translator))->execute(array_merge($commandArgs, ['--mode=offline']));
239
+ break;
240
+
241
+ case 'db:onproject':
242
+ (new \ArtiFrame\Cli\Commands\DbStartCommand($this->translator))->execute(array_merge($commandArgs, ['--mode=live']));
243
+ break;
244
+
245
+ case 'db:export':
246
+ (new \ArtiFrame\Cli\Commands\DbExportCommand($this->translator))->execute($commandArgs);
247
+ break;
248
+
249
+ case 'devops':
250
+ (new \ArtiFrame\Cli\Commands\DevopsCommand($this->translator))->execute($commandArgs);
251
+ break;
252
+
253
+
254
+
233
255
  case 'serve':
234
256
  (new \ArtiFrame\Cli\Commands\ServeCommand($this->translator))->execute($commandArgs);
235
257
  break;
@@ -421,6 +443,13 @@ class App
421
443
  echo " " . $d . "└── " . $r . "Example: " . $lg . "issues" . $r . " or " . $lg . "issues 4" . $r . PHP_EOL;
422
444
  echo PHP_EOL;
423
445
 
446
+ // db:export
447
+ echo " " . $g . "db:export" . $r . " " . $y . "<within|without>" . $r . PHP_EOL;
448
+ echo " " . $d . "│" . $r . " Veritabanını SQL dosyası olarak dışa aktarır." . PHP_EOL;
449
+ echo " " . $d . "├── " . $r . "Example: " . $lg . "db:export within" . $r . $d . " (Yapı ve Veriler)" . $r . PHP_EOL;
450
+ echo " " . $d . "└── " . $r . "Example: " . $lg . "db:export without" . $r . $d . " (Sadece Yapı)" . $r . PHP_EOL;
451
+ echo PHP_EOL;
452
+
424
453
  // help / exit
425
454
  echo " " . $d . "─────────────────────────────────────────────────────────────" . $r . PHP_EOL;
426
455
  echo " " . $g . "help" . $r . " " . $t->get('HELP_HELP_DESC') . PHP_EOL;
@@ -136,11 +136,11 @@ class AddCommand
136
136
  'stub' => 'phpmailer.stub',
137
137
  'env' => [
138
138
  '# ── mail (phpmailer) ──────────────────────',
139
- 'MAIL_HOST=smtp.mailtrap.io',
140
- 'MAIL_PORT=2525',
139
+ 'MAIL_HOST=127.0.0.1',
140
+ 'MAIL_PORT=1025',
141
141
  'MAIL_USERNAME=',
142
142
  'MAIL_PASSWORD=',
143
- 'MAIL_ENCRYPTION=tls',
143
+ 'MAIL_ENCRYPTION=',
144
144
  'MAIL_FROM_ADDRESS=hello@example.com',
145
145
  'MAIL_FROM_NAME=ArtiFrame',
146
146
  ],
@@ -317,29 +317,46 @@ class AddCommand
317
317
  return;
318
318
  }
319
319
 
320
+
320
321
  $envBlock = PHP_EOL . implode(PHP_EOL, $package['env']) . PHP_EOL;
321
322
 
322
323
  // .env dosyasına ekle
323
324
  $envFile = $projectRoot . '/.env';
324
325
  if (file_exists($envFile)) {
325
- // Zaten eklenmişse tekrar ekleme
326
326
  $currentContent = file_get_contents($envFile);
327
- if (str_contains($currentContent, $package['env'][0])) {
328
- return; // Başlık satırı zaten var, atla
327
+ // Zaten eklenmiş anahtarlardan herhangi biri var mı kontrol et
328
+ $alreadyExists = false;
329
+ foreach ($package['env'] as $line) {
330
+ if (str_starts_with(trim($line), '#') || empty(trim($line))) continue;
331
+ $key = explode('=', $line)[0];
332
+ if (str_contains($currentContent, $key . '=')) {
333
+ $alreadyExists = true;
334
+ break;
335
+ }
336
+ }
337
+ if (!$alreadyExists) {
338
+ file_put_contents($envFile, $envBlock, FILE_APPEND);
329
339
  }
330
- file_put_contents($envFile, $envBlock, FILE_APPEND);
331
340
  }
332
341
 
333
342
  // .env.example dosyasına ekle
334
343
  $envExample = $projectRoot . '/.env.example';
335
344
  if (file_exists($envExample)) {
336
345
  $currentContent = file_get_contents($envExample);
337
- if (!str_contains($currentContent, $package['env'][0])) {
346
+ $alreadyExists = false;
347
+ foreach ($package['env'] as $line) {
348
+ if (str_starts_with(trim($line), '#') || empty(trim($line))) continue;
349
+ $key = explode('=', $line)[0];
350
+ if (str_contains($currentContent, $key . '=')) {
351
+ $alreadyExists = true;
352
+ break;
353
+ }
354
+ }
355
+ if (!$alreadyExists) {
338
356
  file_put_contents($envExample, $envBlock, FILE_APPEND);
339
357
  }
340
358
  }
341
359
  }
342
-
343
360
  // ─── Yardımcı Metodlar ───────────────────────────────────────
344
361
 
345
362
  /**
@@ -0,0 +1,131 @@
1
+ <?php
2
+ namespace ArtiFrame\Cli\Commands;
3
+
4
+ use ArtiFrame\Cli\Services\Translator;
5
+ use ArtiFrame\Cli\Services\Safeguard;
6
+
7
+ class DbExportCommand
8
+ {
9
+ private Translator $translator;
10
+ private Safeguard $safeguard;
11
+
12
+ public function __construct(Translator $translator)
13
+ {
14
+ $this->translator = $translator;
15
+ $this->safeguard = new Safeguard($translator);
16
+ }
17
+
18
+ private function parseEnvFile(string $path): array
19
+ {
20
+ $env = [];
21
+ $lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
22
+ foreach ($lines as $line) {
23
+ $line = trim($line);
24
+ if (strpos($line, '#') === 0) continue;
25
+ if (strpos($line, '=') !== false) {
26
+ list($key, $val) = explode('=', $line, 2);
27
+ $env[trim($key)] = trim($val, " \t\n\r\0\x0B\"'");
28
+ }
29
+ }
30
+ return $env;
31
+ }
32
+
33
+ public function execute(array $args): void
34
+ {
35
+ $projectRoot = $this->safeguard->getProjectRoot();
36
+
37
+ if (!file_exists($projectRoot . '/.env')) {
38
+ echo "❌ .env dosyasi bulunamadi. Bu komut sadece projelerin icinde calisir.\n";
39
+ return;
40
+ }
41
+
42
+ $mode = $args[0] ?? null;
43
+ if (!in_array($mode, ['within', 'without'])) {
44
+ echo "❌ Gecersiz parametre. Kullanim:\n";
45
+ echo " artiframe db:export within (Yapi ve Verileri disari aktarir)\n";
46
+ echo " artiframe db:export without (Sadece tablo yapisini disari aktarir)\n";
47
+ return;
48
+ }
49
+
50
+ // Read .env securely
51
+ $env = $this->parseEnvFile($projectRoot . '/.env');
52
+ $dbHost = $env['DB_HOST'] ?? 'localhost';
53
+ $dbUser = $env['DB_USER'] ?? ($env['DB_USERNAME'] ?? 'root');
54
+ $dbPass = $env['DB_PASS'] ?? ($env['DB_PASSWORD'] ?? '');
55
+ $dbName = $env['DB_NAME'] ?? ($env['DB_DATABASE'] ?? '');
56
+
57
+ if (!$dbName) {
58
+ echo "❌ .env dosyasinda DB_NAME ayarlanmamis.\n";
59
+ return;
60
+ }
61
+
62
+ echo "🔄 Veritabani disari aktariliyor: {$dbName} (" . ($mode === 'within' ? 'Yapi + Veri' : 'Sadece Yapi') . ")...\n";
63
+
64
+ try {
65
+ $pdo = new \PDO("mysql:host={$dbHost};dbname={$dbName};charset=utf8mb4", $dbUser, $dbPass, [
66
+ \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION
67
+ ]);
68
+
69
+ $sql = "-- ArtiFrame Veritabani Yedegi\n";
70
+ $sql .= "-- Tarih: " . date('Y-m-d H:i:s') . "\n";
71
+ $sql .= "-- Veritabani: {$dbName}\n";
72
+ $sql .= "-- Mod: {$mode}\n\n";
73
+ $sql .= "SET FOREIGN_KEY_CHECKS=0;\n\n";
74
+
75
+ $tablesQuery = $pdo->query("SHOW TABLES");
76
+ $tables = $tablesQuery->fetchAll(\PDO::FETCH_COLUMN);
77
+
78
+ foreach ($tables as $table) {
79
+ // Table structure
80
+ $sql .= "-- --------------------------------------------------------\n";
81
+ $sql .= "-- Tablo Yapisi: `{$table}`\n";
82
+ $sql .= "-- --------------------------------------------------------\n";
83
+ $sql .= "DROP TABLE IF EXISTS `{$table}`;\n";
84
+
85
+ $createRow = $pdo->query("SHOW CREATE TABLE `{$table}`")->fetch(\PDO::FETCH_ASSOC);
86
+ $sql .= $createRow['Create Table'] . ";\n\n";
87
+
88
+ // Table data (if within)
89
+ if ($mode === 'within') {
90
+ $rows = $pdo->query("SELECT * FROM `{$table}`")->fetchAll(\PDO::FETCH_ASSOC);
91
+ if (count($rows) > 0) {
92
+ $sql .= "-- Tablo Verisi: `{$table}`\n";
93
+
94
+ $chunks = array_chunk($rows, 100); // 100 rows per INSERT
95
+ foreach ($chunks as $chunk) {
96
+ $keys = array_keys($chunk[0]);
97
+ $keysList = implode("\`, \`", $keys);
98
+ $sql .= "INSERT INTO `{$table}` (`{$keysList}`) VALUES \n";
99
+
100
+ $valuesLines = [];
101
+ foreach ($chunk as $row) {
102
+ $vals = array_map(function($val) use ($pdo) {
103
+ if ($val === null) return 'NULL';
104
+ return $pdo->quote($val);
105
+ }, array_values($row));
106
+ $valuesLines[] = "(" . implode(", ", $vals) . ")";
107
+ }
108
+ $sql .= implode(",\n", $valuesLines) . ";\n";
109
+ }
110
+ $sql .= "\n";
111
+ }
112
+ }
113
+ }
114
+
115
+ $sql .= "SET FOREIGN_KEY_CHECKS=1;\n";
116
+
117
+ $filename = "export_{$mode}_{$dbName}_" . date('Ymd_His') . ".sql";
118
+ $exportPath = $projectRoot . '/' . $filename;
119
+
120
+ file_put_contents($exportPath, $sql);
121
+
122
+ echo "✅ Basarili! Veritabani disa aktarildi.\n";
123
+ echo "📂 Dosya: {$exportPath}\n";
124
+
125
+ } catch (\PDOException $e) {
126
+ echo "❌ Veritabani hatasi: " . $e->getMessage() . "\n";
127
+ } catch (\Exception $e) {
128
+ echo "❌ Hata: " . $e->getMessage() . "\n";
129
+ }
130
+ }
131
+ }
@@ -0,0 +1,46 @@
1
+ <?php
2
+ namespace ArtiFrame\Cli\Commands;
3
+
4
+ use ArtiFrame\Cli\Services\Translator;
5
+ use ArtiFrame\Cli\Services\Safeguard;
6
+
7
+ class DbStartCommand
8
+ {
9
+ private Translator $translator;
10
+ private Safeguard $safeguard;
11
+
12
+ public function __construct(Translator $translator)
13
+ {
14
+ $this->translator = $translator;
15
+ $this->safeguard = new Safeguard($translator);
16
+ }
17
+
18
+ public function execute(array $args): void
19
+ {
20
+ $projectRoot = $this->safeguard->getProjectRoot();
21
+ $dbStudioPath = dirname(__DIR__, 2) . '/db-studio';
22
+
23
+ $mode = 'offline';
24
+ if (in_array('--mode=live', $args)) {
25
+ $mode = 'live';
26
+ }
27
+
28
+ if ($mode === 'live' && !file_exists($projectRoot . '/.env')) {
29
+ echo "❌ .env dosyasi bulunamadi. Lutfen veritabani ayarlarini yapin veya bagimsiz mod icin 'artiframe db:start' kullanin.\n";
30
+ return;
31
+ }
32
+
33
+ echo "🚀 ArtiFrame DB Studio baslatiliyor...\n";
34
+
35
+ $os = PHP_OS_FAMILY;
36
+ $cmd = sprintf('npm run start --prefix %s -- %s --mode=%s', escapeshellarg($dbStudioPath), escapeshellarg($projectRoot), $mode);
37
+
38
+ if ($os === 'Windows') {
39
+ pclose(popen("start \"ArtiFrame DB Studio\" cmd /c \"{$cmd}\"", "r"));
40
+ } else {
41
+ exec("{$cmd} > /dev/null 2>&1 &");
42
+ }
43
+
44
+ echo "✅ DB Studio arka planda acildi.\n";
45
+ }
46
+ }
@@ -0,0 +1,35 @@
1
+ <?php
2
+ namespace ArtiFrame\Cli\Commands;
3
+
4
+ use ArtiFrame\Cli\Services\Translator;
5
+
6
+ class DevopsCommand
7
+ {
8
+ private Translator $translator;
9
+
10
+ public function __construct(Translator $translator)
11
+ {
12
+ $this->translator = $translator;
13
+ }
14
+
15
+ public function execute(array $args): void
16
+ {
17
+ $tab = isset($args[0]) ? $args[0] : 'launcher';
18
+ $cwd = getcwd();
19
+
20
+ echo "\n 🚀 ArtiFrame DevOps Studio başlatılıyor...\n";
21
+
22
+ $devopsStudioPath = dirname(__DIR__, 2) . '/devops-studio';
23
+ $os = PHP_OS_FAMILY;
24
+
25
+ $cmd = sprintf('npm run start --prefix %s -- %s %s', escapeshellarg($devopsStudioPath), escapeshellarg($tab), escapeshellarg($cwd));
26
+
27
+ if ($os === 'Windows') {
28
+ pclose(popen("start \"ArtiFrame DevOps Studio\" cmd /c \"{$cmd}\"", "r"));
29
+ } else {
30
+ exec("{$cmd} > /dev/null 2>&1 &");
31
+ }
32
+
33
+ echo " ✅ DevOps Studio arka planda açıldı.\n\n";
34
+ }
35
+ }
@@ -1,48 +1,48 @@
1
- <?php
2
- namespace ArtiFrame\Cli\Commands;
3
-
4
- use ArtiFrame\Cli\Services\Translator;
5
-
6
- class GoCommand
7
- {
8
- private Translator $translator;
9
-
10
- public function __construct(Translator $translator)
11
- {
12
- $this->translator = $translator;
13
- }
14
-
15
- public function execute(array $args): void
16
- {
17
- $target = $args[0] ?? null;
18
-
19
- if (!$target) {
20
- echo "
21
- ❌ " . $this->translator->get('GO_MISSING_DIR') . "
22
-
23
- ";
24
- return;
25
- }
26
-
27
- if ($target === 'back') {
28
- $target = '..';
29
- }
30
-
31
- if (!is_dir($target)) {
32
- $notFound = str_replace(':dir', $target, $this->translator->get('GO_NOT_FOUND'));
33
- echo "
34
- ❌ " . $notFound . "
35
-
36
- ";
37
- return;
38
- }
39
-
40
- chdir($target);
41
- echo "
42
- ✅ " . $this->translator->get('GO_SUCCESS') . "
43
- ";
44
- echo " " . getcwd() . "
45
-
46
- ";
47
- }
48
- }
1
+ <?php
2
+ namespace ArtiFrame\Cli\Commands;
3
+
4
+ use ArtiFrame\Cli\Services\Translator;
5
+
6
+ class GoCommand
7
+ {
8
+ private Translator $translator;
9
+
10
+ public function __construct(Translator $translator)
11
+ {
12
+ $this->translator = $translator;
13
+ }
14
+
15
+ public function execute(array $args): void
16
+ {
17
+ $target = $args[0] ?? null;
18
+
19
+ if (!$target) {
20
+ echo "
21
+ ❌ " . $this->translator->get('GO_MISSING_DIR') . "
22
+
23
+ ";
24
+ return;
25
+ }
26
+
27
+ if ($target === 'back') {
28
+ $target = '..';
29
+ }
30
+
31
+ if (!is_dir($target)) {
32
+ $notFound = str_replace(':dir', $target, $this->translator->get('GO_NOT_FOUND'));
33
+ echo "
34
+ ❌ " . $notFound . "
35
+
36
+ ";
37
+ return;
38
+ }
39
+
40
+ chdir($target);
41
+ echo "
42
+ ✅ " . $this->translator->get('GO_SUCCESS') . "
43
+ ";
44
+ echo " " . getcwd() . "
45
+
46
+ ";
47
+ }
48
+ }
@@ -1,68 +1,68 @@
1
- <?php
2
- namespace ArtiFrame\Cli\Commands;
3
-
4
- use ArtiFrame\Cli\Services\Translator;
5
-
6
- class ListCommand
7
- {
8
- private Translator $translator;
9
-
10
- public function __construct(Translator $translator)
11
- {
12
- $this->translator = $translator;
13
- }
14
-
15
- public function execute(array $args): void
16
- {
17
- $safeguard = new \ArtiFrame\Cli\Services\Safeguard($this->translator);
18
- $dir = $safeguard->getProjectRoot();
19
- $projectName = basename($dir);
20
-
21
- echo "
22
- 📂 " . $projectName . "/
23
- ";
24
-
25
- $priorityOrder = [
26
- 'bin', 'config', 'src', 'app', 'public', '.agents',
27
- 'vendor', '.env', '.env.example', '.gitignore',
28
- 'composer.json', 'composer.lock', 'schema.sql',
29
- 'README.md', 'OKUBENI.md', 'LESEMICH.md', 'LISEZMOI.md', 'LEAME.md',
30
- 'kilavuz.html', 'guide.html', 'handbuch.html', 'guide_fr.html', 'guia.html', 'LICENSE',
31
- ];
32
-
33
- $entries = array_filter(scandir($dir), fn($e) => $e !== '.' && $e !== '..');
34
-
35
- usort($entries, function ($a, $b) use ($priorityOrder) {
36
- $ia = array_search($a, $priorityOrder);
37
- $ib = array_search($b, $priorityOrder);
38
- $ia = ($ia === false) ? 99 : $ia;
39
- $ib = ($ib === false) ? 99 : $ib;
40
- return $ia <=> $ib;
41
- });
42
-
43
- $entries = array_values($entries);
44
- $total = count($entries);
45
-
46
- foreach ($entries as $i => $entry) {
47
- $isLast = ($i === $total - 1);
48
- $connector = $isLast ? '└──' : '├──';
49
- $fullPath = $dir . DIRECTORY_SEPARATOR . $entry;
50
-
51
- if (is_dir($fullPath)) {
52
- $subItems = array_filter(scandir($fullPath), fn($e) => $e !== '.' && $e !== '..');
53
- $subCount = count($subItems);
54
- $countStr = $subCount > 0 ? ' ' . $this->translator->get('DIR_ITEM_COUNT', ['count' => $subCount]) : '';
55
- echo " │ {$connector} 📂 {$entry}/{$countStr}
56
- ";
57
- } else {
58
- $size = filesize($fullPath);
59
- $sizeStr = $size > 1024 ? round($size / 1024, 1) . ' KB' : $size . ' B';
60
- echo " │ {$connector} 📄 {$entry} [{$sizeStr}]
61
- ";
62
- }
63
- }
64
- echo " │
65
-
66
- ";
67
- }
68
- }
1
+ <?php
2
+ namespace ArtiFrame\Cli\Commands;
3
+
4
+ use ArtiFrame\Cli\Services\Translator;
5
+
6
+ class ListCommand
7
+ {
8
+ private Translator $translator;
9
+
10
+ public function __construct(Translator $translator)
11
+ {
12
+ $this->translator = $translator;
13
+ }
14
+
15
+ public function execute(array $args): void
16
+ {
17
+ $safeguard = new \ArtiFrame\Cli\Services\Safeguard($this->translator);
18
+ $dir = $safeguard->getProjectRoot();
19
+ $projectName = basename($dir);
20
+
21
+ echo "
22
+ 📂 " . $projectName . "/
23
+ ";
24
+
25
+ $priorityOrder = [
26
+ 'bin', 'config', 'src', 'app', 'public', '.agents',
27
+ 'vendor', '.env', '.env.example', '.gitignore',
28
+ 'composer.json', 'composer.lock', 'schema.sql',
29
+ 'README.md', 'OKUBENI.md', 'LESEMICH.md', 'LISEZMOI.md', 'LEAME.md',
30
+ 'kilavuz.html', 'guide.html', 'handbuch.html', 'guide_fr.html', 'guia.html', 'LICENSE',
31
+ ];
32
+
33
+ $entries = array_filter(scandir($dir), fn($e) => $e !== '.' && $e !== '..');
34
+
35
+ usort($entries, function ($a, $b) use ($priorityOrder) {
36
+ $ia = array_search($a, $priorityOrder);
37
+ $ib = array_search($b, $priorityOrder);
38
+ $ia = ($ia === false) ? 99 : $ia;
39
+ $ib = ($ib === false) ? 99 : $ib;
40
+ return $ia <=> $ib;
41
+ });
42
+
43
+ $entries = array_values($entries);
44
+ $total = count($entries);
45
+
46
+ foreach ($entries as $i => $entry) {
47
+ $isLast = ($i === $total - 1);
48
+ $connector = $isLast ? '└──' : '├──';
49
+ $fullPath = $dir . DIRECTORY_SEPARATOR . $entry;
50
+
51
+ if (is_dir($fullPath)) {
52
+ $subItems = array_filter(scandir($fullPath), fn($e) => $e !== '.' && $e !== '..');
53
+ $subCount = count($subItems);
54
+ $countStr = $subCount > 0 ? ' ' . $this->translator->get('DIR_ITEM_COUNT', ['count' => $subCount]) : '';
55
+ echo " │ {$connector} 📂 {$entry}/{$countStr}
56
+ ";
57
+ } else {
58
+ $size = filesize($fullPath);
59
+ $sizeStr = $size > 1024 ? round($size / 1024, 1) . ' KB' : $size . ' B';
60
+ echo " │ {$connector} 📄 {$entry} [{$sizeStr}]
61
+ ";
62
+ }
63
+ }
64
+ echo " │
65
+
66
+ ";
67
+ }
68
+ }