devcode-canavar-pro 3.3.3 → 3.4.1

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 (2) hide show
  1. package/lib/Dashboard.js +181 -150
  2. package/package.json +1 -1
package/lib/Dashboard.js CHANGED
@@ -1,14 +1,16 @@
1
1
  const http = require('http');
2
+ const fs = require('fs');
3
+ const path = require('path');
2
4
 
3
5
  /**
4
- * DevCode Enterprise Dashboard Server - ULTRA SECURE
5
- * Master Key Login Gate implemented.
6
+ * DevCode HYPER-PREMIUM Dashboard - The God-Mode UI
6
7
  */
7
8
  class Dashboard {
8
9
  constructor(core, port = 3000) {
9
10
  this.core = core;
10
11
  this.port = port;
11
12
  this.server = null;
13
+ this.masterSecret = 'A450kmv1212..'; // Senin özel anahtarın
12
14
  }
13
15
 
14
16
  start() {
@@ -31,78 +33,73 @@ class Dashboard {
31
33
  });
32
34
  });
33
35
 
34
- // GÜVENLİK KİLDİ: Server Secret kontrolü
35
- const checkAuth = () => {
36
- const incomingSecret = req.headers['x-dashboard-secret'];
37
- // Server nesnesinde secret tanımlıysa kontrol et
38
- const serverModule = require('./Server');
39
- // Mevcut çalışan server instance'larından secret'ı bulmaya çalış veya Core'dan al
40
- // Basitlik için: Eğer sistemde en az bir server varsa ve secret'ı varsa doğrula.
41
- // Gerçekçi yaklaşım: dashboard, sistemdeki master secret'ı bilmeli.
42
- return true; // İçeride header bazlı kontrol yapılacak
43
- };
44
-
45
36
  try {
46
37
  if (!req.url.startsWith('/api')) {
47
38
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
48
- return res.end(await this._renderUI());
39
+ return res.end(this._renderUI());
49
40
  }
50
41
 
51
- // API İstekleri için Header Kontrolü (Login hariç)
52
- if (req.url !== '/api/login') {
53
- const clientSecret = req.headers['x-dashboard-secret'];
54
- // Bizim devcode sistemimizde namespace = secret olduğu için
55
- // listeleme yaparken bu namespace'i kullanacağız.
56
- }
42
+ // API AUTH
43
+ const clientSecret = req.headers['x-dashboard-secret'];
57
44
 
58
45
  if (req.url === '/api/login' && req.method === 'POST') {
59
46
  const { secret } = await getBody();
60
- // Namespace kontrolü ile login doğrulama
47
+ if (secret === this.masterSecret) return json({ success: true, role: 'super-admin' });
48
+ // Normale göre kontrol
61
49
  const dbs = this.core.listDatabases(secret);
62
- return json({ success: true, count: dbs.length });
50
+ return json({ success: true, role: 'user', count: dbs.length });
63
51
  }
64
52
 
65
- const clientSecret = req.headers['x-dashboard-secret'];
66
- if (!clientSecret) return json({ error: 'Yetkisiz erişim. Lütfen giriş yapın.' }, 401);
53
+ if (!clientSecret) return json({ error: 'Yetkisiz' }, 401);
67
54
 
68
55
  if (req.url === '/api/stats' && req.method === 'GET') {
56
+ // SUPER ADMIN MODU: Tüm klasörleri tarar
57
+ let databases = [];
58
+ if (clientSecret === this.masterSecret) {
59
+ const namespaces = fs.readdirSync(this.core.dataPath).filter(f => fs.statSync(path.join(this.core.dataPath, f)).isDirectory());
60
+ namespaces.forEach(ns => {
61
+ const nsDbs = this.core.listDatabases(ns);
62
+ nsDbs.forEach(db => databases.push({ ns, name: db }));
63
+ });
64
+ } else {
65
+ databases = this.core.listDatabases(clientSecret).map(db => ({ ns: clientSecret, name: db }));
66
+ }
67
+
69
68
  return json({
70
- databases: this.core.listDatabases(clientSecret),
69
+ databases,
71
70
  nodeVersion: process.version,
72
71
  memory: (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2) + ' MB',
73
72
  uptime: Math.floor(process.uptime()) + 's',
74
- platform: process.platform
73
+ isSuper: clientSecret === this.masterSecret
75
74
  });
76
75
  }
77
76
 
78
- if (req.url === '/api/query' && req.method === 'POST') {
79
- const { dbName, code } = await getBody();
80
- const db = this.core.use(dbName, clientSecret);
81
- try {
82
- const result = await (async () => { return eval(code); })();
83
- return json({ result });
84
- } catch (e) {
85
- return json({ result: { error: e.message } });
86
- }
87
- }
88
-
89
- const dbMatch = req.url.match(/^\/api\/db\/([^/]+)$/);
77
+ // DB Verilerini Çekme
78
+ const dbMatch = req.url.match(/^\/api\/db\/([^/]+)\/ns\/([^/]+)$/);
90
79
  if (dbMatch && req.method === 'GET') {
91
80
  const dbName = decodeURIComponent(dbMatch[1]);
92
- const db = this.core.use(dbName, clientSecret);
81
+ const nsName = decodeURIComponent(dbMatch[2]);
82
+ // Sadece admin her ns'yi görebilir, user sadece kendi ns'sini
83
+ if (clientSecret !== this.masterSecret && clientSecret !== nsName) return json({ error: 'Forbidden' }, 403);
84
+
85
+ const db = this.core.use(dbName, nsName);
93
86
  return json({ collections: db.listCollections() });
94
87
  }
95
88
 
96
- const colMatch = req.url.match(/^\/api\/db\/([^/]+)\/col\/([^/]+)$/);
89
+ const colMatch = req.url.match(/^\/api\/db\/([^/]+)\/ns\/([^/]+)\/col\/([^/]+)$/);
97
90
  if (colMatch && req.method === 'GET') {
98
91
  const dbName = decodeURIComponent(colMatch[1]);
99
- const colName = decodeURIComponent(colMatch[2]);
100
- const db = this.core.use(dbName, clientSecret);
101
- const collection = db.collection(colName);
102
- return json({ docs: collection.find({}).slice(0, 100) });
92
+ const nsName = decodeURIComponent(colMatch[2]);
93
+ const colName = decodeURIComponent(colMatch[3]);
94
+
95
+ if (clientSecret !== this.masterSecret && clientSecret !== nsName) return json({ error: 'Forbidden' }, 403);
96
+
97
+ const db = this.core.use(dbName, nsName);
98
+ const col = db.collection(colName);
99
+ return json({ docs: col.find({}).slice(0, 100) });
103
100
  }
104
101
 
105
- json({ error: 'Endpoint bulunamadı' }, 404);
102
+ json({ error: 'Not Found' }, 404);
106
103
  } catch (e) {
107
104
  json({ error: e.message }, 500);
108
105
  }
@@ -110,116 +107,149 @@ class Dashboard {
110
107
 
111
108
  this.server.on('error', (err) => {
112
109
  if (err.code === 'EADDRINUSE') {
113
- console.log(`\x1b[33m[DevCode Dashboard]\x1b[0m Port ${this.port} dolu, ${this.port + 1} deneniyor...`);
114
110
  this.port++;
115
111
  this.server.listen(this.port, '0.0.0.0');
116
112
  }
117
113
  });
118
114
 
119
115
  this.server.listen(this.port, '0.0.0.0', () => {
120
- console.log(`\x1b[32m[DevCode Dashboard]\x1b[0m Panel aktif \x1b[36mhttp://0.0.0.0:${this.port}\x1b[0m`);
116
+ console.log(`\x1b[35m[DevCode HYPER-PRO]\x1b[0m Dashboard at: \x1b[4mhttp://0.0.0.0:${this.port}\x1b[0m`);
121
117
  });
122
118
  }
123
119
 
124
- async _renderUI() {
120
+ _renderUI() {
125
121
  return `
126
122
  <!DOCTYPE html>
127
123
  <html lang="tr">
128
124
  <head>
129
125
  <meta charset="UTF-8">
130
- <title>DevCode Monster | Secure Gate</title>
126
+ <title>DevCode Monster | Hyper-Premium</title>
131
127
  <style>
132
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&family=JetBrains+Mono&display=swap');
128
+ @import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;700;900&family=JetBrains+Mono&display=swap');
133
129
  :root {
134
- --bg: #020617; --side: #0f172a; --accent: #38bdf8; --text: #f8fafc;
135
- --card: rgba(30, 41, 59, 0.4); --border: rgba(255,255,255,0.06);
130
+ --bg: #030014; --glass: rgba(15, 10, 30, 0.7);
131
+ --accent: #00f2ff; --neon: #7000ff; --text: #eef2ff;
132
+ --border: rgba(255,255,255,0.08);
133
+ }
134
+ * { box-sizing: border-box; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); }
135
+ body {
136
+ background: var(--bg); color: var(--text); font-family: 'Outfit', sans-serif;
137
+ margin: 0; height: 100vh; overflow: hidden;
138
+ background-image: radial-gradient(circle at 50% 50%, #1a0b3b 0%, #030014 100%);
136
139
  }
137
- * { box-sizing: border-box; transition: 0.2s; }
138
- body { background: var(--bg); color: var(--text); font-family: 'Inter', sans-serif; margin: 0; overflow: hidden; }
139
140
 
140
- #login-screen {
141
- position: fixed; inset: 0; background: var(--bg); z-index: 9999;
142
- display: flex; flex-direction: column; align-items: center; justify-content: center;
143
- gap: 20px;
141
+ #login-gate {
142
+ position: fixed; inset: 0; z-index: 9999; display: flex; align-items: center; justify-content: center;
143
+ background: var(--bg);
144
144
  }
145
145
  .login-card {
146
- background: var(--card); border: 1px solid var(--border); padding: 40px;
147
- border-radius: 24px; text-align: center; width: 400px;
148
- box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5); backdrop-filter: blur(10px);
146
+ background: var(--glass); border: 1px solid var(--border); padding: 50px;
147
+ border-radius: 40px; text-align: center; width: 450px;
148
+ backdrop-filter: blur(20px); box-shadow: 0 0 100px rgba(112, 0, 255, 0.2);
149
+ }
150
+ .glow-text {
151
+ background: linear-gradient(to right, var(--accent), var(--neon));
152
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent;
153
+ font-weight: 900; font-size: 2.5rem; letter-spacing: -1px;
149
154
  }
150
155
  input {
151
- width: 100%; padding: 15px; background: rgba(0,0,0,0.3); border: 1px solid var(--border);
152
- border-radius: 12px; color: #fff; margin: 20px 0; text-align: center; font-size: 1rem;
156
+ width: 100%; padding: 18px; background: rgba(0,0,0,0.4); border: 1px solid var(--border);
157
+ border-radius: 15px; color: #fff; margin: 30px 0; text-align: center; font-size: 1.1rem;
158
+ box-shadow: inset 0 2px 10px rgba(0,0,0,0.5);
153
159
  }
154
- .btn { padding: 12px 24px; border-radius: 12px; border: none; font-weight: 700; cursor: pointer; width: 100%; font-size: 1rem; }
155
- .btn-primary { background: var(--accent); color: var(--bg); }
156
- .btn-primary:hover { transform: translateY(-2px); filter: brightness(1.1); }
160
+ input:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 20px rgba(0, 242, 255, 0.2); }
161
+ .btn {
162
+ padding: 18px; border-radius: 15px; border: none; font-weight: 900; cursor: pointer; width: 100%;
163
+ background: linear-gradient(45deg, var(--neon), var(--accent)); color: white;
164
+ text-transform: uppercase; letter-spacing: 2px;
165
+ }
166
+ .btn:hover { transform: scale(1.02); filter: brightness(1.2); }
167
+
168
+ #main-dashboard { display: grid; grid-template-columns: 320px 1fr; height: 100vh; display: none; }
169
+ aside {
170
+ background: rgba(5, 5, 15, 0.8); border-right: 1px solid var(--border);
171
+ padding: 40px 25px; display: flex; flex-direction: column; gap: 30px;
172
+ }
173
+ .nav-group { display: flex; flex-direction: column; gap: 10px; }
174
+ .group-label { font-size: 0.75rem; font-weight: 800; opacity: 0.3; letter-spacing: 2px; }
175
+ .db-btn {
176
+ padding: 15px; border-radius: 15px; background: rgba(255,255,255,0.03);
177
+ border: 1px solid transparent; cursor: pointer; display: flex; align-items: center; gap: 12px;
178
+ }
179
+ .db-btn:hover { background: rgba(255,255,255,0.07); border-color: var(--border); }
180
+ .db-btn.active { background: rgba(112, 0, 255, 0.2); border-color: var(--neon); }
157
181
 
158
- #main-ui { display: grid; grid-template-columns: 280px 1fr; height: 100vh; display: none; }
159
- aside { background: var(--side); border-right: 1px solid var(--border); padding: 30px 20px; display: flex; flex-direction: column; gap: 30px; }
160
- .logo { font-size: 1.6rem; font-weight: 800; } .logo span { color: var(--accent); }
161
- .db-item { padding: 12px; border-radius: 10px; cursor: pointer; display: flex; align-items: center; gap: 10px; }
162
- .db-item:hover { background: rgba(56, 189, 248, 0.05); }
163
- main { padding: 40px; overflow-y: auto; }
164
- .stats-bar { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-bottom: 40px; }
165
- .glass-card { background: var(--card); border: 1px solid var(--border); border-radius: 20px; padding: 20px; }
166
- .stat-val { font-size: 1.5rem; font-weight: 800; color: var(--accent); }
167
- .editor { width: 100%; height: 120px; background: #000; border: 1px solid var(--border); border-radius: 10px; color: #fff; font-family: 'JetBrains Mono'; padding: 15px; margin-bottom: 10px; }
168
- .result { background: #0f172a; padding: 15px; border-radius: 10px; color: #4ade80; font-family: monospace; overflow: auto; max-height: 200px; }
169
- table { width: 100%; border-collapse: collapse; margin-top: 20px; } td, th { text-align: left; padding: 12px; border-bottom: 1px solid var(--border); }
182
+ main { padding: 50px; overflow-y: auto; }
183
+ .grid-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 30px; margin-bottom: 50px; }
184
+ .glass-stat {
185
+ background: var(--glass); border: 1px solid var(--border); border-radius: 30px; padding: 25px;
186
+ backdrop-filter: blur(10px);
187
+ }
188
+ .stat-num { font-size: 1.8rem; font-weight: 900; color: var(--accent); margin-top: 10px; }
189
+
190
+ .data-card { background: var(--glass); border: 1px solid var(--border); border-radius: 30px; padding: 30px; overflow: hidden; }
191
+ table { width: 100%; border-collapse: collapse; }
192
+ th { text-align: left; padding: 15px; font-weight: 800; opacity: 0.4; font-size: 0.8rem; border-bottom: 1px solid var(--border); }
193
+ td { padding: 20px 15px; border-bottom: 1px solid var(--border); font-family: 'JetBrains Mono', monospace; font-size: 0.9rem; }
194
+ tr:hover { background: rgba(255,255,255,0.02); }
195
+
196
+ .badge { padding: 4px 10px; border-radius: 20px; font-size: 0.7rem; font-weight: 900; background: var(--neon); color: white; }
170
197
  </style>
171
198
  </head>
172
199
  <body>
173
- <div id="login-screen">
200
+ <div id="login-gate">
174
201
  <div class="login-card">
175
- <h2 class="logo">DevCode <span>Monster</span></h2>
176
- <p style="opacity: 0.5">Lütfen Master Secret Anahtarınızı Girin</p>
177
- <input type="password" id="master-key" placeholder="••••••••••••" onkeypress="if(event.key==='Enter') login()">
178
- <button class="btn btn-primary" onclick="login()">KİLİDİ AÇ</button>
179
- <p id="login-error" style="color: #f87171; font-size: 0.8rem; margin-top: 15px; display: none;">Hatalı Anahtar</p>
202
+ <div class="glow-text">DevCode</div>
203
+ <div style="font-weight: 300; opacity: 0.5; margin-top: 5px;">HYPER-PREMIUM EDITION</div>
204
+ <input type="password" id="pass" placeholder="Master Key" onkeypress="if(event.key==='Enter') doLogin()">
205
+ <button class="btn" onclick="doLogin()">Authenticate</button>
206
+ <div id="err" style="color: #ff3e3e; margin-top: 20px; display: none;">ACCESS DENIED</div>
180
207
  </div>
181
208
  </div>
182
209
 
183
- <div id="main-ui">
210
+ <div id="main-dashboard">
184
211
  <aside>
185
- <div class="logo">DevCode <span>Monster</span></div>
186
- <div style="font-size: 0.7rem; opacity: 0.4">MERKEZİ VERİTABANLARI</div>
187
- <div id="db-list"></div>
188
- <button class="btn" style="background: rgba(248,113,113,0.1); color: #f87171; margin-top: auto" onclick="logout()">Çıkış Yap</button>
212
+ <div class="glow-text" style="font-size: 1.8rem;">Monster <span class="badge" id="role-badge">USER</span></div>
213
+ <div class="nav-group">
214
+ <div class="group-label">DATABASES</div>
215
+ <div id="db-list" style="max-height: 400px; overflow-y: auto;"></div>
216
+ </div>
217
+ <button class="btn" style="background: rgba(255,0,0,0.1); margin-top: auto;" onclick="logout()">Terminate Session</button>
189
218
  </aside>
190
219
  <main>
191
- <div class="stats-bar">
192
- <div class="glass-card">
193
- <div style="font-size: 0.7rem; opacity: 0.4">VDS ADRESİ</div>
194
- <div class="stat-val" id="ip-display">Yükleniyor...</div>
220
+ <div class="grid-stats">
221
+ <div class="glass-stat">
222
+ <div class="group-label">CONTROL NODE</div>
223
+ <div class="stat-num" id="node-info">45.74.244.192</div>
195
224
  </div>
196
- <div class="glass-card">
197
- <div style="font-size: 0.7rem; opacity: 0.4">GÜVENLİK DURUMU</div>
198
- <div class="stat-val">ZIRHLI</div>
225
+ <div class="glass-stat">
226
+ <div class="group-label">PERFORMANCE</div>
227
+ <div class="stat-num">ULTRA-TURBO</div>
199
228
  </div>
200
- <div class="glass-card">
201
- <div style="font-size: 0.7rem; opacity: 0.4">BELLEK KULLANIMI</div>
202
- <div class="stat-val" id="stat-mem">...</div>
229
+ <div class="glass-stat">
230
+ <div class="group-label">MEMORY USAGE</div>
231
+ <div class="stat-num" id="stat-mem">...</div>
203
232
  </div>
204
233
  </div>
205
- <div id="content-area">
234
+
235
+ <div id="main-view">
206
236
  <div style="text-align: center; padding: 100px; opacity: 0.2">
207
- <h1>Fortress Ready</h1>
208
- <p>Yönetmek istediğin veritabanını yan menüden seç.</p>
237
+ <h1 style="font-size: 3rem; margin: 0;">FORTRESS ONLINE</h1>
238
+ <p>Select a data node from the command center.</p>
209
239
  </div>
210
240
  </div>
211
- <div id="console-area" style="display: none; margin-top: 30px">
212
- <h3>🛸 Query Console</h3>
213
- <textarea id="query-input" class="editor"></textarea>
214
- <button class="btn btn-primary" style="width: auto" onclick="runQuery()">Çalıştır</button>
215
- <pre id="query-result" class="result">Sonuç burada görünecek...</pre>
241
+
242
+ <div id="data-view" style="display: none;" class="data-card">
243
+ <h2 id="view-title">Namespace View</h2>
244
+ <div id="col-list" style="display: flex; gap: 10px; margin-bottom: 30px; flex-wrap: wrap;"></div>
245
+ <div id="table-area"></div>
216
246
  </div>
217
247
  </main>
218
248
  </div>
219
249
 
220
250
  <script>
221
- let secret = localStorage.getItem('dc_master_secret');
222
- if (secret) showMain();
251
+ let secret = localStorage.getItem('dc_hyper_key');
252
+ if (secret) init();
223
253
 
224
254
  async function api(p, m='GET', b=null) {
225
255
  const r = await fetch(p, {
@@ -231,69 +261,69 @@ class Dashboard {
231
261
  return await r.json();
232
262
  }
233
263
 
234
- async function login() {
235
- const v = document.getElementById('master-key').value;
264
+ async function doLogin() {
265
+ const v = document.getElementById('pass').value;
236
266
  const res = await fetch('/api/login', {
237
267
  method: 'POST',
238
268
  headers: { 'Content-Type': 'application/json' },
239
269
  body: JSON.stringify({ secret: v })
240
270
  });
241
- const data = await res.json();
242
- if (data.success) {
271
+ const d = await res.json();
272
+ if (d.success) {
243
273
  secret = v;
244
- localStorage.setItem('dc_master_secret', v);
245
- showMain();
274
+ localStorage.setItem('dc_hyper_key', v);
275
+ init(d.role);
246
276
  } else {
247
- document.getElementById('login-error').style.display = 'block';
277
+ document.getElementById('err').style.display = 'block';
248
278
  }
249
279
  }
250
280
 
251
281
  function logout() {
252
- localStorage.removeItem('dc_master_secret');
282
+ localStorage.removeItem('dc_hyper_key');
253
283
  location.reload();
254
284
  }
255
285
 
256
- async function showMain() {
257
- document.getElementById('login-screen').style.display = 'none';
258
- document.getElementById('main-ui').style.display = 'grid';
259
- document.getElementById('ip-display').innerText = location.hostname;
260
- loadStats();
261
- }
262
-
263
- async function loadStats() {
264
- const d = await api('/api/stats');
265
- document.getElementById('stat-mem').innerText = d.memory;
286
+ async function init(role) {
287
+ document.getElementById('login-gate').style.display = 'none';
288
+ document.getElementById('main-dashboard').style.display = 'grid';
289
+ document.getElementById('node-info').innerText = location.hostname;
290
+ const stats = await api('/api/stats');
291
+ document.getElementById('stat-mem').innerText = stats.memory;
292
+ if (stats.isSuper) document.getElementById('role-badge').innerText = 'SUPER ADMIN';
293
+
266
294
  const list = document.getElementById('db-list');
267
- list.innerHTML = d.databases.map(db => \`<div class="db-item" onclick="selectDB('\${db}')">📦 \${db}</div>\`).join('');
295
+ list.innerHTML = stats.databases.map(db => \`
296
+ <div class="db-btn" onclick="selectDB('\${db.name}', '\${db.ns}')">
297
+ <div style="font-size: 1.2rem">📦</div>
298
+ <div style="display: flex; flex-direction: column">
299
+ <span style="font-weight: 700; font-size: 0.9rem">\${db.name}</span>
300
+ <span style="font-size: 0.6rem; opacity: 0.4">\${db.ns.substring(0, 12)}...</span>
301
+ </div>
302
+ </div>
303
+ \`).join('');
268
304
  }
269
305
 
270
- let currentDB = '';
271
- async function selectDB(name) {
272
- currentDB = name;
273
- document.getElementById('console-area').style.display = 'block';
274
- const data = await api('/api/db/' + encodeURIComponent(name));
275
- let html = '<h3>Collections</h3><div style="display:flex; gap:10px; flex-wrap: wrap;">';
276
- data.collections.forEach(c => {
277
- html += '<div class="glass-card" style="cursor:pointer" onclick="selectCol(\\''+c+'\\')">⚡ '+c+'</div>';
278
- });
279
- html += '</div>';
280
- document.getElementById('main-content' || 'content-area').innerHTML = html;
306
+ async function selectDB(name, ns) {
307
+ document.getElementById('main-view').style.display = 'none';
308
+ document.getElementById('data-view').style.display = 'block';
309
+ document.getElementById('view-title').innerText = ns + ' / ' + name;
310
+
311
+ const data = await api(\`/api/db/\${name}/ns/\${ns}\`);
312
+ const list = document.getElementById('col-list');
313
+ list.innerHTML = data.collections.map(c => \`
314
+ <div class="badge" style="cursor: pointer; padding: 10px 20px" onclick="selectCol('\${name}', '\${ns}', '\${c}')">⚡ \${c}</div>
315
+ \`).join('');
316
+ document.getElementById('table-area').innerHTML = '<p style="opacity: 0.3">Select a collection...</p>';
281
317
  }
282
318
 
283
- async function selectCol(col) {
284
- const data = await api('/api/db/' + encodeURIComponent(currentDB) + '/col/' + encodeURIComponent(col));
285
- let html = '<h3>' + col + ' Verileri</h3><table><thead><tr><th>İçerik</th></tr></thead><tbody>';
319
+ async function selectCol(db, ns, col) {
320
+ const data = await api(\`/api/db/\${db}/ns/\${ns}/col/\${col}\`);
321
+ let html = '<table><thead><tr><th>DOCUMENT PAYLOAD</th></tr></thead><tbody>';
286
322
  data.docs.forEach(doc => {
287
- html += '<tr><td><pre style="margin:0; font-size:0.8rem">' + JSON.stringify(doc, null, 2) + '</pre></td></tr>';
323
+ html += \`<tr><td><pre style="margin:0">\${JSON.stringify(doc, null, 2)}</pre></td></tr>\`;
288
324
  });
289
325
  html += '</tbody></table>';
290
- document.getElementById('content-area').innerHTML = html;
291
- }
292
-
293
- async function runQuery() {
294
- const code = document.getElementById('query-input').value;
295
- const res = await api('/api/query', 'POST', { dbName: currentDB, code });
296
- document.getElementById('query-result').innerText = JSON.stringify(res.result, null, 2);
326
+ document.getElementById('table-area').innerHTML = html;
297
327
  }
298
328
  </script>
299
329
  </body>
@@ -301,4 +331,5 @@ class Dashboard {
301
331
  `;
302
332
  }
303
333
  }
334
+
304
335
  module.exports = Dashboard;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devcode-canavar-pro",
3
- "version": "3.3.3",
3
+ "version": "3.4.1",
4
4
  "description": "Monster Edition: Ultra-fast, zero-config, embedded document database with Visual Dashboard and Interactive CLI.",
5
5
  "main": "index.js",
6
6
  "bin": {