@artilingo/artiframe-cli 1.2.1 → 1.3.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.
@@ -276,7 +276,8 @@
276
276
  <a href="#cli-new">new</a>
277
277
  <a href="#cli-view">make:view</a>
278
278
  <a href="#cli-api">make:api</a>
279
- <a href="#cli-class">make:class</a>
279
+ <a href="#cli-class">make:class</a>
280
+ <a href="#cli-table">table:</a>
280
281
  <a href="#cli-cliv">cli v</a>
281
282
  <a href="#cli-show">show</a>
282
283
  <a href="#cli-list">list</a>
@@ -310,7 +311,8 @@
310
311
  <a href="#vh-maskemail">maskEmail()</a>
311
312
  <a href="#vh-maskphone">maskPhone()</a>
312
313
  <a href="#vh-slugify">slugify()</a>
313
- <a href="#vh-money">money()</a>
314
+ <a href="#vh-money">money()</a>
315
+ <a href="#vh-uuid">uuid()</a>
314
316
 
315
317
 
316
318
  <div class="sb-cat">System Helpers</div>
@@ -356,7 +358,8 @@
356
358
  <a href="#sh-formatid">formatId()</a>
357
359
  <a href="#sh-intid">intId()</a>
358
360
  <a href="#sh-bigintid">bigintId()</a>
359
- <a href="#sh-stringer">stringer()</a>
361
+ <a href="#sh-stringer">stringer()</a>
362
+ <a href="#sh-otpcoder">OTP Coder</a>
360
363
  <div class="sb-cat">API Güvenliği</div>
361
364
  <a href="#api-methods">HTTP Metod Kontrolü</a>
362
365
  <a href="#api-cors">CORS</a>
@@ -484,6 +487,14 @@
484
487
  }
485
488
  </script>
486
489
 
490
+
491
+ <h3 style="margin-top: 30px;">Ek Komutlar</h3>
492
+ <p><strong>Tabloları Listelemek:</strong> Mevcut tüm tablo şablonlarını ve açıklamalarını görmek için:</p>
493
+ <pre><code>artiframe&gt; <span class="fn">table</span> <span class="st">list</span></code></pre>
494
+
495
+ <p><strong>Tablo İçeriğini Önizlemek:</strong> Bir tabloyu <code>schema.sql</code> dosyasına eklemeden önce SQL içeriğini terminalde incelemek için komutun sonuna <code>check</code> parametresini ekleyebilirsiniz:</p>
496
+ <pre><code>artiframe&gt; <span class="fn">table:</span><span class="st">users</span> <span class="st">check</span></code></pre>
497
+
487
498
  </section>
488
499
 
489
500
  <!-- ====== KURULUM ====== -->
@@ -828,6 +839,99 @@ Example: /src/Service/PaymentService</code></pre>
828
839
 
829
840
 
830
841
 
842
+
843
+ <!-- table: -->
844
+ <section id="cli-table">
845
+ <h2><code>table:</code> <span class="tag b-cli">CLI Komutu</span></h2>
846
+ <p>Projenizdeki <code>schema.sql</code> dosyasına hızlıca standart ve ilişkisel veritabanı tablolarını eklemenizi sağlar. Şablonlar global <code>stubs/sql.stub</code> dosyasından okunur.</p>
847
+ <pre><code>artiframe&gt; <span class="fn">table:</span><span class="st">users</span></code></pre>
848
+ <p>Şu an desteklenen standart tablolar:</p>
849
+ <div class="table-tabs-container" style="margin-top: 20px;">
850
+ <div class="tabs-header" style="display: flex; gap: 10px; margin-bottom: 10px; overflow-x: auto; padding-bottom: 5px;">
851
+ <button class="table-tab-btn active" onclick="switchTableTab('tab-users', this)" style="white-space: nowrap; padding: 10px 20px; background: #00c88c; color: #000; font-weight: 600; border: none; border-radius: 5px; cursor: pointer;">users</button>
852
+ <button class="table-tab-btn" onclick="switchTableTab('tab-sessions', this)" style="white-space: nowrap; padding: 10px 20px; background: #1c2128; color: #fff; border: 1px solid #30363d; border-radius: 5px; cursor: pointer;">user_sessions</button>
853
+ <button class="table-tab-btn" onclick="switchTableTab('tab-prefs', this)" style="white-space: nowrap; padding: 10px 20px; background: #1c2128; color: #fff; border: 1px solid #30363d; border-radius: 5px; cursor: pointer;">user_preferences</button>
854
+ </div>
855
+
856
+ <!-- Tab: users -->
857
+ <div id="tab-users" class="table-tab-content" style="display: block;">
858
+ <pre><code><span class="kw">CREATE TABLE `users` (
859
+ `id` binary(16) NOT NULL,
860
+ `email` varchar(255) NOT NULL,
861
+ `password` varchar(255) NOT NULL,
862
+ `name` varchar(255) DEFAULT NULL,
863
+ `role` enum('user','admin','moderator') NOT NULL DEFAULT 'user',
864
+ `status` tinyint(1) NOT NULL DEFAULT '1',
865
+ `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
866
+ `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
867
+ PRIMARY KEY (`id`),
868
+ UNIQUE KEY `email` (`email`)
869
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;</span></code></pre>
870
+ </div>
871
+
872
+ <!-- Tab: user_sessions -->
873
+ <div id="tab-sessions" class="table-tab-content" style="display: none;">
874
+ <pre><code><span class="kw">CREATE TABLE `user_sessions` (
875
+ `id` binary(16) NOT NULL,
876
+ `user_id` binary(16) NOT NULL,
877
+ `token` varchar(255) NOT NULL,
878
+ `ip_address` varchar(45) DEFAULT NULL,
879
+ `user_agent` varchar(255) DEFAULT NULL,
880
+ `expires_at` timestamp NULL DEFAULT NULL,
881
+ `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
882
+ PRIMARY KEY (`id`),
883
+ UNIQUE KEY `token` (`token`),
884
+ KEY `user_id` (`user_id`),
885
+ CONSTRAINT `fk_user_sessions_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
886
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;</span></code></pre>
887
+ </div>
888
+
889
+ <!-- Tab: user_preferences -->
890
+ <div id="tab-prefs" class="table-tab-content" style="display: none;">
891
+ <pre><code><span class="kw">CREATE TABLE `user_preferences` (
892
+ `id` binary(16) NOT NULL,
893
+ `user_id` binary(16) NOT NULL,
894
+ `language` varchar(10) NOT NULL DEFAULT 'tr',
895
+ `theme` varchar(20) NOT NULL DEFAULT 'light',
896
+ `push_notifications` tinyint(1) NOT NULL DEFAULT '1',
897
+ `email_notifications` tinyint(1) NOT NULL DEFAULT '1',
898
+ `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
899
+ `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
900
+ PRIMARY KEY (`id`),
901
+ UNIQUE KEY `user_id` (`user_id`),
902
+ CONSTRAINT `fk_user_prefs_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
903
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;</span></code></pre>
904
+ </div>
905
+ </div>
906
+
907
+ <script>
908
+ function switchTableTab(tabId, btn) {
909
+ const container = btn.closest('.table-tabs-container');
910
+ container.querySelectorAll('.table-tab-content').forEach(el => el.style.display = 'none');
911
+ container.querySelectorAll('.table-tab-btn').forEach(el => {
912
+ el.style.background = '#1c2128';
913
+ el.style.color = '#fff';
914
+ el.style.border = '1px solid #30363d';
915
+ el.style.fontWeight = '400';
916
+ });
917
+
918
+ container.querySelector('#' + tabId).style.display = 'block';
919
+ btn.style.background = '#00c88c';
920
+ btn.style.color = '#000';
921
+ btn.style.fontWeight = '600';
922
+ btn.style.border = 'none';
923
+ }
924
+ </script>
925
+
926
+ <h3 style="margin-top: 30px;">Ek Komutlar</h3>
927
+ <p><strong>Tabloları Listelemek:</strong> Mevcut tüm tablo şablonlarını ve açıklamalarını görmek için:</p>
928
+ <pre><code>artiframe&gt; <span class="fn">table</span> <span class="st">list</span></code></pre>
929
+
930
+ <p><strong>Tablo İçeriğini Önizlemek:</strong> Bir tabloyu <code>schema.sql</code> dosyasına eklemeden önce SQL içeriğini terminalde incelemek için komutun sonuna <code>check</code> parametresini ekleyebilirsiniz:</p>
931
+ <pre><code>artiframe&gt; <span class="fn">table:</span><span class="st">users</span> <span class="st">check</span></code></pre>
932
+
933
+ </section>
934
+
831
935
  <!-- cli v -->
832
936
  <section id="cli-cliv">
833
937
  <h2><code>cli v</code> (veya <code>cli version</code>) <span class="tag b-cli">CLI Komutu</span></h2>
@@ -4461,7 +4565,15 @@ if ($response['status'] === 'success') {
4461
4565
 
4462
4566
  &lt;span&gt;&lt;?= <span class="fn">money</span>(<span class="var">$urun</span>[<span class="st">'fiyat'</span>], <span class="st">'usd'</span>) ?&gt;&lt;/span&gt;
4463
4567
  <span class="cm">&lt;!-- Çıktı: $1.250,00 --&gt;</span></code></pre>
4464
- </section>
4568
+ </section>
4569
+
4570
+ <section id="vh-uuid">
4571
+ <h2>View Helpers - <code>uuid()</code> <span class="tag b-view">ViewMethod</span></h2>
4572
+ <p>Veritabanından gelen 16 byte'lık binary UUID verisini 36 karakterlik formata çevirip ekrana XSS korumalı olarak basar.</p>
4573
+ <pre><code><span class="cm">&lt;!-- Çıktı: 0190ed84-3f12-7a91-8bc4-91823741abcd --&gt;</span>
4574
+ &lt;div&gt;<span class="kw">&lt;?=</span> <span class="fn">uuid</span>(<span class="var">$pull</span>[<span class="st">'id'</span>]) <span class="kw">?&gt;</span>&lt;/div&gt;</code></pre>
4575
+ </section>
4576
+
4465
4577
 
4466
4578
 
4467
4579
 
@@ -4519,6 +4631,31 @@ if ($response['status'] === 'success') {
4519
4631
  <span class="fn">jsonResponse</span>([<span class="st">'status'</span> =&gt; <span class="st">'error'</span>, <span class="st">'message'</span> =&gt; <span class="st">'Yetkisiz erişim.'</span>], <span class="nu">401</span>);</code></pre>
4520
4632
  </section>
4521
4633
 
4634
+
4635
+ <section id="sh-dd">
4636
+ <h2>System Helpers — <code>dd()</code> <span class="tag b-api">SystemMethod</span></h2>
4637
+ <p>Dump & Die. Geliştirme aşamasında değişkenleri ekrana koyu temalı (dark mode), okunabilir ve şık bir <code>&lt;pre&gt;</code> etiketi içinde basar ve kodun çalışmasını o satırda durdurur (exit). Sınırsız parametre (Variadic) alabilir.</p>
4638
+ <span class="ret">void dd(mixed ...$vars)</span>
4639
+ <pre><code><span class="fn">dd</span>(<span class="var">$_POST</span>, <span class="var">$kullanici_id</span>);
4640
+ <span class="cm">// Değerleri ekrana basar ve sistemi durdurur.</span></code></pre>
4641
+ </section>
4642
+
4643
+
4644
+ <!-- ====== ID GENERATION & UTILITIES ====== -->
4645
+ <section id="id-generation-utilities">
4646
+
4647
+ </section>
4648
+
4649
+
4650
+ <section id="sh-redirect">
4651
+ <h2>System Helpers — <code>redirect()</code> <span class="tag b-api">SystemMethod</span></h2>
4652
+ <span class="ret">void redirect(string $url)</span>
4653
+ <p>İstenilen sayfaya <code>header("Location: ...")</code> ile anında yönlendirme yapar ve çalışmayı durdurur (<code>exit</code>).</p>
4654
+ <pre><code><span class="kw">if</span> (!<span class="var">$isLoggedIn</span>) {
4655
+ <span class="fn">redirect</span>(<span class="st">'/login'</span>);
4656
+ }</code></pre>
4657
+ </section>
4658
+
4522
4659
  <section id="sh-generatecsrf">
4523
4660
  <h2>System Helpers — <code>generateCsrf()</code> <span class="tag b-api">SystemMethod</span></h2>
4524
4661
  <p>Oturum (Session) tabanlı 32 byte uzunluğunda yepyeni bir güvenli CSRF token üretir. Formlara gizli input olarak eklemek için <code>csrfField()</code> (View Helper) kullanılması önerilir.</p>
@@ -4623,14 +4760,7 @@ if ($response['status'] === 'success') {
4623
4760
  <pre><code><span class="var">$ip</span> = <span class="fn">getClientIp</span>(); <span class="cm">// Örn: 192.168.1.1</span></code></pre>
4624
4761
  </section>
4625
4762
 
4626
- <section id="sh-redirect">
4627
- <h2>System Helpers — <code>redirect()</code> <span class="tag b-api">SystemMethod</span></h2>
4628
- <span class="ret">void redirect(string $url)</span>
4629
- <p>İstenilen sayfaya <code>header("Location: ...")</code> ile anında yönlendirme yapar ve çalışmayı durdurur (<code>exit</code>).</p>
4630
- <pre><code><span class="kw">if</span> (!<span class="var">$isLoggedIn</span>) {
4631
- <span class="fn">redirect</span>(<span class="st">'/login'</span>);
4632
- }</code></pre>
4633
- </section>
4763
+
4634
4764
 
4635
4765
 
4636
4766
 
@@ -4698,19 +4828,10 @@ if ($response['status'] === 'success') {
4698
4828
  <span class="cm">// ID, rol gibi dışarıdan manipüle edilmiş değerler otomatik yok edilir.</span></code></pre>
4699
4829
  </section>
4700
4830
 
4701
- <section id="sh-dd">
4702
- <h2>System Helpers — <code>dd()</code> <span class="tag b-api">SystemMethod</span></h2>
4703
- <p>Dump & Die. Geliştirme aşamasında değişkenleri ekrana koyu temalı (dark mode), okunabilir ve şık bir <code>&lt;pre&gt;</code> etiketi içinde basar ve kodun çalışmasını o satırda durdurur (exit). Sınırsız parametre (Variadic) alabilir.</p>
4704
- <span class="ret">void dd(mixed ...$vars)</span>
4705
- <pre><code><span class="fn">dd</span>(<span class="var">$_POST</span>, <span class="var">$kullanici_id</span>);
4706
- <span class="cm">// Değerleri ekrana basar ve sistemi durdurur.</span></code></pre>
4707
- </section>
4708
-
4709
-
4710
- <!-- ====== ID GENERATION & UTILITIES ====== -->
4711
- <section id="id-generation-utilities">
4712
-
4713
- <h2 id="sh-byteid">System Helpers - <code>byteId()</code> <span class="tag b-api">SystemMethod</span></h2>
4831
+
4832
+
4833
+ <section id="sh-byteid">
4834
+ <h2>System Helpers - <code>byteId()</code> <span class="tag b-api">SystemMethod</span></h2>
4714
4835
  <div class="info-box">
4715
4836
  Native, yüksek performanslı ve sıralı (Time-ordered) raw 16-byte <strong>UUIDv7</strong> üretir.
4716
4837
  </div>
@@ -4727,7 +4848,10 @@ if ($response['status'] === 'success') {
4727
4848
  <span class="var">$db</span>-&gt;<span class="fn">prepare</span>(<span class="st">"INSERT INTO users (id, name) VALUES (?, ?)"</span>)-&gt;<span class="fn">execute</span>([<span class="var">$rawId</span>, <span class="st">'Utku'</span>]);</code></pre>
4728
4849
  </div>
4729
4850
 
4730
- <h2 id="sh-makeid">System Helpers - <code>makeId()</code> <span class="tag b-api">SystemMethod</span></h2>
4851
+ </section>
4852
+
4853
+ <section id="sh-makeid">
4854
+ <h2>System Helpers - <code>makeId()</code> <span class="tag b-api">SystemMethod</span></h2>
4731
4855
  <div class="info-box">
4732
4856
  Native, standart 36 karakterlik <strong>UUIDv7</strong> string'i üretir.
4733
4857
  </div>
@@ -4742,7 +4866,10 @@ if ($response['status'] === 'success') {
4742
4866
  <span class="cm">// Örnek Çıktı: 0190ed84-3f12-7a91-8bc4-91823741abcd</span></code></pre>
4743
4867
  </div>
4744
4868
 
4745
- <h2 id="sh-formatid">System Helpers - <code>formatId()</code> <span class="tag b-api">SystemMethod</span></h2>
4869
+ </section>
4870
+
4871
+ <section id="sh-formatid">
4872
+ <h2>System Helpers - <code>formatId()</code> <span class="tag b-api">SystemMethod</span></h2>
4746
4873
  <div class="info-box">
4747
4874
  Raw 16-byte binary UUID'leri 36 karakterlik standart string'e dönüştürür.
4748
4875
  </div>
@@ -4758,7 +4885,10 @@ if ($response['status'] === 'success') {
4758
4885
  <span class="cm">// Örnek Çıktı: 0190ed84-3f12-7a91-8bc4-91823741abcd</span></code></pre>
4759
4886
  </div>
4760
4887
 
4761
- <h2 id="sh-intid">System Helpers - <code>intId()</code> <span class="tag b-api">SystemMethod</span></h2>
4888
+ </section>
4889
+
4890
+ <section id="sh-intid">
4891
+ <h2>System Helpers - <code>intId()</code> <span class="tag b-api">SystemMethod</span></h2>
4762
4892
  <div class="info-box">
4763
4893
  Güvenli, rastgele <code>INT</code> ID üretir. (Max 9 Hane)
4764
4894
  </div>
@@ -4771,7 +4901,10 @@ if ($response['status'] === 'success') {
4771
4901
  <span class="cm">// Örnek Çıktı: 49201834</span></code></pre>
4772
4902
  </div>
4773
4903
 
4774
- <h2 id="sh-bigintid">System Helpers - <code>bigintId()</code> <span class="tag b-api">SystemMethod</span></h2>
4904
+ </section>
4905
+
4906
+ <section id="sh-bigintid">
4907
+ <h2>System Helpers - <code>bigintId()</code> <span class="tag b-api">SystemMethod</span></h2>
4775
4908
  <div class="info-box">
4776
4909
  Güvenli, rastgele <code>BIGINT</code> ID üretir. (Varsayılan 15 hane - JS için güvenli sınır)
4777
4910
  </div>
@@ -4784,7 +4917,10 @@ if ($response['status'] === 'success') {
4784
4917
  <span class="var">$massiveId</span> = <span class="fn">bigintId</span>(18, <span class="kw">true</span>); <span class="cm">// 18 haneli STRING döner (JS için güvenli)</span></code></pre>
4785
4918
  </div>
4786
4919
 
4787
- <h2 id="sh-stringer">System Helpers - <code>stringer()</code> <span class="tag b-api">SystemMethod</span></h2>
4920
+ </section>
4921
+
4922
+ <section id="sh-stringer">
4923
+ <h2>System Helpers - <code>stringer()</code> <span class="tag b-api">SystemMethod</span></h2>
4788
4924
  <div class="info-box">
4789
4925
  Değerleri Javascript'in devasa sayı (BIGINT) duyarsızlığına karşı güvenli bir şekilde string'e sarmalar.
4790
4926
  </div>
@@ -4797,6 +4933,24 @@ if ($response['status'] === 'success') {
4797
4933
  &lt;button data-id=<span class="st">"&lt;?=</span> <span class="fn">stringer</span>(<span class="var">$data</span>[<span class="st">'id'</span>]) <span class="st">?&gt;"</span>&gt;Sil&lt;/button&gt;</code></pre>
4798
4934
  </div>
4799
4935
 
4936
+
4937
+
4938
+ <section id="sh-otpcoder">
4939
+ <h2>System Helpers - OTP Coder <span class="tag b-api">SystemMethod</span></h2>
4940
+ <div class="info-box">Rastgele, kriptografik olarak güvenli Doğrulama Kodları (OTP) üretir.</div>
4941
+ <div class="code-block">
4942
+ <pre><code><span class="cm">// 6 haneli rastgele sayı</span>
4943
+ <span class="var">$code</span> = <span class="fn">otpInt</span>(<span class="nu">6</span>); <span class="cm">// 482910</span>
4944
+
4945
+ <span class="cm">// 8 haneli sadece harf ('c': küçük, 'C': büyük, 'cC': karışık)</span>
4946
+ <span class="var">$code</span> = <span class="fn">otpStr</span>(<span class="nu">8</span>, <span class="st">'C'</span>); <span class="cm">// PKLMDZRA</span>
4947
+
4948
+ <span class="cm">// 6 haneli harf+sayı (Alphanumeric)</span>
4949
+ <span class="var">$code</span> = <span class="fn">otpMix</span>(<span class="nu">6</span>, <span class="st">'C'</span>); <span class="cm">// 9A4X2Z</span></code></pre>
4950
+ </div>
4951
+ </section>
4952
+
4953
+
4800
4954
  </section>
4801
4955
 
4802
4956
  <!-- ====== API GÜVENLİĞİ ====== -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artilingo/artiframe-cli",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "description": "ArtiFrame — Zero-dependency native PHP framework with a powerful multilingual CLI. Scaffold projects, generate views, APIs and classes instantly.",
5
5
  "main": "bin/artiframe.js",
6
6
  "bin": {
package/src/App.php CHANGED
@@ -170,6 +170,17 @@ class App
170
170
 
171
171
  private function routeCommand(string $commandName, array $commandArgs): void
172
172
  {
173
+ if (strpos($commandName, 'table:') === 0) {
174
+ $tableName = substr($commandName, 6);
175
+ (new \ArtiFrame\Cli\Commands\TableCommand($this->translator))->execute(array_merge([$tableName], $commandArgs));
176
+ return;
177
+ }
178
+
179
+ if ($commandName === 'table' && !empty($commandArgs) && $commandArgs[0] === 'list') {
180
+ (new \ArtiFrame\Cli\Commands\TableCommand($this->translator))->execute(['list']);
181
+ return;
182
+ }
183
+
173
184
  switch ($commandName) {
174
185
 
175
186
 
@@ -302,7 +313,13 @@ class App
302
313
  // make:class
303
314
  echo " " . $g . "make:class" . $r . " " . $y . "<path>" . $r . PHP_EOL;
304
315
  echo " " . $d . "│" . $r . " " . $t->get('HELP_MAKECLASS_DESC') . PHP_EOL;
305
- echo " " . $d . "└── " . $r . "Example: " . $lg . "make:class app/Services/UserManager.php" . $r . PHP_EOL;
316
+ echo " " . $d . "└─ " . $r . "Example: " . $lg . "make:class app/Services/UserManager.php" . $r . PHP_EOL;
317
+ echo PHP_EOL;
318
+
319
+ // table
320
+ echo " " . $g . "table:<table>" . $r . PHP_EOL;
321
+ echo " " . $d . "│" . $r . " " . $t->get('HELP_TABLE_DESC') . PHP_EOL;
322
+ echo " " . $d . "└─ " . $r . "Example: " . $lg . "table:users" . $r . PHP_EOL;
306
323
  echo PHP_EOL;
307
324
 
308
325
  // cli v / cli version — CLI self-version
@@ -0,0 +1,82 @@
1
+ <?php
2
+ namespace ArtiFrame\Cli\Commands;
3
+
4
+ use ArtiFrame\Cli\Services\Translator;
5
+ use ArtiFrame\Cli\Services\Safeguard;
6
+
7
+ class TableCommand
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
+ $tableName = $args[0] ?? null;
21
+ $action = $args[1] ?? null;
22
+
23
+ if (!$tableName) {
24
+ echo "❌ " . $this->translator->get('ERROR_TABLE_NAME_REQUIRED') . PHP_EOL;
25
+ return;
26
+ }
27
+
28
+ $stubPath = \ARTIFRAME_CLI_ROOT . '/stubs/sql.stub';
29
+
30
+ if (!file_exists($stubPath)) {
31
+ echo "❌ " . $this->translator->get('ERROR_STUB_NOT_FOUND') . PHP_EOL;
32
+ return;
33
+ }
34
+
35
+ $stubContent = file_get_contents($stubPath);
36
+
37
+ // table list
38
+ if ($tableName === 'list') {
39
+ echo "\033[1;36m" . $this->translator->get('TABLE_LIST_HEADER') . "\033[0m" . PHP_EOL;
40
+ preg_match_all('/-- \[TABLE:(.*?)\]/s', $stubContent, $matches);
41
+
42
+ if (!empty($matches[1])) {
43
+ foreach ($matches[1] as $table) {
44
+ $descKey = 'TABLE_DESC_' . strtoupper($table);
45
+ $desc = $this->translator->get($descKey);
46
+ if ($desc === $descKey) {
47
+ $desc = '-';
48
+ }
49
+ echo " \033[0;32m" . str_pad($table, 20) . "\033[0m : " . $desc . PHP_EOL;
50
+ }
51
+ }
52
+ return;
53
+ }
54
+
55
+ $pattern = "/-- \[TABLE:{$tableName}\](.*?)-- \[\/TABLE:{$tableName}\]/s";
56
+
57
+ if (!preg_match($pattern, $stubContent, $matches)) {
58
+ echo "❌ " . sprintf($this->translator->get('ERROR_TABLE_NOT_IN_STUB'), $tableName) . PHP_EOL;
59
+ return;
60
+ }
61
+
62
+ $tableContent = trim($matches[1]);
63
+
64
+ // table:name check
65
+ if ($action === 'check') {
66
+ echo "\033[1;33m--- SQL FOR `{$tableName}` ---\033[0m" . PHP_EOL;
67
+ echo $tableContent . PHP_EOL;
68
+ echo "\033[1;33m---------------------------\033[0m" . PHP_EOL;
69
+ return;
70
+ }
71
+
72
+ $schemaPath = getcwd() . '/schema.sql';
73
+
74
+ if (!file_exists($schemaPath)) {
75
+ file_put_contents($schemaPath, "-- ArtiFrame DB Schema\n-- Created: " . date('Y-m-d') . "\n");
76
+ }
77
+
78
+ file_put_contents($schemaPath, "\n" . $tableContent . "\n", FILE_APPEND);
79
+
80
+ echo "✅ " . sprintf($this->translator->get('SUCCESS_TABLE_ADDED'), $tableName) . PHP_EOL;
81
+ }
82
+ }
package/src/Lang/de.php CHANGED
@@ -166,4 +166,16 @@ return [
166
166
  'MODE_INVALID' => 'Ungültiger Modus. Verwenden Sie 1 für Debug, 0 für Prod.',
167
167
  'MODE_NOT_PROJECT' => 'ArtiFrame-Projekt nicht gefunden (config/app-version.php fehlt).',
168
168
  'HELP_MODE_DESC' => 'Ändert den Anwendungsmodus (0=Prod, 1=Debug)',
169
+
170
+ // Table
171
+ 'ERROR_TABLE_NAME_REQUIRED' => 'Tabellenname ist erforderlich.',
172
+ 'ERROR_STUB_NOT_FOUND' => 'sql.stub Datei konnte nicht gefunden werden.',
173
+ 'ERROR_TABLE_NOT_IN_STUB' => 'Tabellendefinition \'%s\' nicht in der Stub-Datei gefunden.',
174
+ 'SUCCESS_TABLE_ADDED' => 'Tabelle \'%s\' erfolgreich an schema.sql angehängt.',
175
+ 'HELP_TABLE_DESC' => 'Hängt ein Standard-Tabellenschema aus sql.stub an schema.sql an.',
176
+ 'TABLE_LIST_HEADER' => 'Unterstützte Tabellen:',
177
+ 'TABLE_DESC_USERS' => 'Basis-Benutzer- und Autorisierungstabelle (UUID).',
178
+ 'TABLE_DESC_USER_SESSIONS' => 'Benutzersitzungen (IP, Gerät, Token) verfolgen.',
179
+ 'TABLE_DESC_USER_PREFERENCES' => 'Benutzereinstellungen (Sprache, Thema, Benachrichtigungen).',
180
+
169
181
  ];
package/src/Lang/en.php CHANGED
@@ -166,4 +166,16 @@ return [
166
166
  'MODE_INVALID' => 'Invalid mode. Use 1 for Debug, 0 for Prod.',
167
167
  'MODE_NOT_PROJECT' => 'ArtiFrame project not found (config/app-version.php missing).',
168
168
  'HELP_MODE_DESC' => 'Changes the application mode (0=Prod, 1=Debug)',
169
+
170
+ // Table
171
+ 'ERROR_TABLE_NAME_REQUIRED' => 'Table name is required.',
172
+ 'ERROR_STUB_NOT_FOUND' => 'sql.stub file could not be found.',
173
+ 'ERROR_TABLE_NOT_IN_STUB' => 'Table definition \'%s\' not found in stub file.',
174
+ 'SUCCESS_TABLE_ADDED' => 'Table \'%s\' successfully appended to schema.sql',
175
+ 'HELP_TABLE_DESC' => 'Appends a standard table schema from sql.stub to schema.sql',
176
+ 'TABLE_LIST_HEADER' => 'Supported Tables:',
177
+ 'TABLE_DESC_USERS' => 'Basic user and authorization table (UUID).',
178
+ 'TABLE_DESC_USER_SESSIONS' => 'User sessions (IP, device, token) tracking.',
179
+ 'TABLE_DESC_USER_PREFERENCES' => 'User preferences (language, theme, notifications).',
180
+
169
181
  ];
package/src/Lang/es.php CHANGED
@@ -166,4 +166,16 @@ return [
166
166
  'MODE_INVALID' => 'Modo no válido. Use 1 para Depuración, 0 para Producción.',
167
167
  'MODE_NOT_PROJECT' => 'Proyecto ArtiFrame no encontrado (falta config/app-version.php).',
168
168
  'HELP_MODE_DESC' => 'Cambia el modo de la aplicación (0=Prod, 1=Debug)',
169
+
170
+ // Table
171
+ 'ERROR_TABLE_NAME_REQUIRED' => 'El nombre de la tabla es obligatorio.',
172
+ 'ERROR_STUB_NOT_FOUND' => 'No se pudo encontrar el archivo sql.stub.',
173
+ 'ERROR_TABLE_NOT_IN_STUB' => 'Definición de tabla \'%s\' no encontrada en el archivo stub.',
174
+ 'SUCCESS_TABLE_ADDED' => 'Tabla \'%s\' añadida con éxito a schema.sql',
175
+ 'HELP_TABLE_DESC' => 'Añade un esquema de tabla estándar de sql.stub a schema.sql',
176
+ 'TABLE_LIST_HEADER' => 'Tablas compatibles:',
177
+ 'TABLE_DESC_USERS' => 'Tabla básica de usuarios y autorización (UUID).',
178
+ 'TABLE_DESC_USER_SESSIONS' => 'Seguimiento de sesiones de usuario (IP, dispositivo, token).',
179
+ 'TABLE_DESC_USER_PREFERENCES' => 'Preferencias de usuario (idioma, tema, notificaciones).',
180
+
169
181
  ];
package/src/Lang/fr.php CHANGED
@@ -166,4 +166,16 @@ return [
166
166
  'MODE_INVALID' => 'Mode invalide. Utilisez 1 pour Débogage, 0 pour Production.',
167
167
  'MODE_NOT_PROJECT' => 'Projet ArtiFrame introuvable (config/app-version.php manquant).',
168
168
  'HELP_MODE_DESC' => 'Modifie le mode de l\'application (0=Prod, 1=Debug)',
169
+
170
+ // Table
171
+ 'ERROR_TABLE_NAME_REQUIRED' => 'Le nom de la table est requis.',
172
+ 'ERROR_STUB_NOT_FOUND' => 'Le fichier sql.stub est introuvable.',
173
+ 'ERROR_TABLE_NOT_IN_STUB' => 'La définition de la table \'%s\' est introuvable dans le fichier stub.',
174
+ 'SUCCESS_TABLE_ADDED' => 'Table \'%s\' ajoutée avec succès à schema.sql',
175
+ 'HELP_TABLE_DESC' => 'Ajoute un schéma de table standard de sql.stub à schema.sql',
176
+ 'TABLE_LIST_HEADER' => 'Tables prises en charge :',
177
+ 'TABLE_DESC_USERS' => 'Table de base pour les utilisateurs et l\'autorisation (UUID).',
178
+ 'TABLE_DESC_USER_SESSIONS' => 'Suivi des sessions utilisateur (IP, appareil, token).',
179
+ 'TABLE_DESC_USER_PREFERENCES' => 'Préférences de l\'utilisateur (langue, thème, notifications).',
180
+
169
181
  ];
package/src/Lang/tr.php CHANGED
@@ -166,4 +166,16 @@ return [
166
166
  'MODE_INVALID' => 'Hatalı mod. Debug için 1, Prod için 0 kullanın.',
167
167
  'MODE_NOT_PROJECT' => 'ArtiFrame projesi bulunamadı (config/app-version.php eksik).',
168
168
  'HELP_MODE_DESC' => 'Uygulama çalışma modunu değiştirir (0=Prod, 1=Debug)',
169
+
170
+ // Table
171
+ 'ERROR_TABLE_NAME_REQUIRED' => 'Tablo adı gerekli.',
172
+ 'ERROR_STUB_NOT_FOUND' => 'sql.stub dosyası bulunamadı.',
173
+ 'ERROR_TABLE_NOT_IN_STUB' => '\'%s\' tablo şablonu stub dosyasında bulunamadı.',
174
+ 'SUCCESS_TABLE_ADDED' => '\'%s\' tablosu başarıyla schema.sql dosyasına eklendi.',
175
+ 'HELP_TABLE_DESC' => 'sql.stub dosyasındaki standart tablo yapılarını schema.sql\'e ekler.',
176
+ 'TABLE_LIST_HEADER' => 'Desteklenen Tablolar:',
177
+ 'TABLE_DESC_USERS' => 'Temel kullanıcı ve yetkilendirme tablosu (UUID).',
178
+ 'TABLE_DESC_USER_SESSIONS' => 'Kullanıcı oturumları (IP, cihaz, token) takibi.',
179
+ 'TABLE_DESC_USER_PREFERENCES' => 'Kullanıcı tercihleri (dil, tema, bildirimler).',
180
+
169
181
  ];
package/stubs/sql.stub ADDED
@@ -0,0 +1,46 @@
1
+ -- [TABLE:users]
2
+ CREATE TABLE `users` (
3
+ `id` binary(16) NOT NULL,
4
+ `email` varchar(255) NOT NULL,
5
+ `password` varchar(255) NOT NULL,
6
+ `name` varchar(255) DEFAULT NULL,
7
+ `role` enum('user','admin','moderator') NOT NULL DEFAULT 'user',
8
+ `status` tinyint(1) NOT NULL DEFAULT '1',
9
+ `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
10
+ `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
11
+ PRIMARY KEY (`id`),
12
+ UNIQUE KEY `email` (`email`)
13
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
14
+ -- [/TABLE:users]
15
+
16
+ -- [TABLE:user_sessions]
17
+ CREATE TABLE `user_sessions` (
18
+ `id` binary(16) NOT NULL,
19
+ `user_id` binary(16) NOT NULL,
20
+ `token` varchar(255) NOT NULL,
21
+ `ip_address` varchar(45) DEFAULT NULL,
22
+ `user_agent` varchar(255) DEFAULT NULL,
23
+ `expires_at` timestamp NULL DEFAULT NULL,
24
+ `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
25
+ PRIMARY KEY (`id`),
26
+ UNIQUE KEY `token` (`token`),
27
+ KEY `user_id` (`user_id`),
28
+ CONSTRAINT `fk_user_sessions_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
29
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
30
+ -- [/TABLE:user_sessions]
31
+
32
+ -- [TABLE:user_preferences]
33
+ CREATE TABLE `user_preferences` (
34
+ `id` binary(16) NOT NULL,
35
+ `user_id` binary(16) NOT NULL,
36
+ `language` varchar(10) NOT NULL DEFAULT 'tr',
37
+ `theme` varchar(20) NOT NULL DEFAULT 'light',
38
+ `push_notifications` tinyint(1) NOT NULL DEFAULT '1',
39
+ `email_notifications` tinyint(1) NOT NULL DEFAULT '1',
40
+ `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
41
+ `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
42
+ PRIMARY KEY (`id`),
43
+ UNIQUE KEY `user_id` (`user_id`),
44
+ CONSTRAINT `fk_user_prefs_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
45
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
46
+ -- [/TABLE:user_preferences]