admindb 2.3.1 → 2.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.
- package/README.md +16 -16
- package/dist/app.js +119 -171
- package/dist/public/css/app.css +1 -1
- package/dist/public/js/browse.js +1 -1
- package/dist/public/js/databases.js +1 -1
- package/dist/public/js/designer.js +1 -1
- package/dist/public/js/forms.js +1 -1
- package/dist/public/js/home.js +1 -1
- package/dist/public/js/inspector.js +1 -1
- package/dist/public/js/query.js +1 -1
- package/dist/public/js/schema.js +1 -1
- package/dist/public/js/seed.js +1 -1
- package/dist/routes/api/erd.js +2 -2
- package/dist/routes/api/helpers.d.ts +1 -1
- package/dist/routes/api/import-export.js +8 -6
- package/dist/routes/api/index.js +16 -9
- package/dist/routes/api/query.js +8 -5
- package/dist/routes/api/rows.js +36 -21
- package/dist/routes/api/seed.js +29 -16
- package/dist/routes/api/tables.js +32 -18
- package/dist/routes/databases.js +2 -0
- package/dist/routes/pages.d.ts +1 -1
- package/dist/routes/pages.js +137 -43
- package/dist/views/layouts/main.hbs +1 -1
- package/dist/views/pages/databases.hbs +1 -1
- package/dist/views/pages/erd.hbs +1 -1
- package/dist/views/pages/form.hbs +1 -1
- package/dist/views/pages/home.hbs +1 -1
- package/dist/views/pages/info.hbs +1 -1
- package/dist/views/pages/schema.hbs +1 -1
- package/dist/views/pages/seed-select.hbs +6 -5
- package/dist/views/pages/seed.hbs +3 -3
- package/dist/views/pages/table.hbs +1 -1
- package/dist/views/partials/navbar.hbs +1 -1
- package/dist/views/partials/sidebar.hbs +1 -1
- package/docs/API.md +60 -55
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
<div class="space-y-6">
|
|
2
1
|
<div class="page-header">
|
|
3
2
|
<div class="page-header-row">
|
|
4
3
|
<div>
|
|
5
4
|
<div class="page-pretitle">{{dialect}} Database</div>
|
|
6
5
|
<h1 class="page-title">Info & Settings</h1>
|
|
7
6
|
<p class="mt-0.5 text-xs text-base-content/60">Database configuration, settings, and schema DDL overview.</p>
|
|
8
7
|
</div>
|
|
9
8
|
</div>
|
|
10
9
|
</div>
|
|
11
10
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
12
11
|
<div class="lg:col-span-1 space-y-6">
|
|
13
12
|
{{#if isDefaultPassword}}
|
|
14
13
|
<div class="alert alert-warning text-xs shadow-xs rounded-2xl border border-warning/30 p-3.5">
|
|
15
14
|
{{{icon "warning" class="h-5 w-5 shrink-0 text-warning"}}}
|
|
16
15
|
<div>
|
|
17
16
|
<div class="font-bold text-sm">Default Password in Use</div>
|
|
18
17
|
<div class="text-base-content/80 mt-0.5 leading-relaxed">Console is running with default password (<code class="font-mono font-semibold">admin</code>). Run <code class="font-mono font-semibold">npm run generatehash</code> and set <code class="font-mono font-semibold">ADMINDB_PASSWORD</code>.</div>
|
|
19
18
|
</div>
|
|
20
19
|
</div>
|
|
21
20
|
{{/if}}
|
|
22
21
|
<div class="app-card overflow-hidden">
|
|
23
22
|
<div class="border-b border-base-200 bg-base-200/40 px-4 py-3">
|
|
24
23
|
<h2 class="text-sm font-bold uppercase tracking-wider text-base-content/80">Settings / Configuration</h2>
|
|
25
24
|
</div>
|
|
26
25
|
<div class="p-0">
|
|
27
26
|
<table class="table table-sm w-full">
|
|
28
27
|
<tbody>
|
|
29
28
|
{{#each settings}}
|
|
30
29
|
<tr class="hover:bg-base-200/20">
|
|
31
30
|
<td class="font-medium text-base-content/70 w-1/2">{{@key}}</td>
|
|
32
31
|
<td class="font-mono text-xs">{{this}}</td>
|
|
33
32
|
</tr>
|
|
34
33
|
{{else}}
|
|
35
34
|
<tr>
|
|
36
35
|
<td colspan="2" class="p-4 text-center text-sm text-base-content/40">No settings available</td>
|
|
37
36
|
</tr>
|
|
38
37
|
{{/each}}
|
|
39
38
|
</tbody>
|
|
40
39
|
</table>
|
|
41
40
|
</div>
|
|
42
41
|
</div>
|
|
43
42
|
</div>
|
|
44
43
|
<div class="lg:col-span-2 space-y-6">
|
|
45
44
|
<div class="app-card overflow-hidden flex flex-col h-[75vh]">
|
|
46
45
|
<div class="border-b border-base-200 bg-base-200/40 px-4 py-3 flex items-center justify-between">
|
|
47
46
|
<div class="flex items-center gap-3">
|
|
48
47
|
<h2 class="text-sm font-bold uppercase tracking-wider text-base-content/80">Schema DDL</h2>
|
|
49
48
|
<span class="badge badge-sm badge-ghost font-mono text-[10px] uppercase font-bold">{{dialect}}</span>
|
|
50
49
|
</div>
|
|
51
50
|
<button id="btn-copy-ddl" class="btn btn-sm btn-ghost gap-1.5" disabled>
|
|
52
51
|
{{{icon "copy" class="h-4 w-4"}}}
|
|
53
52
|
Copy
|
|
54
53
|
</button>
|
|
55
54
|
</div>
|
|
56
55
|
<div class="bg-base-300 p-4 overflow-y-auto flex-1 relative">
|
|
57
56
|
<div id="ddl-loader" class="absolute inset-0 flex flex-col items-center justify-center text-base-content/50 gap-3">
|
|
58
57
|
{{{icon "spinner" class="h-6 w-6 animate-spin text-primary"}}}
|
|
59
58
|
<p class="text-sm font-medium">Extracting schema definitions...</p>
|
|
60
59
|
</div>
|
|
61
60
|
<div id="ddl-error" class="hidden absolute inset-0 flex flex-col items-center justify-center text-error gap-3 bg-base-300">
|
|
62
61
|
{{{icon "error" class="h-8 w-8"}}}
|
|
63
62
|
<p class="text-sm font-medium">Failed to load schema.</p>
|
|
64
63
|
</div>
|
|
65
64
|
<pre id="ddl-container" class="hidden m-0 h-full"><code class="language-sql text-sm text-base-content/80 whitespace-pre-wrap"></code></pre>
|
|
66
65
|
</div>
|
|
67
66
|
</div>
|
|
68
67
|
</div>
|
|
69
68
|
</div>
|
|
70
69
|
document.addEventListener('DOMContentLoaded', async () => {
|
|
71
70
|
const loader = document.getElementById('ddl-loader');
|
|
72
71
|
const container = document.getElementById('ddl-container');
|
|
73
72
|
const codeBlock = container.querySelector('code');
|
|
74
73
|
const btnCopy = document.getElementById('btn-copy-ddl');
|
|
75
74
|
const errorBox = document.getElementById('ddl-error');
|
|
76
75
|
try {
|
|
77
76
|
const res = await fetch('{{basePath}}/api/info/ddl');
|
|
78
77
|
const json = await res.json();
|
|
79
78
|
loader.classList.add('hidden');
|
|
80
79
|
if (json.success && json.data) {
|
|
81
80
|
if (window.Utils && window.Utils.highlightSql) {
|
|
82
81
|
codeBlock.innerHTML = window.Utils.highlightSql(json.data);
|
|
83
82
|
} else {
|
|
84
83
|
codeBlock.textContent = json.data;
|
|
85
84
|
}
|
|
86
85
|
container.classList.remove('hidden');
|
|
87
86
|
btnCopy.disabled = false;
|
|
88
87
|
btnCopy.addEventListener('click', async () => {
|
|
89
88
|
try {
|
|
90
89
|
await navigator.clipboard.writeText(json.data);
|
|
91
90
|
const originalText = btnCopy.innerHTML;
|
|
92
91
|
btnCopy.innerHTML = `{{{icon "check" class="h-4 w-4"}}} Copied!`;
|
|
93
92
|
btnCopy.classList.add('text-success');
|
|
94
93
|
setTimeout(() => {
|
|
95
94
|
btnCopy.innerHTML = originalText;
|
|
96
95
|
btnCopy.classList.remove('text-success');
|
|
97
96
|
}, 2000);
|
|
98
97
|
} catch (err) {
|
|
99
98
|
console.error('Failed to copy', err);
|
|
100
99
|
}
|
|
101
100
|
});
|
|
102
101
|
} else {
|
|
103
102
|
if (json.success && !json.data) {
|
|
104
103
|
codeBlock.textContent = '-- No tables defined in the database.';
|
|
105
104
|
container.classList.remove('hidden');
|
|
106
105
|
} else {
|
|
107
106
|
throw new Error(json.error || 'Failed to fetch DDL');
|
|
108
107
|
}
|
|
109
108
|
}
|
|
110
109
|
} catch (err) {
|
|
111
110
|
loader.classList.add('hidden');
|
|
112
111
|
errorBox.classList.remove('hidden');
|
|
113
112
|
errorBox.querySelector('p').textContent = err.message || 'Failed to load schema.';
|
|
114
113
|
}
|
|
115
114
|
});
|
|
115
|
+
<div class="space-y-6">
|
|
116
116
|
<div class="page-header">
|
|
117
117
|
<div class="page-header-row">
|
|
118
118
|
<div>
|
|
119
119
|
<div class="page-pretitle">{{dialect}} Database</div>
|
|
120
120
|
<h1 class="page-title">Info & Settings</h1>
|
|
121
121
|
<p class="mt-0.5 text-xs text-base-content/60">Database configuration, settings, and schema DDL overview.</p>
|
|
122
122
|
</div>
|
|
123
123
|
</div>
|
|
124
124
|
</div>
|
|
125
125
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
126
126
|
<div class="lg:col-span-1 space-y-6">
|
|
127
127
|
{{#if isDefaultPassword}}
|
|
128
128
|
<div class="alert alert-warning text-xs shadow-xs rounded-2xl border border-warning/30 p-3.5">
|
|
129
129
|
{{{icon "warning" class="h-5 w-5 shrink-0 text-warning"}}}
|
|
130
130
|
<div>
|
|
131
131
|
<div class="font-bold text-sm">Default Password in Use</div>
|
|
132
132
|
<div class="text-base-content/80 mt-0.5 leading-relaxed">Console is running with default password (<code class="font-mono font-semibold">admin</code>). Run <code class="font-mono font-semibold">npm run generatehash</code> and set <code class="font-mono font-semibold">ADMINDB_PASSWORD</code>.</div>
|
|
133
133
|
</div>
|
|
134
134
|
</div>
|
|
135
135
|
{{/if}}
|
|
136
136
|
<div class="app-card overflow-hidden">
|
|
137
137
|
<div class="border-b border-base-200 bg-base-200/40 px-4 py-3">
|
|
138
138
|
<h2 class="text-sm font-bold uppercase tracking-wider text-base-content/80">Settings / Configuration</h2>
|
|
139
139
|
</div>
|
|
140
140
|
<div class="p-0">
|
|
141
141
|
<table class="table table-sm w-full">
|
|
142
142
|
<tbody>
|
|
143
143
|
{{#each settings}}
|
|
144
144
|
<tr class="hover:bg-base-200/20">
|
|
145
145
|
<td class="font-medium text-base-content/70 w-1/2">{{@key}}</td>
|
|
146
146
|
<td class="font-mono text-xs">{{this}}</td>
|
|
147
147
|
</tr>
|
|
148
148
|
{{else}}
|
|
149
149
|
<tr>
|
|
150
150
|
<td colspan="2" class="p-4 text-center text-sm text-base-content/40">No settings available</td>
|
|
151
151
|
</tr>
|
|
152
152
|
{{/each}}
|
|
153
153
|
</tbody>
|
|
154
154
|
</table>
|
|
155
155
|
</div>
|
|
156
156
|
</div>
|
|
157
157
|
</div>
|
|
158
158
|
<div class="lg:col-span-2 space-y-6">
|
|
159
159
|
<div class="app-card overflow-hidden flex flex-col h-[75vh]">
|
|
160
160
|
<div class="border-b border-base-200 bg-base-200/40 px-4 py-3 flex items-center justify-between">
|
|
161
161
|
<div class="flex items-center gap-3">
|
|
162
162
|
<h2 class="text-sm font-bold uppercase tracking-wider text-base-content/80">Schema DDL</h2>
|
|
163
163
|
<span class="badge badge-sm badge-ghost font-mono text-[10px] uppercase font-bold">{{dialect}}</span>
|
|
164
164
|
</div>
|
|
165
165
|
<button id="btn-copy-ddl" class="btn btn-sm btn-ghost gap-1.5" disabled>
|
|
166
166
|
{{{icon "copy" class="h-4 w-4"}}}
|
|
167
167
|
Copy
|
|
168
168
|
</button>
|
|
169
169
|
</div>
|
|
170
170
|
<div class="bg-base-300 p-4 overflow-y-auto flex-1 relative">
|
|
171
171
|
<div id="ddl-loader" class="absolute inset-0 flex flex-col items-center justify-center text-base-content/50 gap-3">
|
|
172
172
|
{{{icon "spinner" class="h-6 w-6 animate-spin text-primary"}}}
|
|
173
173
|
<p class="text-sm font-medium">Extracting schema definitions...</p>
|
|
174
174
|
</div>
|
|
175
175
|
<div id="ddl-error" class="hidden absolute inset-0 flex flex-col items-center justify-center text-error gap-3 bg-base-300">
|
|
176
176
|
{{{icon "error" class="h-8 w-8"}}}
|
|
177
177
|
<p class="text-sm font-medium">Failed to load schema.</p>
|
|
178
178
|
</div>
|
|
179
179
|
<pre id="ddl-container" class="hidden m-0 h-full"><code class="language-sql text-sm text-base-content/80 whitespace-pre-wrap"></code></pre>
|
|
180
180
|
</div>
|
|
181
181
|
</div>
|
|
182
182
|
</div>
|
|
183
183
|
</div>
|
|
184
184
|
document.addEventListener('DOMContentLoaded', async () => {
|
|
185
185
|
const loader = document.getElementById('ddl-loader');
|
|
186
186
|
const container = document.getElementById('ddl-container');
|
|
187
187
|
const codeBlock = container.querySelector('code');
|
|
188
188
|
const btnCopy = document.getElementById('btn-copy-ddl');
|
|
189
189
|
const errorBox = document.getElementById('ddl-error');
|
|
190
190
|
try {
|
|
191
191
|
const res = await fetch('{{basePath}}/api/info/{{encodeUri dbId}}/ddl');
|
|
192
192
|
const json = await res.json();
|
|
193
193
|
loader.classList.add('hidden');
|
|
194
194
|
if (json.success && json.data) {
|
|
195
195
|
if (window.Utils && window.Utils.highlightSql) {
|
|
196
196
|
codeBlock.innerHTML = window.Utils.highlightSql(json.data);
|
|
197
197
|
} else {
|
|
198
198
|
codeBlock.textContent = json.data;
|
|
199
199
|
}
|
|
200
200
|
container.classList.remove('hidden');
|
|
201
201
|
btnCopy.disabled = false;
|
|
202
202
|
btnCopy.addEventListener('click', async () => {
|
|
203
203
|
try {
|
|
204
204
|
await navigator.clipboard.writeText(json.data);
|
|
205
205
|
const originalText = btnCopy.innerHTML;
|
|
206
206
|
btnCopy.innerHTML = `{{{icon "check" class="h-4 w-4"}}} Copied!`;
|
|
207
207
|
btnCopy.classList.add('text-success');
|
|
208
208
|
setTimeout(() => {
|
|
209
209
|
btnCopy.innerHTML = originalText;
|
|
210
210
|
btnCopy.classList.remove('text-success');
|
|
211
211
|
}, 2000);
|
|
212
212
|
} catch (err) {
|
|
213
213
|
console.error('Failed to copy', err);
|
|
214
214
|
}
|
|
215
215
|
});
|
|
216
216
|
} else {
|
|
217
217
|
if (json.success && !json.data) {
|
|
218
218
|
codeBlock.textContent = '-- No tables defined in the database.';
|
|
219
219
|
container.classList.remove('hidden');
|
|
220
220
|
} else {
|
|
221
221
|
throw new Error(json.error || 'Failed to fetch DDL');
|
|
222
222
|
}
|
|
223
223
|
}
|
|
224
224
|
} catch (err) {
|
|
225
225
|
loader.classList.add('hidden');
|
|
226
226
|
errorBox.classList.remove('hidden');
|
|
227
227
|
errorBox.querySelector('p').textContent = err.message || 'Failed to load schema.';
|
|
228
228
|
}
|
|
229
229
|
});
|