admindb 2.0.0 → 2.1.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 +2 -2
- package/dist/app.d.ts +1 -69
- package/dist/app.js +1 -257
- package/dist/auth/config.d.ts +1 -19
- package/dist/auth/config.js +1 -147
- package/dist/auth/crypto.d.ts +1 -27
- package/dist/auth/crypto.js +1 -133
- package/dist/auth/index.d.ts +1 -5
- package/dist/auth/index.js +1 -22
- package/dist/auth/middleware.d.ts +1 -14
- package/dist/auth/middleware.js +1 -100
- package/dist/auth/routes.d.ts +1 -7
- package/dist/auth/routes.js +1 -78
- package/dist/auth/types.d.ts +1 -35
- package/dist/auth/types.js +1 -11
- package/dist/cli/args.d.ts +1 -45
- package/dist/cli/args.js +1 -328
- package/dist/cli/config.d.ts +1 -56
- package/dist/cli/config.js +1 -133
- package/dist/cli/index.d.ts +1 -4
- package/dist/cli/index.js +1 -21
- package/dist/cli/runner.d.ts +1 -1
- package/dist/cli/runner.js +1 -222
- package/dist/cli.d.ts +1 -2
- package/dist/cli.js +1 -5
- package/dist/data/datasets.d.ts +1 -17
- package/dist/data/datasets.js +1 -133
- package/dist/data/detector.d.ts +1 -30
- package/dist/data/detector.js +1 -472
- package/dist/data/engine.d.ts +1 -10
- package/dist/data/engine.js +1 -211
- package/dist/data/index.d.ts +1 -5
- package/dist/data/index.js +1 -22
- package/dist/data/strategies.d.ts +1 -30
- package/dist/data/strategies.js +1 -343
- package/dist/data/types.d.ts +1 -73
- package/dist/data/types.js +1 -8
- package/dist/db/database.d.ts +1 -119
- package/dist/db/database.js +1 -471
- package/dist/db/export.d.ts +1 -12
- package/dist/db/export.js +1 -42
- package/dist/db/filters.d.ts +1 -22
- package/dist/db/filters.js +1 -158
- package/dist/db/index.d.ts +1 -8
- package/dist/db/index.js +1 -25
- package/dist/db/introspection.d.ts +1 -6
- package/dist/db/introspection.js +1 -172
- package/dist/db/manager.d.ts +1 -81
- package/dist/db/manager.js +1 -397
- package/dist/db/migrations.d.ts +1 -5
- package/dist/db/migrations.js +1 -110
- package/dist/db/postgres.d.ts +1 -85
- package/dist/db/postgres.js +1 -745
- package/dist/db/types.d.ts +1 -206
- package/dist/db/types.js +1 -7
- package/dist/index.d.ts +1 -23
- package/dist/index.js +1 -66
- 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/databases.js +1 -235
- package/dist/public/js/designer.js +1 -243
- package/dist/public/js/forms.js +1 -826
- package/dist/public/js/icons.js +1 -51
- package/dist/public/js/inspector.js +1 -638
- package/dist/public/js/query.js +1 -322
- package/dist/public/js/schema.js +1 -432
- package/dist/public/js/seed.js +1 -1090
- package/dist/routes/api/helpers.d.ts +1 -42
- package/dist/routes/api/helpers.js +1 -133
- package/dist/routes/api/import-export.d.ts +1 -3
- package/dist/routes/api/import-export.js +1 -85
- package/dist/routes/api/index.d.ts +1 -4
- package/dist/routes/api/index.js +1 -37
- package/dist/routes/api/query.d.ts +1 -3
- package/dist/routes/api/query.js +1 -76
- package/dist/routes/api/rows.d.ts +1 -3
- package/dist/routes/api/rows.js +1 -373
- package/dist/routes/api/seed.d.ts +1 -3
- package/dist/routes/api/seed.js +1 -82
- package/dist/routes/api/tables.d.ts +1 -3
- package/dist/routes/api/tables.js +1 -160
- package/dist/routes/databases.d.ts +1 -26
- package/dist/routes/databases.js +1 -230
- package/dist/routes/index.d.ts +1 -3
- package/dist/routes/index.js +1 -20
- package/dist/routes/pages.d.ts +1 -9
- package/dist/routes/pages.js +1 -382
- package/dist/serverless.d.ts +1 -40
- package/dist/serverless.js +1 -210
- package/dist/sql/classifier.d.ts +1 -19
- package/dist/sql/classifier.js +1 -37
- package/dist/sql/generator.d.ts +1 -78
- package/dist/sql/generator.js +1 -308
- package/dist/sql/index.d.ts +1 -2
- package/dist/sql/index.js +1 -19
- package/dist/types/api.d.ts +1 -412
- package/dist/types/api.js +1 -9
- package/dist/utils/colors.d.ts +1 -40
- package/dist/utils/colors.js +1 -64
- package/dist/utils/common.d.ts +1 -50
- package/dist/utils/common.js +1 -229
- package/dist/utils/csv.d.ts +1 -15
- package/dist/utils/csv.js +1 -80
- package/dist/utils/datatype.d.ts +1 -49
- package/dist/utils/datatype.js +1 -222
- package/dist/utils/icons.d.ts +1 -11
- package/dist/utils/icons.js +1 -72
- package/dist/utils/index.d.ts +1 -4
- package/dist/utils/index.js +1 -21
- package/dist/utils/logger.d.ts +1 -10
- package/dist/utils/logger.js +1 -40
- package/dist/views/layouts/main.hbs +8 -5
- package/dist/views/pages/databases.hbs +0 -18
- package/dist/views/pages/designer.hbs +22 -17
- package/dist/views/pages/error.hbs +0 -2
- package/dist/views/pages/form.hbs +0 -5
- package/dist/views/pages/home.hbs +0 -8
- package/dist/views/pages/login.hbs +0 -13
- package/dist/views/pages/query.hbs +0 -9
- package/dist/views/pages/schema.hbs +0 -20
- package/dist/views/pages/seed.hbs +0 -31
- 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 +0 -8
- package/docs/API.md +144 -0
- package/docs/EXAMPLES.md +576 -0
- package/docs/SECURITY.md +265 -0
- package/package.json +7 -2
- 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/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,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">
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
{{!-- Page: Mock & Seed Data Generator · URL: /tables/:table/seed --}}
|
|
2
1
|
<div class="space-y-6">
|
|
3
|
-
|
|
4
|
-
<!-- Header -->
|
|
5
2
|
<div class="flex flex-wrap items-center justify-between gap-4 border-b border-base-200 pb-5">
|
|
6
3
|
<div class="flex items-center gap-3">
|
|
7
4
|
<a href="{{basePath}}/tables/{{table}}" class="btn btn-circle btn-ghost btn-sm" aria-label="Back to table">
|
|
@@ -17,7 +14,6 @@
|
|
|
17
14
|
</div>
|
|
18
15
|
</div>
|
|
19
16
|
<div class="flex flex-wrap items-center gap-2">
|
|
20
|
-
<!-- Presets dropdown -->
|
|
21
17
|
<div class="dropdown dropdown-end">
|
|
22
18
|
<button tabindex="0" type="button" class="btn btn-outline btn-sm gap-1.5">
|
|
23
19
|
{{{icon "seed" class="h-4 w-4"}}}
|
|
@@ -34,12 +30,10 @@
|
|
|
34
30
|
<li><button type="button" id="seed-import-config" class="py-2">📥 Import Plan JSON…</button></li>
|
|
35
31
|
</ul>
|
|
36
32
|
</div>
|
|
37
|
-
|
|
38
33
|
<button id="seed-preview" type="button" class="btn btn-outline btn-sm gap-1.5">
|
|
39
34
|
{{{icon "inspect" class="h-4 w-4 text-primary"}}}
|
|
40
35
|
Preview Data
|
|
41
36
|
</button>
|
|
42
|
-
|
|
43
37
|
{{#unless readonly}}
|
|
44
38
|
<button id="seed-insert" type="button" class="btn btn-primary btn-sm gap-1.5 shadow-sm">
|
|
45
39
|
{{{icon "plus" class="h-4 w-4"}}}
|
|
@@ -53,11 +47,8 @@
|
|
|
53
47
|
{{/unless}}
|
|
54
48
|
</div>
|
|
55
49
|
</div>
|
|
56
|
-
|
|
57
|
-
<!-- Configuration Bar -->
|
|
58
50
|
<div class="app-card p-5 bg-base-100">
|
|
59
51
|
<div class="grid grid-cols-1 gap-5 lg:grid-cols-12 lg:items-end">
|
|
60
|
-
<!-- Row count control -->
|
|
61
52
|
<div class="lg:col-span-4 space-y-1.5">
|
|
62
53
|
<label class="field-label !mb-0 font-medium" for="seed-count">
|
|
63
54
|
<span>Rows to generate</span>
|
|
@@ -72,8 +63,6 @@
|
|
|
72
63
|
</div>
|
|
73
64
|
</div>
|
|
74
65
|
</div>
|
|
75
|
-
|
|
76
|
-
<!-- Column Search Filter -->
|
|
77
66
|
<div class="lg:col-span-4 space-y-1.5">
|
|
78
67
|
<label class="field-label !mb-0 font-medium" for="seed-search">
|
|
79
68
|
<span>Filter columns</span>
|
|
@@ -85,8 +74,6 @@
|
|
|
85
74
|
<input id="seed-search" type="text" placeholder="Search column by name or type..." class="field-input pl-9 text-xs" />
|
|
86
75
|
</div>
|
|
87
76
|
</div>
|
|
88
|
-
|
|
89
|
-
<!-- Seeding options (truncate / clear) -->
|
|
90
77
|
<div class="lg:col-span-4 flex flex-col justify-end space-y-2">
|
|
91
78
|
{{#unless readonly}}
|
|
92
79
|
<label class="cursor-pointer flex items-center gap-2 text-xs font-medium text-base-content/80 hover:text-base-content transition-colors">
|
|
@@ -101,8 +88,6 @@
|
|
|
101
88
|
</div>
|
|
102
89
|
</div>
|
|
103
90
|
</div>
|
|
104
|
-
|
|
105
|
-
<!-- Column strategies section -->
|
|
106
91
|
<div class="space-y-3">
|
|
107
92
|
<div class="flex flex-wrap items-center justify-between gap-2">
|
|
108
93
|
<div class="flex items-center gap-2">
|
|
@@ -124,18 +109,12 @@
|
|
|
124
109
|
</button>
|
|
125
110
|
</div>
|
|
126
111
|
</div>
|
|
127
|
-
|
|
128
|
-
<!-- Cards Grid -->
|
|
129
112
|
<div id="seed-columns" class="grid grid-cols-1 gap-3.5 md:grid-cols-2 2xl:grid-cols-3"></div>
|
|
130
113
|
<div id="seed-empty-search" class="hidden p-8 text-center app-card">
|
|
131
114
|
<p class="text-sm text-base-content/50">No columns match the current search query.</p>
|
|
132
115
|
</div>
|
|
133
116
|
</div>
|
|
134
|
-
|
|
135
|
-
<!-- Feedback / Warnings Alert -->
|
|
136
117
|
<div id="seed-feedback" class="hidden"></div>
|
|
137
|
-
|
|
138
|
-
<!-- Interactive Dual-Mode Preview Section -->
|
|
139
118
|
<div id="seed-preview-card" class="hidden app-card overflow-hidden transition-all duration-200">
|
|
140
119
|
<div class="flex flex-wrap items-center justify-between border-b border-base-200 bg-base-200/40 px-5 py-3 gap-3">
|
|
141
120
|
<div class="flex items-center gap-3">
|
|
@@ -151,7 +130,6 @@
|
|
|
151
130
|
</div>
|
|
152
131
|
<span id="preview-summary-badge" class="badge badge-sm badge-ghost font-mono"></span>
|
|
153
132
|
</div>
|
|
154
|
-
|
|
155
133
|
<div class="flex flex-wrap items-center gap-1.5">
|
|
156
134
|
<button id="seed-export-csv" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary">
|
|
157
135
|
{{{icon "export" class="h-3.5 w-3.5"}}}
|
|
@@ -171,23 +149,17 @@
|
|
|
171
149
|
</button>
|
|
172
150
|
</div>
|
|
173
151
|
</div>
|
|
174
|
-
|
|
175
|
-
<!-- View 1: Interactive Table View -->
|
|
176
152
|
<div id="seed-table-view-container" class="overflow-x-auto max-h-[32rem]">
|
|
177
153
|
<table class="table table-sm table-pin-rows table-zebra w-full text-xs">
|
|
178
154
|
<thead id="seed-preview-thead" class="bg-base-200 font-mono text-[11px] text-base-content/70"></thead>
|
|
179
155
|
<tbody id="seed-preview-tbody"></tbody>
|
|
180
156
|
</table>
|
|
181
157
|
</div>
|
|
182
|
-
|
|
183
|
-
<!-- View 2: SQL View -->
|
|
184
158
|
<div id="seed-sql-view-container" class="hidden p-4">
|
|
185
159
|
<pre class="code-panel max-h-[32rem] overflow-auto"><code id="seed-sql-code"></code></pre>
|
|
186
160
|
</div>
|
|
187
161
|
</div>
|
|
188
162
|
</div>
|
|
189
|
-
|
|
190
|
-
<!-- Config JSON Modal -->
|
|
191
163
|
<dialog id="seed-config-dialog" class="modal">
|
|
192
164
|
<div class="modal-box app-card max-w-lg">
|
|
193
165
|
<h3 id="seed-config-dialog-title" class="text-base font-bold">Seed Plan Configuration</h3>
|
|
@@ -202,8 +174,6 @@
|
|
|
202
174
|
<button>close</button>
|
|
203
175
|
</form>
|
|
204
176
|
</dialog>
|
|
205
|
-
|
|
206
|
-
<!-- Truncate Confirmation Modal -->
|
|
207
177
|
<dialog id="seed-truncate-dialog" class="modal">
|
|
208
178
|
<div class="modal-box app-card max-w-md border border-error/30">
|
|
209
179
|
<div class="flex items-center gap-3 text-error">
|
|
@@ -227,6 +197,5 @@
|
|
|
227
197
|
<button>close</button>
|
|
228
198
|
</form>
|
|
229
199
|
</dialog>
|
|
230
|
-
|
|
231
200
|
<script id="seed-config" type="application/json">{{{json seedConfig}}}</script>
|
|
232
201
|
<script src="{{basePath}}/js/seed.js" defer></script>
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
{{!-- Page: Table Records Browser & Pagination · URL: /tables/:table (or /{basePath}/tables/:table) --}}
|
|
2
1
|
<div class="space-y-5">
|
|
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
|
<span class="grid h-12 w-12 place-items-center rounded-xl bg-primary/10 text-primary">
|
|
@@ -60,8 +57,6 @@
|
|
|
60
57
|
{{/unless}}
|
|
61
58
|
</div>
|
|
62
59
|
</div>
|
|
63
|
-
|
|
64
|
-
<!-- Row filters -->
|
|
65
60
|
<details class="app-card overflow-hidden" {{#if filterQS}}open{{/if}}>
|
|
66
61
|
<summary class="group flex cursor-pointer list-none items-center justify-between gap-2 px-4 py-3 transition hover:bg-base-200/40 [&::-webkit-details-marker]:hidden">
|
|
67
62
|
<span class="flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-base-content/45">
|
|
@@ -88,8 +83,6 @@
|
|
|
88
83
|
</div>
|
|
89
84
|
</form>
|
|
90
85
|
</details>
|
|
91
|
-
|
|
92
|
-
<!-- CSV import -->
|
|
93
86
|
<div id="import-panel" class="app-card hidden p-4">
|
|
94
87
|
<div class="mb-3 flex items-center justify-between">
|
|
95
88
|
<h2 class="text-sm font-semibold uppercase tracking-wide text-base-content/45">Import CSV into <span class="font-mono normal-case">{{table}}</span></h2>
|
|
@@ -107,10 +100,8 @@
|
|
|
107
100
|
<p class="text-xs text-base-content/45">The first row must be column names matching this table. Empty cells are treated as “not set” so database defaults apply. The import is transactional — a failed row rolls back everything.</p>
|
|
108
101
|
</div>
|
|
109
102
|
</div>
|
|
110
|
-
|
|
111
103
|
{{#if rows.length}}
|
|
112
104
|
<div class="app-card overflow-hidden">
|
|
113
|
-
<!-- Toolbar -->
|
|
114
105
|
<div class="flex flex-wrap items-center justify-between gap-2 border-b border-base-200 px-4 py-2.5">
|
|
115
106
|
<div class="flex flex-wrap items-center gap-3">
|
|
116
107
|
<span class="text-sm text-base-content/65">Showing <b class="tabular-nums font-bold text-base-content">{{firstRow}}</b>–<b class="tabular-nums font-bold text-base-content">{{lastRow}}</b> of <b class="tabular-nums font-bold text-base-content">{{count}}</b> rows</span>
|
|
@@ -127,8 +118,6 @@
|
|
|
127
118
|
</label>
|
|
128
119
|
</div>
|
|
129
120
|
</div>
|
|
130
|
-
|
|
131
|
-
<!-- Bulk selection bar -->
|
|
132
121
|
<div id="bulk-bar" class="hidden items-center justify-between gap-2 border-b border-base-200 bg-primary/[0.04] px-4 py-2">
|
|
133
122
|
<span class="text-sm font-medium text-base-content/80">
|
|
134
123
|
<b id="bulk-count" class="tabular-nums text-primary">0</b> row(s) selected
|
|
@@ -149,7 +138,6 @@
|
|
|
149
138
|
<button id="bulk-clear" type="button" class="btn btn-ghost btn-xs text-base-content/60">Clear</button>
|
|
150
139
|
</div>
|
|
151
140
|
</div>
|
|
152
|
-
|
|
153
141
|
<div class="overflow-x-auto">
|
|
154
142
|
<table id="main-table" class="table table-compact table-pin-rows">
|
|
155
143
|
<thead>
|
|
@@ -303,8 +291,6 @@
|
|
|
303
291
|
</tbody>
|
|
304
292
|
</table>
|
|
305
293
|
</div>
|
|
306
|
-
|
|
307
|
-
<!-- Pagination -->
|
|
308
294
|
{{#if (gt pages 1)}}
|
|
309
295
|
<div class="flex flex-wrap items-center justify-between gap-2 border-t border-base-200 px-4 py-3">
|
|
310
296
|
<span class="text-sm text-base-content/50">Page {{page}} of {{pages}}</span>
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
{{!-- Partial: Top Navigation Bar Header --}}
|
|
2
1
|
<div class="sticky top-0 z-30 border-b border-base-300/80 bg-base-100/85 backdrop-blur-md">
|
|
3
|
-
|
|
4
2
|
<div class="navbar mx-auto w-full max-w-[1500px] px-4 sm:px-6 lg:px-8">
|
|
5
3
|
<div class="flex-none lg:hidden">
|
|
6
4
|
<label for="sidebar-toggle" class="btn btn-square btn-ghost" aria-label="open sidebar">
|
|
@@ -25,7 +23,6 @@
|
|
|
25
23
|
{{/if}}
|
|
26
24
|
{{/unless}}
|
|
27
25
|
</div>
|
|
28
|
-
|
|
29
26
|
<div class="flex items-center gap-1.5">
|
|
30
27
|
{{#unless noSidebar}}
|
|
31
28
|
{{#unless databasesMode}}
|
|
@@ -51,7 +48,6 @@
|
|
|
51
48
|
</a>
|
|
52
49
|
{{/unless}}
|
|
53
50
|
{{/unless}}
|
|
54
|
-
|
|
55
51
|
{{#if authEnabled}}
|
|
56
52
|
{{#if authUser}}
|
|
57
53
|
{{#if isDefaultPassword}}
|
|
@@ -79,11 +75,9 @@
|
|
|
79
75
|
</div>
|
|
80
76
|
{{/if}}
|
|
81
77
|
{{/if}}
|
|
82
|
-
|
|
83
78
|
<button id="theme-toggle" type="button" class="btn btn-square btn-ghost btn-sm" aria-label="Toggle dark mode" title="Toggle dark mode">
|
|
84
79
|
{{{icon "moon" class="h-5 w-5"}}}
|
|
85
80
|
</button>
|
|
86
|
-
|
|
87
81
|
</div>
|
|
88
82
|
</div>
|
|
89
83
|
</div>
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
{{!-- Partial: Left Navigation Sidebar --}}
|
|
2
1
|
<aside class="flex h-full min-h-full w-72 flex-col bg-neutral text-neutral-content">
|
|
3
|
-
|
|
4
2
|
<div class="flex items-center gap-2.5 px-5 pb-4 pt-5">
|
|
5
3
|
<div class="w-full">
|
|
6
4
|
<div class="flex items-center justify-between">
|
|
@@ -16,7 +14,6 @@
|
|
|
16
14
|
<div class="mt-0.5 text-[11px] text-neutral-content/50 truncate">{{#if databasesMode}}Database manager{{else}}{{dbId}}{{/if}}</div>
|
|
17
15
|
</div>
|
|
18
16
|
</div>
|
|
19
|
-
|
|
20
17
|
{{#if databasesMode}}
|
|
21
18
|
<nav class="flex-1 overflow-y-auto px-3 py-2">
|
|
22
19
|
<ul class="space-y-0.5">
|
|
@@ -38,7 +35,6 @@
|
|
|
38
35
|
class="w-full rounded-lg border border-white/10 bg-white/[0.06] py-2 pl-9 pr-3 text-sm text-neutral-content outline-none transition placeholder:text-neutral-content/40 focus:border-primary/70 focus:ring-4 focus:ring-primary/20" />
|
|
39
36
|
</label>
|
|
40
37
|
</div>
|
|
41
|
-
|
|
42
38
|
<nav class="flex-1 overflow-y-auto px-3 py-2">
|
|
43
39
|
<ul class="space-y-0.5">
|
|
44
40
|
{{#if databasesUrl}}
|
|
@@ -70,12 +66,10 @@
|
|
|
70
66
|
</li>
|
|
71
67
|
{{/unless}}
|
|
72
68
|
</ul>
|
|
73
|
-
|
|
74
69
|
<div class="mb-2 mt-6 flex items-center justify-between px-3">
|
|
75
70
|
<span class="text-[11px] font-semibold uppercase tracking-wider text-neutral-content/40">Tables</span>
|
|
76
71
|
<span id="table-count" class="rounded-md bg-white/[0.06] px-1.5 py-0.5 text-[10px] font-semibold text-neutral-content/50">{{tables.length}}</span>
|
|
77
72
|
</div>
|
|
78
|
-
|
|
79
73
|
<ul id="table-list" class="space-y-0.5">
|
|
80
74
|
{{#each tables}}
|
|
81
75
|
<li class="table-item" data-name="{{this}}">
|
|
@@ -90,7 +84,6 @@
|
|
|
90
84
|
<li class="px-3 py-2 text-xs text-neutral-content/40">No tables yet</li>
|
|
91
85
|
{{/each}}
|
|
92
86
|
</ul>
|
|
93
|
-
|
|
94
87
|
{{#if internalTables.length}}
|
|
95
88
|
<div class="mb-2 mt-6 px-3 text-[11px] font-semibold uppercase tracking-wider text-neutral-content/40">Internal</div>
|
|
96
89
|
<ul class="space-y-0.5">
|
|
@@ -108,7 +101,6 @@
|
|
|
108
101
|
{{/if}}
|
|
109
102
|
</nav>
|
|
110
103
|
{{/if}}
|
|
111
|
-
|
|
112
104
|
<div class="border-t border-white/10 px-5 py-3">
|
|
113
105
|
<div class="flex items-center justify-between">
|
|
114
106
|
<div class="text-[11px] font-medium uppercase tracking-wider text-neutral-content/40">{{#if databasesMode}}Directory{{else}}Engine: {{dialectName}}{{/if}}</div>
|
package/docs/API.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# AdminDB REST API
|
|
2
|
+
|
|
3
|
+
Every route is under `basePath` and returns the consistent shape
|
|
4
|
+
`{ success, data?, error? }`. In multi-db mode, every route is scoped under the
|
|
5
|
+
database identifier, e.g. `/api/app.db/tables` or `/api/prod_pg/tables`.
|
|
6
|
+
|
|
7
|
+
AdminDB supports both **SQLite** and **PostgreSQL** database backends seamlessly.
|
|
8
|
+
|
|
9
|
+
## Tables & rows
|
|
10
|
+
|
|
11
|
+
| Method | Path | Purpose |
|
|
12
|
+
| ------ | ---------------------------------------- | -------------------------------- |
|
|
13
|
+
| GET | `/api/tables` | List tables |
|
|
14
|
+
| GET | `/api/tables/:table/info` | Column + FK metadata, PK columns |
|
|
15
|
+
| GET | `/api/tables/:table/fk-options` | Values for FK dropdowns |
|
|
16
|
+
| GET | `/api/tables/:table/rows?page&limit&f` | Paginated rows (`f` = URL-encoded JSON filters — legacy strings like `{"age":">35"}` or structured conditions like `{"balance":{"op":"gte","value":"100"}}`) |
|
|
17
|
+
| GET | `/api/tables/:table/rows/count?f=` | Filtered row count |
|
|
18
|
+
| GET | `/api/tables/:table/row/:id` | Single row by (encoded) PK |
|
|
19
|
+
| GET | `/api/tables/:table/rows/:id/references` | Rows in other tables whose foreign keys reference this row |
|
|
20
|
+
| GET | `/api/tables/:table/row/:id/blob/:column` | Stream binary BLOB / BYTEA with MIME detection (add `?download=1` to force download) |
|
|
21
|
+
| GET | `/api/tables/:table/row/:id/blob/:column/meta` | Inspect BLOB / BYTEA metadata, MIME sniffing & 3-column hex dump |
|
|
22
|
+
| PUT | `/api/tables/:table/row/:id/blob/:column` | Update binary value (`{ data: base64/hex, format?: 'base64'|'hex'|'text' }`) |
|
|
23
|
+
| POST | `/api/tables/:table/rows` | Insert row (or batch of rows with `{ rows: [...] }`) |
|
|
24
|
+
| POST | `/api/tables/:table/rows/generate` | Generate INSERT SQL (no execute) |
|
|
25
|
+
| POST | `/api/tables/:table/rows/import` | Import CSV (`{ csv }`, header row must match columns) |
|
|
26
|
+
| GET | `/api/tables/:table/export?format=` | Download all rows as `csv` or `json` |
|
|
27
|
+
| PUT | `/api/tables/:table/row/:id` | Update row (`{ values, nulls? }` — `nulls` explicitly sets columns to NULL) |
|
|
28
|
+
| PUT | `/api/tables/:table/row/:id/generate` | Generate UPDATE SQL (no execute) |
|
|
29
|
+
| DELETE | `/api/tables/:table/row/:id` | Delete row |
|
|
30
|
+
| POST | `/api/tables/:table/rows/bulk-impact` | FK-impact preview: how many rows in other tables reference the selected rows |
|
|
31
|
+
| POST | `/api/tables/:table/rows/bulk-delete` | Delete selected rows (`{ ids, confirmImpact }`; transactional) |
|
|
32
|
+
| POST | `/api/tables/:table/rows/bulk-export` | Export only the selected rows as `csv`/`json` (`{ ids, format }`) |
|
|
33
|
+
| POST | `/api/tables/:table/rows/bulk-update` | Apply staged inline edits (`{ updates: [{ id, values?, nulls? }] }`; transactional) |
|
|
34
|
+
| GET | `/api/tables/:table/seed/config` | Per-column generator strategies + detected defaults |
|
|
35
|
+
| GET | `/api/tables/:table/seed/plan` | Detect intelligent seed plan heuristics |
|
|
36
|
+
| POST | `/api/tables/:table/seed/preview` | Generate preview sample rows for grid without executing |
|
|
37
|
+
| POST | `/api/tables/:table/seed/generate` | Generate seed INSERT SQL without executing (`{ count, plan }`) |
|
|
38
|
+
| POST | `/api/tables/:table/seed` | Generate and insert seed rows transactionally (`{ count, plan, truncate? }`) |
|
|
39
|
+
|
|
40
|
+
## Schema & indexes
|
|
41
|
+
|
|
42
|
+
| Method | Path | Purpose |
|
|
43
|
+
| ------ | ------------------------------------ | -------------------------------- |
|
|
44
|
+
| POST | `/api/tables` | Create table |
|
|
45
|
+
| POST | `/api/tables/generate` | Generate CREATE SQL (no execute) |
|
|
46
|
+
| GET | `/api/tables/:table/schema` | Full schema (constraints, indexes, FK refs) |
|
|
47
|
+
| GET | `/api/tables/:table/ddl` | Get formatted `CREATE TABLE` and `INDEX` DDL |
|
|
48
|
+
|
|
49
|
+
| POST | `/api/tables/:table/rename` | Rename the table |
|
|
50
|
+
| POST | `/api/tables/:table/columns` | Add a column |
|
|
51
|
+
| PUT | `/api/tables/:table/columns/:column` | Modify/rename a column |
|
|
52
|
+
| DELETE | `/api/tables/:table/columns/:column` | Drop a column (safety-checked) |
|
|
53
|
+
| DELETE | `/api/tables/:table` | Drop the table (safety-checked) |
|
|
54
|
+
| POST | `/api/tables/:table/indexes` | Create an index (`{ name?, columns[], unique? }`) |
|
|
55
|
+
| DELETE | `/api/tables/:table/indexes/:index` | Drop an index (auto indexes refused) |
|
|
56
|
+
|
|
57
|
+
## Queries
|
|
58
|
+
|
|
59
|
+
| Method | Path | Purpose |
|
|
60
|
+
| ------ | ----------------- | -------------------------- |
|
|
61
|
+
| POST | `/api/query` | Run arbitrary SQL |
|
|
62
|
+
| POST | `/api/query/export` | Run a SELECT and download as `csv`/`json` |
|
|
63
|
+
| GET | `/api/queries` | List saved queries |
|
|
64
|
+
| POST | `/api/queries` | Save a named query |
|
|
65
|
+
| DELETE | `/api/queries/:id`| Delete a saved query |
|
|
66
|
+
|
|
67
|
+
## Manager mode (databases landing page)
|
|
68
|
+
|
|
69
|
+
These endpoints manage database files and power the filesystem browser:
|
|
70
|
+
|
|
71
|
+
| Method | Path | Purpose |
|
|
72
|
+
| ------ | ------------------------------- | ------------------------------------------- |
|
|
73
|
+
| GET | `/api/databases` | List managed databases |
|
|
74
|
+
| POST | `/api/databases` | Create a new SQLite database (`{ name }`) |
|
|
75
|
+
| POST | `/api/databases/connect-postgres` | Connect a PostgreSQL database (`{ name?, connectionString, readonly? }`) |
|
|
76
|
+
| POST | `/api/databases/:id/mode` | Toggle/set database mode (`{ readonly: boolean }`) |
|
|
77
|
+
| DELETE | `/api/databases/:id` | Delete SQLite database file or disconnect PostgreSQL connection |
|
|
78
|
+
| GET | `/api/fs/list?path=` | List subfolders + SQLite files under a path (sandboxed file browser) |
|
|
79
|
+
| POST | `/api/databases/open` | Open/register an existing database file by path (`{ path, readonly? }`) |
|
|
80
|
+
|
|
81
|
+
## Authentication & Sessions
|
|
82
|
+
|
|
83
|
+
| Method | Path | Purpose |
|
|
84
|
+
| ------ | --------------------- | ------------------------------------------- |
|
|
85
|
+
| GET | `/login` | Web UI login page |
|
|
86
|
+
| POST | `/login` | Authenticate with `{ username, password }` and get session token |
|
|
87
|
+
| POST | `/logout` | Terminate session and clear cookie |
|
|
88
|
+
| GET | `/logout` | Terminate session and redirect to `/login` |
|
|
89
|
+
|
|
90
|
+
All API endpoints accept:
|
|
91
|
+
- **HTTP Basic Auth**: `Authorization: Basic <base64(username:password)>`
|
|
92
|
+
- **Bearer Token**: `Authorization: Bearer <sessionToken>`
|
|
93
|
+
- **Session Cookie**: `admindb_session=<sessionToken>`
|
|
94
|
+
|
|
95
|
+
### Generating Password Hashes
|
|
96
|
+
Generate salted `scrypt` password hashes for custom credentials:
|
|
97
|
+
```bash
|
|
98
|
+
npm run generatehash
|
|
99
|
+
# Enter password -> outputs scrypt:<salt>:<hash>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Paste the generated hash into `ADMINDB_PASSWORD`, CLI `-P`, or `auth.password` option.
|
|
103
|
+
|
|
104
|
+
### Disabling Native Authentication & Custom Application Auth
|
|
105
|
+
Pass `auth: false`, CLI `--no-auth`, or `ADMINDB_AUTH=false` to turn off built-in authentication when integrating your own security layer.
|
|
106
|
+
|
|
107
|
+
> [!WARNING]
|
|
108
|
+
> **Security & Responsibility Notice**:
|
|
109
|
+
> AdminDB's built-in authentication is designed for basic access control during local development. For production environments and internet-facing networks, **it is entirely the user's responsibility to protect AdminDB** by placing it behind your own application authentication (e.g. NextAuth, Passport, JWT, SSO/OAuth middleware), a VPN, an IP-allowlist reverse proxy (Nginx, Cloudflare Access), or HTTPS with rate limiting.
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
## TypeScript API Types & Helpers
|
|
113
|
+
|
|
114
|
+
All request and response types, data inspection helpers, and serverless handlers are exported by the package entry point:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import {
|
|
118
|
+
createRouter,
|
|
119
|
+
createServerlessHandler,
|
|
120
|
+
createLambdaHandler,
|
|
121
|
+
sniffMimeType,
|
|
122
|
+
generateHexDump,
|
|
123
|
+
analyzeBlob,
|
|
124
|
+
isJsonString,
|
|
125
|
+
formatJsonSafely,
|
|
126
|
+
type ApiResponse,
|
|
127
|
+
type GetRowsResponseData,
|
|
128
|
+
type BlobMetaResponseData,
|
|
129
|
+
type TableDdlResponseData,
|
|
130
|
+
} from 'admindb';
|
|
131
|
+
|
|
132
|
+
// 1. Sniff MIME type from binary magic bytes
|
|
133
|
+
const analysis = sniffMimeType(imageBuffer);
|
|
134
|
+
console.log(analysis.mime, analysis.ext, analysis.isImage);
|
|
135
|
+
|
|
136
|
+
// 2. Generate a 3-column hex dump
|
|
137
|
+
const dump = generateHexDump(binaryBuffer, 1024);
|
|
138
|
+
dump.lines.forEach((l) => console.log(`${l.offset} ${l.hex} |${l.ascii}|`));
|
|
139
|
+
|
|
140
|
+
// 3. Serverless request handler (Vercel, AWS Lambda, Cloudflare, etc.)
|
|
141
|
+
export default createServerlessHandler({ dbPath: './app.db' });
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
|