@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.
- package/LICENSE +660 -660
- package/bin/artiframe.js +0 -0
- package/bin/artiframe.php +0 -0
- package/core-stubs/app/ApiAuthControl.php +76 -0
- package/core-stubs/app/ApiControl.php +81 -35
- package/core-stubs/app/AuthControl.php +39 -0
- package/core-stubs/app/Database.php +36 -35
- package/core-stubs/app/DotEnv.php +19 -1
- package/core-stubs/app/ViewControl.php +47 -1
- package/core-stubs/bin/SQLMethod.php +261 -0
- package/core-stubs/bin/SystemMethod.php +115 -74
- package/core-stubs/bin/ViewMethod.php +19 -5
- package/core-stubs/docs/de.html +4325 -4347
- package/core-stubs/docs/en.html +4325 -4347
- package/core-stubs/docs/es.html +4325 -4347
- package/core-stubs/docs/fr.html +4325 -4347
- package/core-stubs/docs/tr.html +117 -46
- package/core-stubs/public/403.php +52 -0
- package/core-stubs/public/assets/css/components/header.css +174 -0
- package/core-stubs/public/assets/css/components/mobilenav.css +198 -0
- package/core-stubs/public/assets/css/components/sidebar.css +184 -0
- package/core-stubs/public/assets/css/root/app.css +975 -38
- package/core-stubs/public/assets/css/root/root.css +64 -0
- package/core-stubs/public/assets/js/components/header.js +380 -0
- package/core-stubs/public/assets/js/components/mobilenav.js +97 -0
- package/core-stubs/public/assets/js/components/theme-modal.js +74 -0
- package/core-stubs/public/assets/js/root/app.js +1870 -0
- package/core-stubs/public/includes/footer.php +4 -5
- package/core-stubs/public/includes/head-auth.php +65 -0
- package/core-stubs/public/includes/head.php +56 -17
- package/core-stubs/public/includes/header.php +135 -1
- package/core-stubs/public/includes/mobilenav.php +75 -3
- package/core-stubs/public/includes/sidebar.php +186 -1
- package/core-stubs/public/includes/theme-modal.php +1 -0
- package/db-studio/debug.log +3 -0
- package/db-studio/index.html +1755 -0
- package/db-studio/launcher.html +102 -0
- package/db-studio/launcher.js +180 -0
- package/db-studio/logo.svg +22 -0
- package/db-studio/main.js +568 -0
- package/db-studio/package-lock.json +1034 -0
- package/db-studio/package.json +16 -0
- package/db-studio/preload.js +29 -0
- package/devops-studio/api-inspector.js +222 -0
- package/devops-studio/index.html +1892 -0
- package/devops-studio/logo.svg +22 -0
- package/devops-studio/main.js +67 -0
- package/devops-studio/make-wizard.js +635 -0
- package/devops-studio/package-lock.json +871 -0
- package/devops-studio/package.json +12 -0
- package/package.json +5 -2
- package/scripts/postinstall.js +44 -8
- package/server-studio/.json-404-guard +1 -0
- package/server-studio/index.html +283 -0
- package/server-studio/logo.svg +22 -0
- package/server-studio/main.js +133 -0
- package/server-studio/package-lock.json +1179 -0
- package/server-studio/package.json +15 -0
- package/server-studio/router.php +99 -0
- package/src/App.php +29 -0
- package/src/Commands/AddCommand.php +26 -9
- package/src/Commands/DbExportCommand.php +131 -0
- package/src/Commands/DbStartCommand.php +46 -0
- package/src/Commands/DevopsCommand.php +35 -0
- package/src/Commands/GoCommand.php +48 -48
- package/src/Commands/ListCommand.php +68 -68
- package/src/Commands/MakeApiCommand.php +6 -1
- package/src/Commands/MakeViewCommand.php +25 -2
- package/src/Commands/NewProjectCommand.php +16 -11
- package/src/Commands/OptimizeCommand.php +61 -0
- package/src/Commands/RemoveCommand.php +35 -7
- package/src/Commands/ServeCommand.php +46 -91
- package/src/Commands/ShowCommand.php +24 -24
- package/src/Commands/UpgradeCommand.php +39 -10
- package/stubs/make/api-switch-case.stub +1 -1
- package/stubs/make/auth-api-standart.stub +20 -0
- package/stubs/make/auth-api-switch-case.stub +38 -0
- package/stubs/make/auth-view.stub +26 -0
- package/stubs/make/class.stub +10 -2
- package/stubs/make/view.stub +3 -0
- package/stubs/service/image.stub +334 -334
- package/stubs/service/iyzico.stub +637 -637
- package/stubs/service/jwt.stub +312 -312
- package/stubs/service/phpmailer.stub +143 -143
- package/stubs/service/pusher.stub +232 -232
- package/stubs/service/qrcode.stub +169 -169
- package/stubs/service/redis.stub +361 -361
- package/stubs/service/s3.stub +377 -377
- package/stubs/service/stripe.stub +526 -526
- 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, '<').replace(/>/g, '>');
|
|
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;
|