@artilingo/artiframe-cli 2.0.4 → 2.0.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 (90) hide show
  1. package/LICENSE +660 -660
  2. package/bin/artiframe.js +0 -0
  3. package/bin/artiframe.php +0 -0
  4. package/core-stubs/app/ApiAuthControl.php +76 -0
  5. package/core-stubs/app/ApiControl.php +81 -35
  6. package/core-stubs/app/AuthControl.php +39 -0
  7. package/core-stubs/app/Database.php +36 -35
  8. package/core-stubs/app/DotEnv.php +19 -1
  9. package/core-stubs/app/ViewControl.php +47 -1
  10. package/core-stubs/bin/SQLMethod.php +261 -0
  11. package/core-stubs/bin/SystemMethod.php +115 -74
  12. package/core-stubs/bin/ViewMethod.php +19 -5
  13. package/core-stubs/docs/de.html +4325 -4347
  14. package/core-stubs/docs/en.html +4325 -4347
  15. package/core-stubs/docs/es.html +4325 -4347
  16. package/core-stubs/docs/fr.html +4325 -4347
  17. package/core-stubs/docs/tr.html +117 -46
  18. package/core-stubs/public/403.php +52 -0
  19. package/core-stubs/public/assets/css/components/header.css +174 -0
  20. package/core-stubs/public/assets/css/components/mobilenav.css +198 -0
  21. package/core-stubs/public/assets/css/components/sidebar.css +184 -0
  22. package/core-stubs/public/assets/css/root/app.css +975 -38
  23. package/core-stubs/public/assets/css/root/root.css +64 -0
  24. package/core-stubs/public/assets/js/components/header.js +380 -0
  25. package/core-stubs/public/assets/js/components/mobilenav.js +97 -0
  26. package/core-stubs/public/assets/js/components/theme-modal.js +74 -0
  27. package/core-stubs/public/assets/js/root/app.js +1870 -0
  28. package/core-stubs/public/includes/footer.php +4 -5
  29. package/core-stubs/public/includes/head-auth.php +65 -0
  30. package/core-stubs/public/includes/head.php +56 -17
  31. package/core-stubs/public/includes/header.php +135 -1
  32. package/core-stubs/public/includes/mobilenav.php +75 -3
  33. package/core-stubs/public/includes/sidebar.php +186 -1
  34. package/core-stubs/public/includes/theme-modal.php +1 -0
  35. package/db-studio/debug.log +3 -0
  36. package/db-studio/index.html +1755 -0
  37. package/db-studio/launcher.html +102 -0
  38. package/db-studio/launcher.js +180 -0
  39. package/db-studio/logo.svg +22 -0
  40. package/db-studio/main.js +568 -0
  41. package/db-studio/package-lock.json +1034 -0
  42. package/db-studio/package.json +16 -0
  43. package/db-studio/preload.js +29 -0
  44. package/devops-studio/api-inspector.js +222 -0
  45. package/devops-studio/index.html +1892 -0
  46. package/devops-studio/logo.svg +22 -0
  47. package/devops-studio/main.js +67 -0
  48. package/devops-studio/make-wizard.js +635 -0
  49. package/devops-studio/package-lock.json +871 -0
  50. package/devops-studio/package.json +12 -0
  51. package/package.json +5 -2
  52. package/scripts/postinstall.js +44 -8
  53. package/server-studio/.json-404-guard +1 -0
  54. package/server-studio/index.html +283 -0
  55. package/server-studio/logo.svg +22 -0
  56. package/server-studio/main.js +133 -0
  57. package/server-studio/package-lock.json +1179 -0
  58. package/server-studio/package.json +15 -0
  59. package/server-studio/router.php +99 -0
  60. package/src/App.php +29 -0
  61. package/src/Commands/AddCommand.php +26 -9
  62. package/src/Commands/DbExportCommand.php +131 -0
  63. package/src/Commands/DbStartCommand.php +46 -0
  64. package/src/Commands/DevopsCommand.php +35 -0
  65. package/src/Commands/GoCommand.php +48 -48
  66. package/src/Commands/ListCommand.php +68 -68
  67. package/src/Commands/MakeApiCommand.php +6 -1
  68. package/src/Commands/MakeViewCommand.php +25 -2
  69. package/src/Commands/NewProjectCommand.php +16 -11
  70. package/src/Commands/OptimizeCommand.php +61 -0
  71. package/src/Commands/RemoveCommand.php +35 -7
  72. package/src/Commands/ServeCommand.php +46 -91
  73. package/src/Commands/ShowCommand.php +24 -24
  74. package/src/Commands/UpgradeCommand.php +39 -10
  75. package/stubs/make/api-switch-case.stub +1 -1
  76. package/stubs/make/auth-api-standart.stub +20 -0
  77. package/stubs/make/auth-api-switch-case.stub +38 -0
  78. package/stubs/make/auth-view.stub +26 -0
  79. package/stubs/make/class.stub +10 -2
  80. package/stubs/make/view.stub +3 -0
  81. package/stubs/service/image.stub +334 -334
  82. package/stubs/service/iyzico.stub +637 -637
  83. package/stubs/service/jwt.stub +312 -312
  84. package/stubs/service/phpmailer.stub +143 -143
  85. package/stubs/service/pusher.stub +232 -232
  86. package/stubs/service/qrcode.stub +169 -169
  87. package/stubs/service/redis.stub +361 -361
  88. package/stubs/service/s3.stub +377 -377
  89. package/stubs/service/stripe.stub +526 -526
  90. package/stubs/service/twilio.stub +361 -361
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "artiframe-db-studio",
3
+ "version": "1.0.0",
4
+ "main": "main.js",
5
+ "scripts": {
6
+ "start": "electron ."
7
+ },
8
+ "dependencies": {
9
+ "@faker-js/faker": "^10.6.0",
10
+ "dotenv": "^16.3.1",
11
+ "mysql2": "^3.6.1"
12
+ },
13
+ "devDependencies": {
14
+ "electron": "^26.2.2"
15
+ }
16
+ }
@@ -0,0 +1,29 @@
1
+ const { contextBridge, ipcRenderer } = require('electron');
2
+
3
+ contextBridge.exposeInMainWorld('api', {
4
+ getAppMode: () => ipcRenderer.invoke('get-app-mode'),
5
+
6
+ previewSchemaFile: (schemaJson) => ipcRenderer.invoke('preview-schema-file', schemaJson),
7
+
8
+
9
+ saveArtiframeFile: (globalDbData) => ipcRenderer.invoke('save-artiframe-file', globalDbData),
10
+ loadArtiframeFile: () => ipcRenderer.invoke('load-artiframe-file'),
11
+
12
+ getWorkspace: () => ipcRenderer.invoke('get-workspace'),
13
+ setWorkspace: (dirPath) => ipcRenderer.invoke('set-workspace', dirPath),
14
+ selectDirectory: () => ipcRenderer.invoke('select-directory'),
15
+ getProjects: (workspacePath) => ipcRenderer.invoke('get-projects', workspacePath),
16
+ openProject: (pPath) => ipcRenderer.invoke('open-project', pPath),
17
+
18
+ getSchema: () => ipcRenderer.invoke('get-schema'),
19
+ onAppMode: (callback) => ipcRenderer.on('set-app-mode', (event, data) => callback(data)),
20
+ restartOffline: () => ipcRenderer.invoke('restart-offline'),
21
+ scaffoldProject: (dirName, schemaJson, customWorkspace) => ipcRenderer.invoke('scaffold-project', dirName, schemaJson, customWorkspace),
22
+
23
+ executeSql: (sql) => ipcRenderer.invoke('execute-sql', sql),
24
+ saveLayout: (layoutData) => ipcRenderer.invoke('save-layout', layoutData),
25
+ getTableData: (tableName, limit, offset) => ipcRenderer.invoke('get-table-data', tableName, limit, offset),
26
+ updateRow: (tableName, pkCol, pkVal, data) => ipcRenderer.invoke('update-row', tableName, pkCol, pkVal, data),
27
+ deleteRow: (tableName, pkCol, pkVal) => ipcRenderer.invoke('delete-row', tableName, pkCol, pkVal),
28
+ seedTable: (tableName, columns, count) => ipcRenderer.invoke('seed-table', tableName, columns, count)
29
+ });
@@ -0,0 +1,222 @@
1
+ const http = require('http'); // Node http for fetching csrf token if needed
2
+
3
+ function renderApiInspector(relPath, content) {
4
+ const container = document.getElementById('api-inspector-container');
5
+ const pathLabel = document.getElementById('api-inspector-path');
6
+
7
+ if (!relPath.startsWith('public/api') || !relPath.endsWith('.php')) {
8
+ pathLabel.innerText = "Sadece public/api altındaki PHP dosyaları test edilebilir.";
9
+ container.innerHTML = '<div style="flex:1; display:flex; align-items:center; justify-content:center; color:#8b949e; font-size:13px; text-align:center;">Lütfen public/api klasöründen bir API dosyası seçin.</div>';
10
+ return;
11
+ }
12
+
13
+ pathLabel.innerText = relPath;
14
+
15
+ // Load APP_URL from .env
16
+ const envPath = path.join(currentCwd, '.env');
17
+ let appUrl = 'http://localhost:9002';
18
+ if (fs.existsSync(envPath)) {
19
+ const envContent = fs.readFileSync(envPath, 'utf8');
20
+ const urlMatch = envContent.match(/^APP_URL=(.*)$/m);
21
+ if (urlMatch) {
22
+ appUrl = urlMatch[1].trim();
23
+ }
24
+ }
25
+ const urlInput = document.getElementById('api-base-url');
26
+ if (urlInput.value === 'http://localhost:9002') {
27
+ urlInput.value = appUrl;
28
+ }
29
+
30
+ // Determine Endpoint Route
31
+ // e.g. public/api/auth/login.php -> /api/auth/login
32
+ let route = relPath.replace('public/', '/').replace('.php', '');
33
+
34
+ // Smart Parsing
35
+ const params = [];
36
+ // Match $_POST['...'], $_GET['...'], $_REQUEST['...']
37
+ const paramRegex = /\$_(POST|GET|REQUEST)\s*\[\s*['"]([a-zA-Z0-9_]+)['"]\s*\]/g;
38
+ let pMatch;
39
+ const foundKeys = new Set();
40
+
41
+ while ((pMatch = paramRegex.exec(content)) !== null) {
42
+ const type = pMatch[1];
43
+ const key = pMatch[2];
44
+ if (!foundKeys.has(key)) {
45
+ foundKeys.add(key);
46
+ // Try to infer type
47
+ let inputType = 'text';
48
+ if (key.toLowerCase().includes('password') || key.toLowerCase().includes('sifre')) {
49
+ inputType = 'password';
50
+ } else if (key.toLowerCase().includes('mail')) {
51
+ inputType = 'email';
52
+ }
53
+ params.push({ key, type, inputType });
54
+ }
55
+ }
56
+
57
+ // Build UI
58
+ let uiHtml = `
59
+ <div style="width:350px; background:#161b22; border:1px solid #30363d; border-radius:8px; display:flex; flex-direction:column; flex-shrink:0;">
60
+ <div style="padding:15px; border-bottom:1px solid #30363d; display:flex; gap:10px;">
61
+ <select id="api-method" style="background:#0d1117; border:1px solid #30363d; color:#58a6ff; font-weight:bold; border-radius:4px; padding:6px; outline:none; font-size:12px;">
62
+ <option value="POST" selected>POST</option>
63
+ <option value="GET">GET</option>
64
+ <option value="PUT">PUT</option>
65
+ <option value="DELETE">DELETE</option>
66
+ </select>
67
+ <input type="text" id="api-route" value="${route}" style="flex:1; background:#0d1117; border:1px solid #30363d; color:#c9d1d9; border-radius:4px; padding:6px 10px; font-size:12px; outline:none; font-family:monospace;">
68
+ </div>
69
+
70
+ <div style="flex:1; overflow-y:auto; padding:15px; display:flex; flex-direction:column; gap:15px;" id="api-params-form">
71
+ <div style="font-size:12px; font-weight:bold; color:#f0f6fc; margin-bottom:5px;">Otomatik Çıkarılan Parametreler</div>
72
+ ${params.length === 0 ? '<div style="color:#8b949e; font-size:12px; font-style:italic;">Parametre bulunamadı.</div>' : ''}
73
+ ${params.map(p => `
74
+ <div style="display:flex; flex-direction:column; gap:4px;">
75
+ <label style="color:#8b949e; font-size:11px; display:flex; justify-content:space-between;">
76
+ <span style="font-family:monospace; color:#c9d1d9;">${p.key}</span>
77
+ <span style="color:#3fb950; font-size:10px;">$_${p.type}</span>
78
+ </label>
79
+ <input type="${p.inputType}" data-param="${p.key}" class="api-param-input" placeholder="Değer..." style="background:#0d1117; border:1px solid #30363d; color:#c9d1d9; border-radius:4px; padding:8px 10px; font-size:12px; outline:none; transition:border 0.2s;">
80
+ </div>
81
+ `).join('')}
82
+
83
+ <div style="margin-top:10px; border-top:1px dashed #30363d; padding-top:15px;">
84
+ <div style="font-size:12px; font-weight:bold; color:#f0f6fc; margin-bottom:10px;">DevOps Sihri</div>
85
+ <label style="display:flex; align-items:center; gap:8px; font-size:12px; color:#8b949e; cursor:pointer;">
86
+ <input type="checkbox" id="api-auto-csrf" checked style="accent-color:#58a6ff;">
87
+ CSRF Token'ı otomatik çek ve ekle
88
+ </label>
89
+ </div>
90
+ </div>
91
+
92
+ <div style="padding:15px; border-top:1px solid #30363d; background:#0d1117; border-radius:0 0 8px 8px;">
93
+ <button onclick="executeApiRequest()" style="width:100%; background:#238636; color:#fff; border:none; padding:10px; border-radius:6px; font-weight:bold; cursor:pointer; font-size:13px; display:flex; align-items:center; justify-content:center; gap:8px;">
94
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
95
+ GÖNDER (TEST ET)
96
+ </button>
97
+ </div>
98
+ </div>
99
+
100
+ <div style="flex:1; background:#0d1117; border:1px solid #30363d; border-radius:8px; display:flex; flex-direction:column; overflow:hidden;">
101
+ <div style="padding:10px 15px; border-bottom:1px solid #30363d; background:#161b22; display:flex; justify-content:space-between; align-items:center;">
102
+ <div style="font-size:12px; font-weight:bold; color:#f0f6fc;">Yanıt Görüntüleyici (Response)</div>
103
+ <div style="display:flex; gap:15px; font-size:11px; font-family:monospace; color:#8b949e;">
104
+ <div id="api-res-status">Durum: Bekleniyor</div>
105
+ <div id="api-res-time">Süre: -</div>
106
+ </div>
107
+ </div>
108
+ <div id="api-res-body" style="flex:1; padding:15px; overflow-y:auto; font-family:'JetBrains Mono', monospace; font-size:12px; color:#c9d1d9; white-space:pre-wrap; word-wrap:break-word;">
109
+ <div style="color:#8b949e; opacity:0.6; text-align:center; margin-top:50px;">Henüz bir istek atılmadı.</div>
110
+ </div>
111
+ </div>
112
+ `;
113
+
114
+ container.innerHTML = uiHtml;
115
+ }
116
+
117
+ window.executeApiRequest = async function() {
118
+ const baseUrl = document.getElementById('api-base-url').value.replace(/\/+$/, '');
119
+ const route = document.getElementById('api-route').value;
120
+ const method = document.getElementById('api-method').value;
121
+ const autoCsrf = document.getElementById('api-auto-csrf').checked;
122
+
123
+ const fullUrl = baseUrl + route;
124
+ const formData = new FormData();
125
+
126
+ // Topla
127
+ document.querySelectorAll('.api-param-input').forEach(input => {
128
+ formData.append(input.dataset.param, input.value);
129
+ });
130
+
131
+ const resBody = document.getElementById('api-res-body');
132
+ const resStatus = document.getElementById('api-res-status');
133
+ const resTime = document.getElementById('api-res-time');
134
+
135
+ resBody.innerHTML = '<div style="color:#58a6ff; text-align:center; margin-top:50px;">İstek gönderiliyor... ⏳</div>';
136
+ resStatus.innerText = 'Durum: Yükleniyor';
137
+ resTime.innerText = 'Süre: -';
138
+
139
+ let csrfToken = null;
140
+ let cookieStr = '';
141
+
142
+ try {
143
+ if (autoCsrf) {
144
+ resBody.innerHTML = '<div style="color:#d2a8ff; text-align:center; margin-top:50px;">CSRF Token alınıyor... 🛡️</div>';
145
+
146
+ // fetch to base url to get CSRF
147
+ const csrfRes = await fetch(baseUrl);
148
+ const htmlText = await csrfRes.text();
149
+
150
+ const metaMatch = htmlText.match(/<meta\s+name=["']csrf-token["']\s+content=["']([^"']+)["']/i);
151
+ if (metaMatch) {
152
+ csrfToken = metaMatch[1];
153
+ } else {
154
+ // Try finding it in inputs
155
+ const inputMatch = htmlText.match(/<input\s+type=["']hidden["']\s+name=["']csrf_token["']\s+value=["']([^"']+)["']/i);
156
+ if (inputMatch) csrfToken = inputMatch[1];
157
+ }
158
+
159
+ if (csrfToken) {
160
+ formData.append('csrf_token', csrfToken); // ArtiFrame uses csrf_token
161
+ }
162
+ }
163
+
164
+ const startTime = performance.now();
165
+
166
+ const options = {
167
+ method: method,
168
+ credentials: 'include'
169
+ };
170
+
171
+ if (method !== 'GET') {
172
+ options.body = formData;
173
+ }
174
+
175
+ const response = await fetch(fullUrl, options);
176
+ const endTime = performance.now();
177
+
178
+ const statusColor = response.ok ? '#3fb950' : '#ff7b72';
179
+ resStatus.innerHTML = `Durum: <span style="color:${statusColor}; font-weight:bold;">${response.status} ${response.statusText}</span>`;
180
+ resTime.innerText = `Süre: ${Math.round(endTime - startTime)}ms`;
181
+
182
+ const contentType = response.headers.get('content-type');
183
+ let responseText = await response.text();
184
+
185
+ if (contentType && contentType.includes('application/json')) {
186
+ try {
187
+ const jsonObj = JSON.parse(responseText);
188
+ responseText = JSON.stringify(jsonObj, null, 4);
189
+ // Syntax highlighting
190
+ responseText = responseText.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
191
+ let cls = 'color:#79c0ff;'; // string
192
+ if (/^"/.test(match)) {
193
+ if (/:$/.test(match)) {
194
+ cls = 'color:#f0f6fc; font-weight:bold;'; // key
195
+ } else {
196
+ cls = 'color:#a5d6ff;'; // string value
197
+ }
198
+ } else if (/true|false/.test(match)) {
199
+ cls = 'color:#ff7b72;'; // boolean
200
+ } else if (/null/.test(match)) {
201
+ cls = 'color:#d2a8ff;'; // null
202
+ } else {
203
+ cls = 'color:#3fb950;'; // number
204
+ }
205
+ return '<span style="' + cls + '">' + match + '</span>';
206
+ });
207
+ } catch(e) {}
208
+ } else {
209
+ // Escape HTML if not JSON
210
+ responseText = responseText.replace(/</g, '&lt;').replace(/>/g, '&gt;');
211
+ }
212
+
213
+ resBody.innerHTML = responseText;
214
+
215
+ } catch (err) {
216
+ resStatus.innerHTML = `Durum: <span style="color:#ff7b72; font-weight:bold;">Hata!</span>`;
217
+ resBody.innerHTML = `<span style="color:#ff7b72;">İstek başarısız oldu: ${err.message}</span>\n\nLütfen sunucunun (APP_URL) çalıştığından ve CORS engeli olmadığından emin olun.`;
218
+ }
219
+ }
220
+
221
+ // Attach hook to global
222
+ window.renderApiInspector = renderApiInspector;