admindb 2.1.0 → 2.2.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 +41 -12
- package/dist/app.d.ts +1 -69
- package/dist/app.js +3 -30
- package/dist/auth/config.d.ts +1 -19
- package/dist/auth/config.js +0 -26
- package/dist/auth/crypto.d.ts +1 -27
- package/dist/auth/crypto.js +1 -26
- package/dist/auth/index.d.ts +1 -5
- package/dist/auth/index.js +0 -1
- package/dist/auth/middleware.d.ts +1 -14
- package/dist/auth/middleware.js +0 -15
- package/dist/auth/routes.d.ts +1 -7
- package/dist/auth/routes.js +0 -8
- package/dist/auth/types.d.ts +1 -35
- package/dist/auth/types.js +1 -5
- package/dist/cli/args.d.ts +1 -45
- package/dist/cli/args.js +3 -11
- package/dist/cli/config.d.ts +1 -56
- package/dist/cli/config.js +0 -5
- package/dist/cli/index.d.ts +1 -4
- package/dist/cli/index.js +0 -1
- package/dist/cli/runner.d.ts +1 -1
- package/dist/cli/runner.js +6 -17
- package/dist/cli.d.ts +1 -2
- package/dist/cli.js +0 -1
- package/dist/data/chain.d.ts +1 -0
- package/dist/data/chain.js +707 -0
- package/dist/data/datasets.d.ts +1 -17
- package/dist/data/datasets.js +0 -4
- package/dist/data/detector.d.ts +1 -30
- package/dist/data/detector.js +53 -14
- package/dist/data/engine.d.ts +1 -10
- package/dist/data/engine.js +82 -48
- package/dist/data/index.d.ts +1 -5
- package/dist/data/index.js +1 -1
- package/dist/data/strategies.d.ts +1 -30
- package/dist/data/strategies.js +4 -8
- package/dist/data/types.d.ts +1 -73
- package/dist/data/types.js +0 -3
- package/dist/db/database.d.ts +1 -119
- package/dist/db/database.js +20 -14
- package/dist/db/export.d.ts +1 -12
- package/dist/db/export.js +54 -6
- package/dist/db/filters.d.ts +1 -22
- package/dist/db/filters.js +0 -16
- package/dist/db/index.d.ts +1 -8
- package/dist/db/index.js +0 -1
- package/dist/db/introspection.d.ts +1 -6
- package/dist/db/introspection.js +0 -5
- package/dist/db/manager.d.ts +1 -81
- package/dist/db/manager.js +13 -59
- package/dist/db/migrations.d.ts +1 -5
- package/dist/db/migrations.js +2 -5
- package/dist/db/postgres.d.ts +1 -85
- package/dist/db/postgres.js +21 -31
- package/dist/db/types.d.ts +1 -206
- package/dist/db/types.js +0 -1
- package/dist/index.d.ts +1 -23
- package/dist/index.js +0 -14
- package/dist/public/css/app.css +1 -1
- package/dist/public/js/api.js +1 -47
- package/dist/public/js/app.js +1 -262
- package/dist/public/js/browse.js +1 -1371
- package/dist/public/js/common.js +1 -0
- package/dist/public/js/databases.js +1 -235
- package/dist/public/js/designer.js +1 -258
- package/dist/public/js/forms.js +1 -826
- package/dist/public/js/home.js +1 -0
- package/dist/public/js/inspector.js +1 -638
- package/dist/public/js/query.js +1 -322
- package/dist/public/js/schema.js +1 -447
- package/dist/public/js/seed.js +1 -1090
- package/dist/routes/api/erd.d.ts +1 -0
- package/dist/routes/api/erd.js +50 -0
- package/dist/routes/api/helpers.d.ts +1 -42
- package/dist/routes/api/helpers.js +33 -3
- package/dist/routes/api/import-export.d.ts +1 -3
- package/dist/routes/api/import-export.js +0 -2
- package/dist/routes/api/index.d.ts +1 -4
- package/dist/routes/api/index.js +15 -4
- package/dist/routes/api/query.d.ts +1 -3
- package/dist/routes/api/query.js +13 -11
- package/dist/routes/api/rows.d.ts +1 -3
- package/dist/routes/api/rows.js +0 -11
- package/dist/routes/api/seed.d.ts +1 -3
- package/dist/routes/api/seed.js +79 -8
- package/dist/routes/api/tables.d.ts +1 -3
- package/dist/routes/api/tables.js +77 -6
- package/dist/routes/databases.d.ts +1 -26
- package/dist/routes/databases.js +1 -3
- package/dist/routes/index.d.ts +1 -3
- package/dist/routes/index.js +0 -1
- package/dist/routes/pages.d.ts +1 -9
- package/dist/routes/pages.js +18 -11
- package/dist/serverless.d.ts +1 -40
- package/dist/serverless.js +3 -39
- package/dist/sql/classifier.d.ts +1 -19
- package/dist/sql/classifier.js +0 -13
- package/dist/sql/error-analyzer.d.ts +1 -0
- package/dist/sql/error-analyzer.js +550 -0
- package/dist/sql/generator.d.ts +1 -81
- package/dist/sql/generator.js +0 -29
- package/dist/sql/index.d.ts +1 -2
- package/dist/sql/index.js +0 -1
- package/dist/types/api.d.ts +1 -412
- package/dist/types/api.js +0 -7
- package/dist/utils/colors.d.ts +1 -40
- package/dist/utils/colors.js +0 -10
- package/dist/utils/common.d.ts +1 -50
- package/dist/utils/common.js +19 -23
- package/dist/utils/csv.d.ts +1 -15
- package/dist/utils/csv.js +0 -13
- package/dist/utils/datatype.d.ts +1 -49
- package/dist/utils/datatype.js +0 -41
- package/dist/utils/icons.d.ts +1 -11
- package/dist/utils/icons.js +25 -16
- package/dist/utils/index.d.ts +1 -4
- package/dist/utils/index.js +0 -1
- package/dist/utils/logger.d.ts +1 -10
- package/dist/utils/logger.js +0 -4
- package/dist/views/layouts/main.hbs +14 -5
- package/dist/views/pages/databases.hbs +0 -18
- package/dist/views/pages/designer.hbs +0 -10
- package/dist/views/pages/erd.hbs +1241 -0
- package/dist/views/pages/error.hbs +0 -2
- package/dist/views/pages/form.hbs +0 -5
- package/dist/views/pages/home.hbs +98 -10
- package/dist/views/pages/info.hbs +107 -0
- package/dist/views/pages/login.hbs +0 -13
- package/dist/views/pages/query.hbs +54 -21
- package/dist/views/pages/schema.hbs +0 -20
- package/dist/views/pages/seed.hbs +435 -202
- package/dist/views/pages/table.hbs +0 -14
- package/dist/views/partials/icon.hbs +0 -1
- package/dist/views/partials/navbar.hbs +0 -6
- package/dist/views/partials/sidebar.hbs +12 -8
- package/docs/API.md +6 -1
- package/docs/EXAMPLES.md +3 -0
- package/package.json +7 -5
- package/dist/app.js.map +0 -1
- package/dist/auth/config.js.map +0 -1
- package/dist/auth/crypto.js.map +0 -1
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/middleware.js.map +0 -1
- package/dist/auth/routes.js.map +0 -1
- package/dist/auth/types.js.map +0 -1
- package/dist/cli/args.js.map +0 -1
- package/dist/cli/config.js.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/runner.js.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/data/datasets.js.map +0 -1
- package/dist/data/detector.js.map +0 -1
- package/dist/data/engine.js.map +0 -1
- package/dist/data/index.js.map +0 -1
- package/dist/data/strategies.js.map +0 -1
- package/dist/data/types.js.map +0 -1
- package/dist/db/database.js.map +0 -1
- package/dist/db/export.js.map +0 -1
- package/dist/db/filters.js.map +0 -1
- package/dist/db/index.js.map +0 -1
- package/dist/db/introspection.js.map +0 -1
- package/dist/db/manager.js.map +0 -1
- package/dist/db/migrations.js.map +0 -1
- package/dist/db/postgres.js.map +0 -1
- package/dist/db/types.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/public/css/input.css +0 -302
- package/dist/public/js/icons.js +0 -51
- package/dist/routes/api/helpers.js.map +0 -1
- package/dist/routes/api/import-export.js.map +0 -1
- package/dist/routes/api/index.js.map +0 -1
- package/dist/routes/api/query.js.map +0 -1
- package/dist/routes/api/rows.js.map +0 -1
- package/dist/routes/api/seed.js.map +0 -1
- package/dist/routes/api/tables.js.map +0 -1
- package/dist/routes/databases.js.map +0 -1
- package/dist/routes/index.js.map +0 -1
- package/dist/routes/pages.js.map +0 -1
- package/dist/serverless.js.map +0 -1
- package/dist/sql/classifier.js.map +0 -1
- package/dist/sql/generator.js.map +0 -1
- package/dist/sql/index.js.map +0 -1
- package/dist/types/api.js.map +0 -1
- package/dist/utils/colors.js.map +0 -1
- package/dist/utils/common.js.map +0 -1
- package/dist/utils/csv.js.map +0 -1
- package/dist/utils/datatype.js.map +0 -1
- package/dist/utils/icons.js.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/logger.js.map +0 -1
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
{{!-- Page: Error Display · URL: HTTP 404 / 500 Error Handlers --}}
|
|
2
1
|
<div class="mx-auto mt-16 max-w-md space-y-6 text-center">
|
|
3
|
-
|
|
4
2
|
<div class="mx-auto grid h-20 w-20 place-items-center rounded-3xl bg-error/10 text-error">
|
|
5
3
|
{{{icon "warning" class="h-10 w-10"}}}
|
|
6
4
|
</div>
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
{{!-- Page: Row Editor & Inserter · URL: /tables/:table/rows/new or /tables/:table/rows/:id/edit --}}
|
|
2
1
|
<div class="mx-auto max-w-3xl space-y-5">
|
|
3
|
-
|
|
4
|
-
<!-- Header -->
|
|
5
2
|
<div class="flex items-center gap-3">
|
|
6
3
|
<a href="{{basePath}}/tables/{{table}}" class="btn btn-circle btn-ghost btn-sm" aria-label="Back to table">
|
|
7
4
|
{{{icon "arrowLeft" class="h-5 w-5"}}}
|
|
@@ -14,7 +11,6 @@
|
|
|
14
11
|
<p class="text-sm text-base-content/55">{{infoSummary}}</p>
|
|
15
12
|
</div>
|
|
16
13
|
</div>
|
|
17
|
-
|
|
18
14
|
<div class="app-card">
|
|
19
15
|
<div class="border-b border-base-200 px-6 py-4">
|
|
20
16
|
<h2 class="text-sm font-semibold uppercase tracking-wide text-base-content/45">Row fields</h2>
|
|
@@ -42,7 +38,6 @@
|
|
|
42
38
|
</p>
|
|
43
39
|
</div>
|
|
44
40
|
</div>
|
|
45
|
-
|
|
46
41
|
<div id="generated-sql" class="hidden">
|
|
47
42
|
<div class="app-card">
|
|
48
43
|
<div class="flex items-center justify-between border-b border-base-200 px-6 py-4">
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
{{!-- Page: Database Overview Dashboard · URL: / (or /{basePath}/) --}}
|
|
2
1
|
<div class="space-y-8">
|
|
3
|
-
|
|
4
|
-
<!-- Header -->
|
|
5
2
|
<div class="flex flex-wrap items-end justify-between gap-4">
|
|
6
3
|
<div>
|
|
7
4
|
<p class="text-sm font-semibold uppercase tracking-wider text-primary">Overview</p>
|
|
@@ -21,8 +18,6 @@
|
|
|
21
18
|
{{/unless}}
|
|
22
19
|
</div>
|
|
23
20
|
</div>
|
|
24
|
-
|
|
25
|
-
<!-- Stat cards -->
|
|
26
21
|
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4">
|
|
27
22
|
<div class="stat-card">
|
|
28
23
|
<span class="stat-icon bg-primary/10 text-primary">
|
|
@@ -68,20 +63,102 @@
|
|
|
68
63
|
</div>
|
|
69
64
|
</div>
|
|
70
65
|
</div>
|
|
71
|
-
|
|
72
|
-
<!-- Tables -->
|
|
73
66
|
<div>
|
|
74
67
|
<div class="mb-3 flex items-center justify-between">
|
|
75
68
|
<h2 class="text-lg font-bold">Tables</h2>
|
|
76
69
|
<span class="text-sm text-base-content/45">{{tables.length}} total</span>
|
|
77
70
|
</div>
|
|
78
|
-
|
|
79
71
|
{{#if tables.length}}
|
|
72
|
+
{{#unless readonly}}
|
|
73
|
+
<div id="home-bulk-toolbar"
|
|
74
|
+
style="max-height: 0; overflow: hidden; transition: max-height 0.22s cubic-bezier(0.4,0,0.2,1), opacity 0.18s ease; opacity: 0;"
|
|
75
|
+
aria-hidden="true">
|
|
76
|
+
<div class="mb-3 flex flex-wrap items-center gap-3 rounded-xl border border-base-300 bg-base-100 px-4 py-3 shadow-soft">
|
|
77
|
+
<span id="home-bulk-count"
|
|
78
|
+
class="inline-flex items-center gap-1.5 rounded-full bg-primary/10 px-3 py-1 text-xs font-bold text-primary">
|
|
79
|
+
<span id="home-bulk-count-num">0</span> selected
|
|
80
|
+
</span>
|
|
81
|
+
<div class="h-4 w-px bg-base-300"></div>
|
|
82
|
+
<div class="dropdown dropdown-bottom" id="home-dd-clear">
|
|
83
|
+
<button tabindex="0" id="home-btn-clear"
|
|
84
|
+
class="btn btn-sm btn-warning gap-1.5 font-semibold">
|
|
85
|
+
{{{icon "refresh" class="h-3.5 w-3.5"}}}
|
|
86
|
+
Clear Rows
|
|
87
|
+
{{{icon "chevronDown" class="h-3 w-3 opacity-60"}}}
|
|
88
|
+
</button>
|
|
89
|
+
<ul tabindex="0"
|
|
90
|
+
class="dropdown-content menu bg-base-100 rounded-xl border border-base-300 shadow-lift z-30 mt-1 w-64 p-2 text-sm">
|
|
91
|
+
<li>
|
|
92
|
+
<button id="home-clear-normal" class="flex items-start gap-2.5 rounded-lg px-3 py-2.5 hover:bg-base-200 text-left w-full">
|
|
93
|
+
<span class="mt-0.5 text-warning shrink-0">{{{icon "warning" class="h-4 w-4"}}}</span>
|
|
94
|
+
<span>
|
|
95
|
+
<span class="block font-semibold">Clear rows</span>
|
|
96
|
+
<span class="block text-xs text-base-content/50">Deletes all rows; fails if FK references exist</span>
|
|
97
|
+
</span>
|
|
98
|
+
</button>
|
|
99
|
+
</li>
|
|
100
|
+
<li>
|
|
101
|
+
<button id="home-clear-force" class="flex items-start gap-2.5 rounded-lg px-3 py-2.5 hover:bg-error/10 text-left w-full text-error">
|
|
102
|
+
<span class="mt-0.5 shrink-0">{{{icon "warning" class="h-4 w-4"}}}</span>
|
|
103
|
+
<span>
|
|
104
|
+
<span class="block font-semibold">Force Clear <span class="text-[10px] font-bold uppercase tracking-wide rounded bg-error/15 px-1 py-0.5 ml-1">ignore FK</span></span>
|
|
105
|
+
<span class="block text-xs text-error/60">Disables FK checks; deletes regardless of references</span>
|
|
106
|
+
</span>
|
|
107
|
+
</button>
|
|
108
|
+
</li>
|
|
109
|
+
</ul>
|
|
110
|
+
</div>
|
|
111
|
+
<div class="dropdown dropdown-bottom" id="home-dd-drop">
|
|
112
|
+
<button tabindex="0" id="home-btn-drop"
|
|
113
|
+
class="btn btn-sm btn-error gap-1.5 font-semibold text-white">
|
|
114
|
+
{{{icon "warning" class="h-3.5 w-3.5"}}}
|
|
115
|
+
Drop Tables
|
|
116
|
+
{{{icon "chevronDown" class="h-3 w-3 opacity-60"}}}
|
|
117
|
+
</button>
|
|
118
|
+
<ul tabindex="0"
|
|
119
|
+
class="dropdown-content menu bg-base-100 rounded-xl border border-base-300 shadow-lift z-30 mt-1 w-64 p-2 text-sm">
|
|
120
|
+
<li>
|
|
121
|
+
<button id="home-drop-normal" class="flex items-start gap-2.5 rounded-lg px-3 py-2.5 hover:bg-base-200 text-left w-full">
|
|
122
|
+
<span class="mt-0.5 text-error shrink-0">{{{icon "warning" class="h-4 w-4"}}}</span>
|
|
123
|
+
<span>
|
|
124
|
+
<span class="block font-semibold">Drop tables</span>
|
|
125
|
+
<span class="block text-xs text-base-content/50">Permanently deletes tables and all data</span>
|
|
126
|
+
</span>
|
|
127
|
+
</button>
|
|
128
|
+
</li>
|
|
129
|
+
<li>
|
|
130
|
+
<button id="home-drop-force" class="flex items-start gap-2.5 rounded-lg px-3 py-2.5 hover:bg-error/10 text-left w-full text-error">
|
|
131
|
+
<span class="mt-0.5 shrink-0">{{{icon "warning" class="h-4 w-4"}}}</span>
|
|
132
|
+
<span>
|
|
133
|
+
<span class="block font-semibold">Force Drop <span class="text-[10px] font-bold uppercase tracking-wide rounded bg-error/15 px-1 py-0.5 ml-1">ignore FK</span></span>
|
|
134
|
+
<span class="block text-xs text-error/60">Drops with FK checks disabled; cascades on Postgres</span>
|
|
135
|
+
</span>
|
|
136
|
+
</button>
|
|
137
|
+
</li>
|
|
138
|
+
</ul>
|
|
139
|
+
</div>
|
|
140
|
+
<div class="ml-auto">
|
|
141
|
+
<button id="home-bulk-deselect"
|
|
142
|
+
class="btn btn-ghost btn-sm gap-1 text-base-content/50 hover:text-base-content">
|
|
143
|
+
{{{icon "x" class="h-3.5 w-3.5"}}}
|
|
144
|
+
Deselect all
|
|
145
|
+
</button>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
{{/unless}}
|
|
80
150
|
<div class="app-card overflow-hidden">
|
|
81
151
|
<div class="overflow-x-auto">
|
|
82
|
-
<table class="table table-sm">
|
|
152
|
+
<table class="table table-sm" id="home-tables-table">
|
|
83
153
|
<thead>
|
|
84
154
|
<tr class="bg-base-200/70 text-xs uppercase tracking-wide text-base-content/50">
|
|
155
|
+
{{#unless readonly}}
|
|
156
|
+
<th class="w-10">
|
|
157
|
+
<input type="checkbox" id="home-select-all"
|
|
158
|
+
class="checkbox checkbox-sm checkbox-primary"
|
|
159
|
+
title="Select all tables" />
|
|
160
|
+
</th>
|
|
161
|
+
{{/unless}}
|
|
85
162
|
<th class="font-semibold">Table</th>
|
|
86
163
|
<th class="text-right font-semibold">Columns</th>
|
|
87
164
|
<th class="text-right font-semibold">Rows</th>
|
|
@@ -90,7 +167,15 @@
|
|
|
90
167
|
</thead>
|
|
91
168
|
<tbody>
|
|
92
169
|
{{#each tables}}
|
|
93
|
-
<tr class="group hover:bg-base-200/50">
|
|
170
|
+
<tr class="group hover:bg-base-200/50 home-table-row" data-table="{{this}}">
|
|
171
|
+
{{#unless ../readonly}}
|
|
172
|
+
<td class="w-10">
|
|
173
|
+
<input type="checkbox"
|
|
174
|
+
class="checkbox checkbox-sm checkbox-primary home-table-checkbox"
|
|
175
|
+
data-table="{{this}}"
|
|
176
|
+
title="Select {{this}}" />
|
|
177
|
+
</td>
|
|
178
|
+
{{/unless}}
|
|
94
179
|
<td>
|
|
95
180
|
<a href="{{../basePath}}/tables/{{this}}" class="inline-flex items-center gap-2.5 font-medium">
|
|
96
181
|
<span class="grid h-8 w-8 place-items-center rounded-lg bg-primary/10 text-primary transition-colors group-hover:bg-primary/20">
|
|
@@ -130,3 +215,6 @@
|
|
|
130
215
|
{{/if}}
|
|
131
216
|
</div>
|
|
132
217
|
</div>
|
|
218
|
+
{{#unless readonly}}
|
|
219
|
+
<script src="{{basePath}}/js/home.js" defer></script>
|
|
220
|
+
{{/unless}}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<div class="space-y-6">
|
|
2
|
+
<div class="flex flex-wrap items-center justify-between gap-3">
|
|
3
|
+
<div>
|
|
4
|
+
<p class="text-sm font-semibold uppercase tracking-wider text-primary">{{dialect}} Database</p>
|
|
5
|
+
<h1 class="mt-1 text-3xl font-extrabold tracking-tight">Info & Settings</h1>
|
|
6
|
+
<p class="mt-1.5 text-sm text-base-content/55">Database configuration, settings, and schema DDL overview.</p>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
10
|
+
<div class="lg:col-span-1 space-y-6">
|
|
11
|
+
<div class="app-card overflow-hidden">
|
|
12
|
+
<div class="border-b border-base-200 bg-base-200/40 px-4 py-3">
|
|
13
|
+
<h2 class="text-sm font-bold uppercase tracking-wider text-base-content/80">Settings / Configuration</h2>
|
|
14
|
+
</div>
|
|
15
|
+
<div class="p-0">
|
|
16
|
+
<table class="table table-sm w-full">
|
|
17
|
+
<tbody>
|
|
18
|
+
{{#each settings}}
|
|
19
|
+
<tr class="hover:bg-base-200/20">
|
|
20
|
+
<td class="font-medium text-base-content/70 w-1/2">{{@key}}</td>
|
|
21
|
+
<td class="font-mono text-xs">{{this}}</td>
|
|
22
|
+
</tr>
|
|
23
|
+
{{else}}
|
|
24
|
+
<tr>
|
|
25
|
+
<td colspan="2" class="p-4 text-center text-sm text-base-content/40">No settings available</td>
|
|
26
|
+
</tr>
|
|
27
|
+
{{/each}}
|
|
28
|
+
</tbody>
|
|
29
|
+
</table>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="lg:col-span-2 space-y-6">
|
|
34
|
+
<div class="app-card overflow-hidden flex flex-col h-[75vh]">
|
|
35
|
+
<div class="border-b border-base-200 bg-base-200/40 px-4 py-3 flex items-center justify-between">
|
|
36
|
+
<div class="flex items-center gap-3">
|
|
37
|
+
<h2 class="text-sm font-bold uppercase tracking-wider text-base-content/80">Schema DDL</h2>
|
|
38
|
+
<span class="badge badge-sm badge-ghost font-mono text-[10px] uppercase font-bold">{{dialect}}</span>
|
|
39
|
+
</div>
|
|
40
|
+
<button id="btn-copy-ddl" class="btn btn-sm btn-ghost gap-1.5" disabled>
|
|
41
|
+
{{{icon "copy" class="h-4 w-4"}}}
|
|
42
|
+
Copy
|
|
43
|
+
</button>
|
|
44
|
+
</div>
|
|
45
|
+
<div class="bg-base-300 p-4 overflow-y-auto flex-1 relative">
|
|
46
|
+
<div id="ddl-loader" class="absolute inset-0 flex flex-col items-center justify-center text-base-content/50 gap-3">
|
|
47
|
+
{{{icon "spinner" class="h-6 w-6 animate-spin text-primary"}}}
|
|
48
|
+
<p class="text-sm font-medium">Extracting schema definitions...</p>
|
|
49
|
+
</div>
|
|
50
|
+
<div id="ddl-error" class="hidden absolute inset-0 flex flex-col items-center justify-center text-error gap-3 bg-base-300">
|
|
51
|
+
{{{icon "error" class="h-8 w-8"}}}
|
|
52
|
+
<p class="text-sm font-medium">Failed to load schema.</p>
|
|
53
|
+
</div>
|
|
54
|
+
<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>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
<script>
|
|
61
|
+
document.addEventListener('DOMContentLoaded', async () => {
|
|
62
|
+
const loader = document.getElementById('ddl-loader');
|
|
63
|
+
const container = document.getElementById('ddl-container');
|
|
64
|
+
const codeBlock = container.querySelector('code');
|
|
65
|
+
const btnCopy = document.getElementById('btn-copy-ddl');
|
|
66
|
+
const errorBox = document.getElementById('ddl-error');
|
|
67
|
+
try {
|
|
68
|
+
const res = await fetch('{{basePath}}/api/info/ddl');
|
|
69
|
+
const json = await res.json();
|
|
70
|
+
loader.classList.add('hidden');
|
|
71
|
+
if (json.success && json.data) {
|
|
72
|
+
if (window.Utils && window.Utils.highlightSql) {
|
|
73
|
+
codeBlock.innerHTML = window.Utils.highlightSql(json.data);
|
|
74
|
+
} else {
|
|
75
|
+
codeBlock.textContent = json.data;
|
|
76
|
+
}
|
|
77
|
+
container.classList.remove('hidden');
|
|
78
|
+
btnCopy.disabled = false;
|
|
79
|
+
btnCopy.addEventListener('click', async () => {
|
|
80
|
+
try {
|
|
81
|
+
await navigator.clipboard.writeText(json.data);
|
|
82
|
+
const originalText = btnCopy.innerHTML;
|
|
83
|
+
btnCopy.innerHTML = `{{{icon "check" class="h-4 w-4"}}} Copied!`;
|
|
84
|
+
btnCopy.classList.add('text-success');
|
|
85
|
+
setTimeout(() => {
|
|
86
|
+
btnCopy.innerHTML = originalText;
|
|
87
|
+
btnCopy.classList.remove('text-success');
|
|
88
|
+
}, 2000);
|
|
89
|
+
} catch (err) {
|
|
90
|
+
console.error('Failed to copy', err);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
} else {
|
|
94
|
+
if (json.success && !json.data) {
|
|
95
|
+
codeBlock.textContent = '-- No tables defined in the database.';
|
|
96
|
+
container.classList.remove('hidden');
|
|
97
|
+
} else {
|
|
98
|
+
throw new Error(json.error || 'Failed to fetch DDL');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} catch (err) {
|
|
102
|
+
loader.classList.add('hidden');
|
|
103
|
+
errorBox.classList.remove('hidden');
|
|
104
|
+
errorBox.querySelector('p').textContent = err.message || 'Failed to load schema.';
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
</script>
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
{{!-- Page: Authentication & Login · URL: /login --}}
|
|
2
1
|
<div class="flex min-h-[75vh] items-center justify-center py-6 px-4">
|
|
3
|
-
|
|
4
2
|
<div class="w-full max-w-md">
|
|
5
|
-
<!-- Brand Header -->
|
|
6
3
|
<div class="mb-8 text-center">
|
|
7
4
|
<div class="mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-2xl bg-primary/10 text-primary shadow-soft">
|
|
8
5
|
{{{icon "database" class="h-8 w-8"}}}
|
|
@@ -14,8 +11,6 @@
|
|
|
14
11
|
Sign in to access your database administration console
|
|
15
12
|
</p>
|
|
16
13
|
</div>
|
|
17
|
-
|
|
18
|
-
<!-- Login Card -->
|
|
19
14
|
<div class="app-card border border-base-300/80 bg-base-100 p-6 sm:p-8 shadow-soft">
|
|
20
15
|
{{#if error}}
|
|
21
16
|
<div class="mb-6 flex items-start gap-3 rounded-xl bg-error/10 p-4 text-sm text-error border border-error/20" role="alert">
|
|
@@ -25,7 +20,6 @@
|
|
|
25
20
|
<div class="font-medium">{{error}}</div>
|
|
26
21
|
</div>
|
|
27
22
|
{{/if}}
|
|
28
|
-
|
|
29
23
|
{{#if isDefaultPassword}}
|
|
30
24
|
<div class="mb-6 rounded-xl bg-info/10 p-3.5 text-xs text-info border border-info/20">
|
|
31
25
|
<div class="font-semibold flex items-center gap-1.5 mb-1">
|
|
@@ -40,12 +34,10 @@
|
|
|
40
34
|
</p>
|
|
41
35
|
</div>
|
|
42
36
|
{{/if}}
|
|
43
|
-
|
|
44
37
|
<form method="POST" action="{{basePath}}/login" class="space-y-4">
|
|
45
38
|
{{#if next}}
|
|
46
39
|
<input type="hidden" name="next" value="{{next}}" />
|
|
47
40
|
{{/if}}
|
|
48
|
-
|
|
49
41
|
<div>
|
|
50
42
|
<label class="field-label" for="login-username">
|
|
51
43
|
<span>Username</span>
|
|
@@ -67,7 +59,6 @@
|
|
|
67
59
|
</div>
|
|
68
60
|
</div>
|
|
69
61
|
</div>
|
|
70
|
-
|
|
71
62
|
<div>
|
|
72
63
|
<label class="field-label" for="login-password">
|
|
73
64
|
<span>Password</span>
|
|
@@ -87,7 +78,6 @@
|
|
|
87
78
|
</div>
|
|
88
79
|
</div>
|
|
89
80
|
</div>
|
|
90
|
-
|
|
91
81
|
<div class="pt-2">
|
|
92
82
|
<button type="submit" class="btn btn-primary w-full gap-2 font-semibold shadow-soft">
|
|
93
83
|
{{{icon "logout" class="h-4 w-4 rotate-180"}}}
|
|
@@ -96,8 +86,6 @@
|
|
|
96
86
|
</div>
|
|
97
87
|
</form>
|
|
98
88
|
</div>
|
|
99
|
-
|
|
100
|
-
<!-- Security & Auth Control Note -->
|
|
101
89
|
<div class="mt-6 space-y-2 text-center text-xs text-base-content/55">
|
|
102
90
|
<p class="leading-relaxed">
|
|
103
91
|
<span class="font-semibold text-base-content/80">Security Notice:</span> Built-in auth provides basic access control. For production, protect your admin routes using your own application authentication, VPN, or reverse proxy.
|
|
@@ -108,4 +96,3 @@
|
|
|
108
96
|
</div>
|
|
109
97
|
</div>
|
|
110
98
|
</div>
|
|
111
|
-
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
{{!-- Page: SQL Query Console & Workbench · URL: /query --}}
|
|
2
1
|
<div class="space-y-6">
|
|
3
|
-
|
|
4
|
-
<!-- Header -->
|
|
5
2
|
<div class="flex flex-wrap items-center justify-between gap-3">
|
|
6
3
|
<div>
|
|
7
4
|
<p class="text-sm font-semibold uppercase tracking-wider text-primary">Workspace</p>
|
|
@@ -21,8 +18,6 @@
|
|
|
21
18
|
</button>
|
|
22
19
|
</div>
|
|
23
20
|
</div>
|
|
24
|
-
|
|
25
|
-
<!-- Saved queries row -->
|
|
26
21
|
<div class="flex flex-wrap items-end gap-3">
|
|
27
22
|
<div class="form-control w-full max-w-xs">
|
|
28
23
|
<label class="field-label" for="saved-query-select">Saved queries</label>
|
|
@@ -44,28 +39,66 @@
|
|
|
44
39
|
</div>
|
|
45
40
|
{{/unless}}
|
|
46
41
|
</div>
|
|
47
|
-
|
|
48
|
-
<!-- Editor -->
|
|
49
42
|
<div class="app-card overflow-hidden">
|
|
50
|
-
<div class="flex items-center justify-between border-b border-base-200 bg-base-200/40 px-4 py-2
|
|
51
|
-
<
|
|
52
|
-
<span class="
|
|
53
|
-
|
|
43
|
+
<div class="flex flex-wrap items-center justify-between gap-2 border-b border-base-200 bg-base-200/40 px-4 py-2">
|
|
44
|
+
<div class="flex items-center gap-2">
|
|
45
|
+
<span class="flex items-center gap-1.5 text-xs font-semibold text-base-content/70">
|
|
46
|
+
<span class="grid h-5 w-5 place-items-center rounded bg-primary/10 text-primary">
|
|
47
|
+
{{{icon "query" class="h-3.5 w-3.5"}}}
|
|
48
|
+
</span>
|
|
49
|
+
query.sql
|
|
54
50
|
</span>
|
|
55
|
-
|
|
56
|
-
</
|
|
57
|
-
<
|
|
51
|
+
<span class="badge badge-sm badge-ghost font-mono text-[10px] uppercase font-bold">{{#if isPostgres}}Postgres{{else}}SQLite{{/if}}</span>
|
|
52
|
+
</div>
|
|
53
|
+
<div class="flex flex-wrap items-center gap-1.5">
|
|
54
|
+
<div class="dropdown dropdown-end">
|
|
55
|
+
<label tabindex="0" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary">
|
|
56
|
+
{{{icon "terminal" class="h-3.5 w-3.5"}}}
|
|
57
|
+
Snippets
|
|
58
|
+
</label>
|
|
59
|
+
<ul tabindex="0" class="dropdown-content z-30 menu p-1.5 shadow-2xl bg-base-100 rounded-xl w-56 border border-base-300 text-xs">
|
|
60
|
+
<li class="menu-title text-[10px] uppercase tracking-wider text-base-content/40">Query Templates</li>
|
|
61
|
+
<li><a class="js-snippet" data-snippet="SELECT * FROM table_name\nWHERE condition\nORDER BY id DESC\nLIMIT 50;">SELECT rows</a></li>
|
|
62
|
+
<li><a class="js-snippet" data-snippet="SELECT COUNT(*) AS total\nFROM table_name;">COUNT summary</a></li>
|
|
63
|
+
<li><a class="js-snippet" data-snippet="SELECT a.*, b.*\nFROM table_a a\nJOIN table_b b ON b.a_id = a.id\nLIMIT 50;">JOIN tables</a></li>
|
|
64
|
+
<li><a class="js-snippet" data-snippet="INSERT INTO table_name (col1, col2)\nVALUES ('value1', 'value2');">INSERT row</a></li>
|
|
65
|
+
<li><a class="js-snippet" data-snippet="UPDATE table_name\nSET col1 = 'value1'\nWHERE id = 1;">UPDATE row</a></li>
|
|
66
|
+
<li><a class="js-snippet" data-snippet="DELETE FROM table_name\nWHERE id = 1;">DELETE row</a></li>
|
|
67
|
+
<li><a class="js-snippet" data-snippet="CREATE TABLE new_table (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL,\n created_at TEXT DEFAULT (datetime('now'))\n);">CREATE TABLE</a></li>
|
|
68
|
+
</ul>
|
|
69
|
+
</div>
|
|
70
|
+
<button id="format-query" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary" title="Format SQL (Beautify)">
|
|
71
|
+
{{{icon "format" class="h-3.5 w-3.5"}}}
|
|
72
|
+
Format
|
|
73
|
+
</button>
|
|
74
|
+
<button id="copy-query" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary" title="Copy SQL to clipboard">
|
|
75
|
+
{{{icon "copy" class="h-3.5 w-3.5"}}}
|
|
76
|
+
Copy
|
|
77
|
+
</button>
|
|
78
|
+
<button id="clear-query" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-error" title="Clear editor">
|
|
79
|
+
{{{icon "trash" class="h-3.5 w-3.5"}}}
|
|
80
|
+
Clear
|
|
81
|
+
</button>
|
|
82
|
+
<span class="hidden sm:inline-block text-[11px] text-base-content/35 border-l border-base-300 pl-2">Ctrl/⌘ + Enter to run</span>
|
|
83
|
+
</div>
|
|
58
84
|
</div>
|
|
59
|
-
<div>
|
|
60
|
-
<div class="sql-
|
|
61
|
-
<
|
|
62
|
-
|
|
85
|
+
<div class="sql-editor-wrap">
|
|
86
|
+
<div id="query-gutter" class="sql-gutter" aria-hidden="true">
|
|
87
|
+
<div class="sql-gutter-line">1</div>
|
|
88
|
+
</div>
|
|
89
|
+
<div id="query-sql" class="sql-code-editor" contenteditable="plaintext-only" spellcheck="false" data-placeholder="-- Write SQL here or choose a snippet/saved query SELECT * FROM table_name WHERE …"></div>
|
|
90
|
+
</div>
|
|
91
|
+
<div class="flex items-center justify-between border-t border-base-200 bg-base-200/30 px-3.5 py-1.5 text-[11px] font-mono text-base-content/50">
|
|
92
|
+
<div class="flex items-center gap-3">
|
|
93
|
+
<span id="editor-cursor-pos">Ln 1, Col 1</span>
|
|
94
|
+
<span id="editor-stats">0 chars</span>
|
|
95
|
+
</div>
|
|
96
|
+
<div class="flex items-center gap-2">
|
|
97
|
+
<span class="text-[10px] text-base-content/40">Tab to indent · Ctrl+Z / Ctrl+Y to undo/redo · Ctrl+/ to comment</span>
|
|
63
98
|
</div>
|
|
64
|
-
<div id="query-message"></div>
|
|
65
99
|
</div>
|
|
100
|
+
<div id="query-message" class="p-3"></div>
|
|
66
101
|
</div>
|
|
67
|
-
|
|
68
|
-
<!-- Results -->
|
|
69
102
|
<div id="query-result" class="hidden">
|
|
70
103
|
<div class="app-card overflow-hidden">
|
|
71
104
|
<div class="flex items-center gap-2 border-b border-base-200 px-4 py-3">
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
{{!-- Page: Table Schema & Structure Inspector · URL: /tables/:table/schema --}}
|
|
2
1
|
<div class="space-y-6">
|
|
3
|
-
|
|
4
|
-
<!-- Header -->
|
|
5
2
|
<div class="flex flex-wrap items-center justify-between gap-3">
|
|
6
3
|
<div class="flex items-center gap-3.5">
|
|
7
4
|
<a href="{{basePath}}/tables/{{table}}" class="btn btn-circle btn-ghost btn-sm" aria-label="Back to table">
|
|
@@ -23,8 +20,6 @@
|
|
|
23
20
|
</a>
|
|
24
21
|
</div>
|
|
25
22
|
</div>
|
|
26
|
-
|
|
27
|
-
<!-- Rename table -->
|
|
28
23
|
<div class="app-card p-5">
|
|
29
24
|
<div class="flex flex-wrap items-end gap-3">
|
|
30
25
|
<div class="w-full max-w-sm">
|
|
@@ -38,8 +33,6 @@
|
|
|
38
33
|
{{#if isInternal}}<span class="mb-1 text-xs text-base-content/45">Internal tables cannot be renamed.</span>{{/if}}
|
|
39
34
|
</div>
|
|
40
35
|
</div>
|
|
41
|
-
|
|
42
|
-
<!-- Columns -->
|
|
43
36
|
<div class="app-card overflow-hidden">
|
|
44
37
|
<div class="flex flex-wrap items-center justify-between gap-2 border-b border-base-200 px-5 py-4">
|
|
45
38
|
<h2 class="text-sm font-semibold uppercase tracking-wide text-base-content/45">
|
|
@@ -51,7 +44,6 @@
|
|
|
51
44
|
Add column
|
|
52
45
|
</button>
|
|
53
46
|
</div>
|
|
54
|
-
|
|
55
47
|
<div id="add-column-panel" class="hidden border-b border-base-200 p-4">
|
|
56
48
|
<div class="mb-2 text-xs font-bold uppercase tracking-wider text-primary">Add New Column</div>
|
|
57
49
|
<div id="add-column-form" class="grid grid-cols-2 items-end gap-2.5 sm:grid-cols-12"></div>
|
|
@@ -61,7 +53,6 @@
|
|
|
61
53
|
<button id="add-column-cancel" type="button" class="btn btn-ghost btn-sm">Cancel</button>
|
|
62
54
|
</div>
|
|
63
55
|
</div>
|
|
64
|
-
|
|
65
56
|
<div id="edit-column-panel" class="hidden border-b border-base-200 bg-base-200/30 p-4">
|
|
66
57
|
<div class="mb-2.5 flex items-center justify-between">
|
|
67
58
|
<div class="flex items-center gap-2">
|
|
@@ -77,7 +68,6 @@
|
|
|
77
68
|
<button id="edit-column-cancel" type="button" class="btn btn-ghost btn-sm">Cancel</button>
|
|
78
69
|
</div>
|
|
79
70
|
</div>
|
|
80
|
-
|
|
81
71
|
<div class="overflow-x-auto">
|
|
82
72
|
<table class="table table-sm">
|
|
83
73
|
<thead>
|
|
@@ -136,8 +126,6 @@
|
|
|
136
126
|
</table>
|
|
137
127
|
</div>
|
|
138
128
|
</div>
|
|
139
|
-
|
|
140
|
-
<!-- Foreign keys -->
|
|
141
129
|
{{#if schema.foreignKeys.length}}
|
|
142
130
|
<div class="app-card overflow-hidden">
|
|
143
131
|
<div class="border-b border-base-200 px-5 py-4">
|
|
@@ -167,8 +155,6 @@
|
|
|
167
155
|
</div>
|
|
168
156
|
</div>
|
|
169
157
|
{{/if}}
|
|
170
|
-
|
|
171
|
-
<!-- Indexes -->
|
|
172
158
|
<div class="app-card overflow-hidden">
|
|
173
159
|
<div class="flex flex-wrap items-center justify-between gap-2 border-b border-base-200 px-5 py-4">
|
|
174
160
|
<h2 class="text-sm font-semibold uppercase tracking-wide text-base-content/45">
|
|
@@ -180,7 +166,6 @@
|
|
|
180
166
|
Add index
|
|
181
167
|
</button>
|
|
182
168
|
</div>
|
|
183
|
-
|
|
184
169
|
<div id="add-index-panel" class="hidden border-b border-base-200 p-4">
|
|
185
170
|
<div class="grid grid-cols-1 gap-3 sm:grid-cols-3">
|
|
186
171
|
<div>
|
|
@@ -216,7 +201,6 @@
|
|
|
216
201
|
<button id="add-index-cancel" type="button" class="btn btn-ghost btn-sm">Cancel</button>
|
|
217
202
|
</div>
|
|
218
203
|
</div>
|
|
219
|
-
|
|
220
204
|
<div class="overflow-x-auto">
|
|
221
205
|
{{#if schema.indexes.length}}
|
|
222
206
|
<table class="table table-sm">
|
|
@@ -266,8 +250,6 @@
|
|
|
266
250
|
{{/if}}
|
|
267
251
|
</div>
|
|
268
252
|
</div>
|
|
269
|
-
|
|
270
|
-
<!-- Referenced by -->
|
|
271
253
|
{{#if schema.references.length}}
|
|
272
254
|
<div class="app-card overflow-hidden">
|
|
273
255
|
<div class="border-b border-base-200 px-5 py-4">
|
|
@@ -293,8 +275,6 @@
|
|
|
293
275
|
</div>
|
|
294
276
|
</div>
|
|
295
277
|
{{/if}}
|
|
296
|
-
|
|
297
|
-
<!-- Danger zone -->
|
|
298
278
|
{{#unless isInternal}}
|
|
299
279
|
<div class="rounded-2xl border border-error/25 bg-error/[0.03] p-5">
|
|
300
280
|
<h2 class="flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-error">
|