admindb 1.2.0 → 2.0.0
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 +250 -352
- package/dist/app.d.ts +25 -4
- package/dist/app.js +79 -15
- package/dist/app.js.map +1 -1
- package/dist/auth/config.d.ts +19 -0
- package/dist/auth/config.js +147 -0
- package/dist/auth/config.js.map +1 -0
- package/dist/auth/crypto.d.ts +27 -0
- package/dist/auth/crypto.js +133 -0
- package/dist/auth/crypto.js.map +1 -0
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.js +22 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/middleware.d.ts +14 -0
- package/dist/auth/middleware.js +100 -0
- package/dist/auth/middleware.js.map +1 -0
- package/dist/auth/routes.d.ts +7 -0
- package/dist/auth/routes.js +78 -0
- package/dist/auth/routes.js.map +1 -0
- package/dist/auth/types.d.ts +35 -0
- package/dist/auth/types.js +11 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/cli/args.d.ts +45 -0
- package/dist/cli/args.js +328 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/config.d.ts +56 -0
- package/dist/cli/config.js +133 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.js +21 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/runner.d.ts +1 -0
- package/dist/cli/runner.js +222 -0
- package/dist/cli/runner.js.map +1 -0
- package/dist/cli.js +2 -127
- package/dist/cli.js.map +1 -1
- package/dist/data/datasets.d.ts +17 -0
- package/dist/data/datasets.js +133 -0
- package/dist/data/datasets.js.map +1 -0
- package/dist/data/detector.d.ts +30 -0
- package/dist/data/detector.js +472 -0
- package/dist/data/detector.js.map +1 -0
- package/dist/data/engine.d.ts +10 -0
- package/dist/data/engine.js +211 -0
- package/dist/data/engine.js.map +1 -0
- package/dist/data/index.d.ts +5 -0
- package/dist/data/index.js +22 -0
- package/dist/data/index.js.map +1 -0
- package/dist/data/strategies.d.ts +30 -0
- package/dist/data/strategies.js +343 -0
- package/dist/data/strategies.js.map +1 -0
- package/dist/data/types.d.ts +73 -0
- package/dist/data/types.js +8 -0
- package/dist/data/types.js.map +1 -0
- package/dist/db/database.d.ts +14 -142
- package/dist/db/database.js +209 -435
- package/dist/db/database.js.map +1 -1
- package/dist/db/export.d.ts +2 -2
- package/dist/db/export.js +7 -2
- package/dist/db/export.js.map +1 -1
- package/dist/db/filters.d.ts +22 -0
- package/dist/db/filters.js +158 -0
- package/dist/db/filters.js.map +1 -0
- package/dist/db/index.d.ts +8 -0
- package/dist/db/index.js +25 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/introspection.d.ts +6 -0
- package/dist/db/introspection.js +172 -0
- package/dist/db/introspection.js.map +1 -0
- package/dist/db/manager.d.ts +32 -19
- package/dist/db/manager.js +203 -44
- package/dist/db/manager.js.map +1 -1
- package/dist/db/migrations.d.ts +5 -0
- package/dist/db/migrations.js +110 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/postgres.d.ts +85 -0
- package/dist/db/postgres.js +745 -0
- package/dist/db/postgres.js.map +1 -0
- package/dist/db/types.d.ts +206 -0
- package/dist/db/types.js +7 -0
- package/dist/db/types.js.map +1 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.js +46 -4
- package/dist/index.js.map +1 -1
- package/dist/public/css/app.css +1 -1
- package/dist/public/css/input.css +83 -13
- package/dist/public/js/app.js +142 -0
- package/dist/public/js/browse.js +591 -104
- package/dist/public/js/databases.js +105 -13
- package/dist/public/js/designer.js +40 -2
- package/dist/public/js/forms.js +610 -28
- package/dist/public/js/icons.js +51 -0
- package/dist/public/js/inspector.js +638 -0
- package/dist/public/js/query.js +93 -3
- package/dist/public/js/schema.js +170 -52
- package/dist/public/js/seed.js +1090 -0
- package/dist/routes/api/helpers.d.ts +42 -0
- package/dist/routes/api/helpers.js +133 -0
- package/dist/routes/api/helpers.js.map +1 -0
- package/dist/routes/api/import-export.d.ts +3 -0
- package/dist/routes/api/import-export.js +85 -0
- package/dist/routes/api/import-export.js.map +1 -0
- package/dist/routes/api/index.d.ts +4 -0
- package/dist/routes/api/index.js +37 -0
- package/dist/routes/api/index.js.map +1 -0
- package/dist/routes/api/query.d.ts +3 -0
- package/dist/routes/api/query.js +76 -0
- package/dist/routes/api/query.js.map +1 -0
- package/dist/routes/api/rows.d.ts +3 -0
- package/dist/routes/api/rows.js +373 -0
- package/dist/routes/api/rows.js.map +1 -0
- package/dist/routes/api/seed.d.ts +3 -0
- package/dist/routes/api/seed.js +82 -0
- package/dist/routes/api/seed.js.map +1 -0
- package/dist/routes/api/tables.d.ts +3 -0
- package/dist/routes/api/tables.js +160 -0
- package/dist/routes/api/tables.js.map +1 -0
- package/dist/routes/databases.d.ts +8 -11
- package/dist/routes/databases.js +100 -66
- package/dist/routes/databases.js.map +1 -1
- package/dist/routes/index.d.ts +3 -0
- package/dist/routes/index.js +20 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/pages.d.ts +3 -3
- package/dist/routes/pages.js +163 -54
- package/dist/routes/pages.js.map +1 -1
- package/dist/serverless.d.ts +40 -0
- package/dist/serverless.js +210 -0
- package/dist/serverless.js.map +1 -0
- package/dist/sql/generator.d.ts +4 -3
- package/dist/sql/generator.js +103 -6
- package/dist/sql/generator.js.map +1 -1
- package/dist/sql/index.d.ts +2 -0
- package/dist/sql/index.js +19 -0
- package/dist/sql/index.js.map +1 -0
- package/dist/types/api.d.ts +412 -0
- package/dist/types/api.js +9 -0
- package/dist/types/api.js.map +1 -0
- package/dist/utils/colors.d.ts +40 -0
- package/dist/utils/colors.js +64 -0
- package/dist/utils/colors.js.map +1 -0
- package/dist/{util.d.ts → utils/common.d.ts} +10 -6
- package/dist/{util.js → utils/common.js} +80 -13
- package/dist/utils/common.js.map +1 -0
- package/dist/utils/csv.js.map +1 -0
- package/dist/utils/datatype.d.ts +49 -0
- package/dist/utils/datatype.js +222 -0
- package/dist/utils/datatype.js.map +1 -0
- package/dist/utils/icons.d.ts +11 -0
- package/dist/utils/icons.js +72 -0
- package/dist/utils/icons.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +21 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/{logger.d.ts → utils/logger.d.ts} +1 -1
- package/dist/utils/logger.js +40 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/views/layouts/main.hbs +33 -11
- package/dist/views/pages/databases.hbs +182 -74
- package/dist/views/pages/designer.hbs +9 -6
- package/dist/views/pages/error.hbs +3 -3
- package/dist/views/pages/form.hbs +5 -3
- package/dist/views/pages/home.hbs +22 -13
- package/dist/views/pages/login.hbs +111 -0
- package/dist/views/pages/query.hbs +10 -8
- package/dist/views/pages/schema.hbs +41 -13
- package/dist/views/pages/seed.hbs +232 -0
- package/dist/views/pages/table.hbs +155 -70
- package/dist/views/partials/icon.hbs +2 -0
- package/dist/views/partials/navbar.hbs +70 -31
- package/dist/views/partials/sidebar.hbs +108 -99
- package/package.json +12 -5
- package/dist/args.d.ts +0 -28
- package/dist/args.js +0 -187
- package/dist/args.js.map +0 -1
- package/dist/config.d.ts +0 -17
- package/dist/config.js +0 -23
- package/dist/config.js.map +0 -1
- package/dist/csv.js.map +0 -1
- package/dist/logger.js +0 -25
- package/dist/logger.js.map +0 -1
- package/dist/routes/api.d.ts +0 -9
- package/dist/routes/api.js +0 -786
- package/dist/routes/api.js.map +0 -1
- package/dist/test/classifier.test.d.ts +0 -1
- package/dist/test/classifier.test.js +0 -44
- package/dist/test/classifier.test.js.map +0 -1
- package/dist/test/csv.test.d.ts +0 -1
- package/dist/test/csv.test.js +0 -64
- package/dist/test/csv.test.js.map +0 -1
- package/dist/test/database.test.d.ts +0 -1
- package/dist/test/database.test.js +0 -402
- package/dist/test/database.test.js.map +0 -1
- package/dist/test/generator.test.d.ts +0 -1
- package/dist/test/generator.test.js +0 -132
- package/dist/test/generator.test.js.map +0 -1
- package/dist/test/manager.test.d.ts +0 -1
- package/dist/test/manager.test.js +0 -146
- package/dist/test/manager.test.js.map +0 -1
- package/dist/util.js.map +0 -1
- /package/dist/{csv.d.ts → utils/csv.d.ts} +0 -0
- /package/dist/{csv.js → utils/csv.js} +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SVG Icons registry for AdminDB.
|
|
4
|
+
*
|
|
5
|
+
* Centralizes all SVG icons in a single module, providing consistent
|
|
6
|
+
* styling, clean templates, and zero inline SVG duplication.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ICONS = void 0;
|
|
10
|
+
exports.renderIcon = renderIcon;
|
|
11
|
+
exports.ICONS = {
|
|
12
|
+
// Navigation & Core
|
|
13
|
+
menu: '<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16" /></svg>',
|
|
14
|
+
home: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" /></svg>',
|
|
15
|
+
database: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 7v10c0 1.1.9 2 2 2h12a2 2 0 002-2V7M4 7c0-1.1.9-2 2-2h12a2 2 0 012 2M4 7c0 1.1.9 2 2 2h12a2 2 0 002-2" /></svg>',
|
|
16
|
+
table: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 10h18M3 14h18m-9-4v8m-7 0h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z" /></svg>',
|
|
17
|
+
query: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 10V3L4 14h7v7l9-11h-7z" /></svg>',
|
|
18
|
+
designer: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4" /></svg>',
|
|
19
|
+
plus: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4" /></svg>',
|
|
20
|
+
book: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" /></svg>',
|
|
21
|
+
schema: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" /><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" /></svg>',
|
|
22
|
+
// Actions
|
|
23
|
+
search: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /></svg>',
|
|
24
|
+
filter: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414A1 1 0 0014 15.414V20a1 1 0 01-1 1h-2a1 1 0 01-1-1v-4.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z" /></svg>',
|
|
25
|
+
export: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" /></svg>',
|
|
26
|
+
import: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" /></svg>',
|
|
27
|
+
seed: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z" /></svg>',
|
|
28
|
+
edit: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" /></svg>',
|
|
29
|
+
trash: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" /></svg>',
|
|
30
|
+
copy: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" /></svg>',
|
|
31
|
+
duplicate: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2" /></svg>',
|
|
32
|
+
save: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4" /></svg>',
|
|
33
|
+
run: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" /><path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>',
|
|
34
|
+
inspect: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/><path stroke-linecap="round" stroke-linejoin="round" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/></svg>',
|
|
35
|
+
sql: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" /></svg>',
|
|
36
|
+
// Arrows & Direction
|
|
37
|
+
chevronDown: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7" /></svg>',
|
|
38
|
+
chevronUp: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 15l7-7 7 7" /></svg>',
|
|
39
|
+
chevronLeft: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7" /></svg>',
|
|
40
|
+
chevronRight: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7" /></svg>',
|
|
41
|
+
arrowLeft: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M10 19l-7-7m0 0l7-7m-7 7h18" /></svg>',
|
|
42
|
+
arrowRight: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6" /></svg>',
|
|
43
|
+
arrowUp: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 10h13M3 10l4-4m-4 4l4 4" /></svg>',
|
|
44
|
+
// Indicators & Status
|
|
45
|
+
check: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" /></svg>',
|
|
46
|
+
x: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>',
|
|
47
|
+
warning: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /></svg>',
|
|
48
|
+
stats: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>',
|
|
49
|
+
key: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" /></svg>',
|
|
50
|
+
dotsHorizontal: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 12h.01M12 12h.01M19 12h.01M6 12a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0z" /></svg>',
|
|
51
|
+
dotsVertical: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z" /></svg>',
|
|
52
|
+
// Auth & Account
|
|
53
|
+
user: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /></svg>',
|
|
54
|
+
logout: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" /></svg>',
|
|
55
|
+
lock: '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" /></svg>',
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Renders an SVG icon by name with optional custom CSS classes.
|
|
59
|
+
*/
|
|
60
|
+
function renderIcon(name, customClass) {
|
|
61
|
+
const svg = exports.ICONS[name];
|
|
62
|
+
if (!svg)
|
|
63
|
+
return '';
|
|
64
|
+
if (!customClass)
|
|
65
|
+
return svg;
|
|
66
|
+
// Replace existing class attribute or inject new one
|
|
67
|
+
if (svg.includes('class="')) {
|
|
68
|
+
return svg.replace(/class="[^"]*"/, `class="${customClass}"`);
|
|
69
|
+
}
|
|
70
|
+
return svg.replace('<svg', `<svg class="${customClass}"`);
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=icons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icons.js","sourceRoot":"","sources":["../../src/utils/icons.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAwDH,gCAUC;AAhEY,QAAA,KAAK,GAA2B;IAC3C,oBAAoB;IACpB,IAAI,EAAE,0NAA0N;IAChO,IAAI,EAAE,mVAAmV;IACzV,QAAQ,EAAE,2SAA2S;IACrT,KAAK,EAAE,2RAA2R;IAClS,KAAK,EAAE,6NAA6N;IACpO,QAAQ,EAAE,iNAAiN;IAC3N,IAAI,EAAE,iNAAiN;IACvN,IAAI,EAAE,qbAAqb;IAC3b,MAAM,EAAE,kwBAAkwB;IAE1wB,UAAU;IACV,MAAM,EAAE,8OAA8O;IACtP,MAAM,EAAE,kXAAkX;IAC1X,MAAM,EAAE,iQAAiQ;IACzQ,MAAM,EAAE,iQAAiQ;IACzQ,IAAI,EAAE,2SAA2S;IACjT,IAAI,EAAE,yTAAyT;IAC/T,KAAK,EAAE,+TAA+T;IACtU,IAAI,EAAE,wTAAwT;IAC9T,SAAS,EAAE,mWAAmW;IAC9W,IAAI,EAAE,8RAA8R;IACpS,GAAG,EAAE,iYAAiY;IACtY,OAAO,EAAE,oZAAoZ;IAC7Z,GAAG,EAAE,kUAAkU;IAEvU,qBAAqB;IACrB,WAAW,EAAE,iNAAiN;IAC9N,SAAS,EAAE,gNAAgN;IAC3N,WAAW,EAAE,kNAAkN;IAC/N,YAAY,EAAE,+MAA+M;IAC7N,SAAS,EAAE,8NAA8N;IACzO,UAAU,EAAE,2NAA2N;IACvO,OAAO,EAAE,6NAA6N;IAEtO,sBAAsB;IACtB,KAAK,EAAE,iNAAiN;IACxN,CAAC,EAAE,uNAAuN;IAC1N,OAAO,EAAE,uUAAuU;IAChV,KAAK,EAAE,gUAAgU;IACvU,GAAG,EAAE,6TAA6T;IAClU,cAAc,EAAE,2TAA2T;IAC3U,YAAY,EAAE,wTAAwT;IAEtU,iBAAiB;IACjB,IAAI,EAAE,sQAAsQ;IAC5Q,MAAM,EAAE,4RAA4R;IACpS,IAAI,EAAE,uSAAuS;CAC9S,CAAC;AAEF;;GAEG;AACH,SAAgB,UAAU,CAAC,IAAY,EAAE,WAAoB;IAC3D,MAAM,GAAG,GAAG,aAAK,CAAC,IAAI,CAAC,CAAC;IACxB,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,IAAI,CAAC,WAAW;QAAE,OAAO,GAAG,CAAC;IAE7B,qDAAqD;IACrD,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5B,OAAO,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,UAAU,WAAW,GAAG,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,eAAe,WAAW,GAAG,CAAC,CAAC;AAC5D,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./common"), exports);
|
|
18
|
+
__exportStar(require("./csv"), exports);
|
|
19
|
+
__exportStar(require("./logger"), exports);
|
|
20
|
+
__exportStar(require("./colors"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,wCAAsB;AACtB,2CAAyB;AACzB,2CAAyB"}
|
|
@@ -6,5 +6,5 @@ export interface Logger {
|
|
|
6
6
|
error(...args: unknown[]): void;
|
|
7
7
|
child(scope: string): Logger;
|
|
8
8
|
}
|
|
9
|
-
/** Minimal console logger with level filtering and scoped children. */
|
|
9
|
+
/** Minimal, color-enhanced console logger with level filtering and scoped children. */
|
|
10
10
|
export declare function createLogger(level?: LogLevel, scope?: string): Logger;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createLogger = createLogger;
|
|
4
|
+
const colors_1 = require("./colors");
|
|
5
|
+
const LEVELS = { debug: 10, info: 20, warn: 30, error: 40 };
|
|
6
|
+
function formatTime() {
|
|
7
|
+
const d = new Date();
|
|
8
|
+
const pad = (n) => String(n).padStart(2, '0');
|
|
9
|
+
return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
|
10
|
+
}
|
|
11
|
+
const BADGES = {
|
|
12
|
+
debug: colors_1.c.magenta('[debug]'),
|
|
13
|
+
info: colors_1.c.cyan('[info]'),
|
|
14
|
+
warn: colors_1.c.yellow('[warn]'),
|
|
15
|
+
error: colors_1.c.red(colors_1.c.bold('[error]')),
|
|
16
|
+
};
|
|
17
|
+
/** Minimal, color-enhanced console logger with level filtering and scoped children. */
|
|
18
|
+
function createLogger(level = 'info', scope = 'admindb') {
|
|
19
|
+
const threshold = LEVELS[level] ?? LEVELS.info;
|
|
20
|
+
// Clean scope name (e.g. "admindb:db:users.db" -> "db:users.db")
|
|
21
|
+
const cleanScope = scope === 'admindb' || scope === 'app' ? '' : scope.replace(/^admindb:/, '');
|
|
22
|
+
const scopeTag = cleanScope ? colors_1.c.dim(colors_1.c.cyan(`[${cleanScope}]`)) : '';
|
|
23
|
+
const write = (lv, args) => {
|
|
24
|
+
if (LEVELS[lv] < threshold)
|
|
25
|
+
return;
|
|
26
|
+
const time = colors_1.c.gray(formatTime());
|
|
27
|
+
const badge = BADGES[lv];
|
|
28
|
+
const prefix = [time, badge, scopeTag].filter(Boolean).join(' ');
|
|
29
|
+
// eslint-disable-next-line no-console
|
|
30
|
+
console.log(prefix, ...args);
|
|
31
|
+
};
|
|
32
|
+
return {
|
|
33
|
+
debug: (...args) => write('debug', args),
|
|
34
|
+
info: (...args) => write('info', args),
|
|
35
|
+
warn: (...args) => write('warn', args),
|
|
36
|
+
error: (...args) => write('error', args),
|
|
37
|
+
child: (s) => createLogger(level, cleanScope ? `${cleanScope}:${s}` : s),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";;AA4BA,oCAuBC;AAnDD,qCAA6B;AAY7B,MAAM,MAAM,GAA6B,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAEtF,SAAS,UAAU;IACjB,MAAM,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;IACrB,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACtD,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC;AAC9E,CAAC;AAED,MAAM,MAAM,GAA6B;IACvC,KAAK,EAAE,UAAC,CAAC,OAAO,CAAC,SAAS,CAAC;IAC3B,IAAI,EAAE,UAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;IACtB,IAAI,EAAE,UAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;IACxB,KAAK,EAAE,UAAC,CAAC,GAAG,CAAC,UAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;CAChC,CAAC;AAEF,uFAAuF;AACvF,SAAgB,YAAY,CAAC,QAAkB,MAAM,EAAE,KAAK,GAAG,SAAS;IACtE,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC;IAE/C,iEAAiE;IACjE,MAAM,UAAU,GAAG,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAChG,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,UAAC,CAAC,GAAG,CAAC,UAAC,CAAC,IAAI,CAAC,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEpE,MAAM,KAAK,GAAG,CAAC,EAAY,EAAE,IAAe,EAAQ,EAAE;QACpD,IAAI,MAAM,CAAC,EAAE,CAAC,GAAG,SAAS;YAAE,OAAO;QACnC,MAAM,IAAI,GAAG,UAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAClC,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;QACzB,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjE,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;QACxC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC;QACtC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC;QACtC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;QACxC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;KACzE,CAAC;AACJ,CAAC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
{{!-- Layout: Main Application Wrapper (renders all pages via {{{body}}}) --}}
|
|
1
2
|
<!DOCTYPE html>
|
|
2
3
|
<html lang="en" data-theme="admindb">
|
|
4
|
+
|
|
3
5
|
<head>
|
|
4
6
|
<meta charset="utf-8" />
|
|
5
7
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
@@ -9,7 +11,7 @@
|
|
|
9
11
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet" />
|
|
10
12
|
<link rel="stylesheet" href="{{basePath}}/css/app.css" />
|
|
11
13
|
<script>
|
|
12
|
-
window.APP = { basePath: {{{json basePath}}}, readonly: {{{json readonly}}} };
|
|
14
|
+
window.APP = { basePath: {{{json basePath}}}, readonly: {{{json readonly}}}, serverless: {{{json serverless}}} };
|
|
13
15
|
// Apply the saved theme before first paint to avoid a flash.
|
|
14
16
|
(function () {
|
|
15
17
|
try {
|
|
@@ -18,32 +20,52 @@
|
|
|
18
20
|
} catch (e) {}
|
|
19
21
|
})();
|
|
20
22
|
</script>
|
|
23
|
+
<script src="{{basePath}}/js/icons.js" defer></script>
|
|
21
24
|
<script src="{{basePath}}/js/api.js" defer></script>
|
|
22
25
|
<script src="{{basePath}}/js/app.js" defer></script>
|
|
26
|
+
<script src="{{basePath}}/js/inspector.js" defer></script>
|
|
27
|
+
|
|
23
28
|
</head>
|
|
24
29
|
<body class="min-h-screen bg-base-200 text-base-content">
|
|
25
30
|
{{#if readonly}}
|
|
26
31
|
<div class="flex items-center justify-center gap-2 bg-warning/15 px-4 py-2 text-center text-sm font-semibold text-warning">
|
|
27
|
-
<
|
|
28
|
-
|
|
32
|
+
<span class="shrink-0">{{{icon "warning" class="h-4 w-4"}}}</span>
|
|
33
|
+
{{#if serverless}}
|
|
34
|
+
Serverless mode active — database is open in read-only mode. Writes and schema modifications are disabled.
|
|
35
|
+
{{else}}
|
|
36
|
+
Read-only mode — this database is open without write access. All writes are disabled.
|
|
37
|
+
{{/if}}
|
|
29
38
|
</div>
|
|
30
39
|
{{/if}}
|
|
31
|
-
|
|
32
|
-
<
|
|
33
|
-
<div class="drawer-content flex min-h-screen flex-col">
|
|
40
|
+
{{#if noSidebar}}
|
|
41
|
+
<div class="flex min-h-screen flex-col">
|
|
34
42
|
{{> navbar}}
|
|
35
43
|
<main class="mx-auto w-full max-w-[1500px] flex-1 px-4 py-6 sm:px-6 lg:px-8 lg:py-8">
|
|
36
44
|
{{{body}}}
|
|
37
45
|
</main>
|
|
38
46
|
<footer class="border-t border-base-300 px-6 py-4 text-center text-xs text-base-content/40">
|
|
39
|
-
AdminDB{{#if version}} v{{version}}{{/if}} ·
|
|
47
|
+
AdminDB{{#if version}} v{{version}}{{/if}} · SQLite & PostgreSQL database administration
|
|
40
48
|
</footer>
|
|
41
49
|
</div>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
50
|
+
{{else}}
|
|
51
|
+
<div class="drawer lg:drawer-open">
|
|
52
|
+
<input id="sidebar-toggle" type="checkbox" class="drawer-toggle" />
|
|
53
|
+
<div class="drawer-content flex min-h-screen flex-col">
|
|
54
|
+
{{> navbar}}
|
|
55
|
+
<main class="mx-auto w-full max-w-[1500px] flex-1 px-4 py-6 sm:px-6 lg:px-8 lg:py-8">
|
|
56
|
+
{{{body}}}
|
|
57
|
+
</main>
|
|
58
|
+
<footer class="border-t border-base-300 px-6 py-4 text-center text-xs text-base-content/40">
|
|
59
|
+
AdminDB{{#if version}} v{{version}}{{/if}} · SQLite & PostgreSQL database administration
|
|
60
|
+
</footer>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<div class="drawer-side z-40">
|
|
64
|
+
<label for="sidebar-toggle" aria-label="close sidebar" class="drawer-overlay"></label>
|
|
65
|
+
{{> sidebar}}
|
|
66
|
+
</div>
|
|
45
67
|
</div>
|
|
46
|
-
|
|
68
|
+
{{/if}}
|
|
47
69
|
<div id="toast-container" class="pointer-events-none fixed inset-x-0 top-4 z-50 flex flex-col items-center gap-2 px-4"></div>
|
|
48
70
|
</body>
|
|
49
71
|
</html>
|
|
@@ -1,73 +1,85 @@
|
|
|
1
|
+
{{!-- Page: Multi-Database Manager Landing · URL: /databases (or / in manager mode) --}}
|
|
1
2
|
<div class="space-y-6">
|
|
3
|
+
|
|
2
4
|
<!-- Header -->
|
|
3
5
|
<div>
|
|
4
6
|
<p class="text-sm font-semibold uppercase tracking-wider text-primary">Manager</p>
|
|
5
7
|
<h1 class="mt-1 text-3xl font-extrabold tracking-tight">Databases</h1>
|
|
6
|
-
<p class="mt-1.5 text-sm text-base-content/55">
|
|
8
|
+
<p class="mt-1.5 text-sm text-base-content/55">Connect to PostgreSQL databases, create SQLite files, or open existing local databases with configurable read/write access.</p>
|
|
7
9
|
</div>
|
|
8
10
|
|
|
9
|
-
<!--
|
|
10
|
-
<div class="
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<
|
|
11
|
+
<!-- Connect & Create Actions Grid -->
|
|
12
|
+
<div class="grid grid-cols-1 gap-5 lg:grid-cols-2">
|
|
13
|
+
<!-- Connect PostgreSQL Database -->
|
|
14
|
+
<div class="app-card p-5 border border-info/30 bg-info/[0.02]">
|
|
15
|
+
<div class="mb-3 flex items-center justify-between">
|
|
16
|
+
<h2 class="flex items-center gap-2 text-sm font-bold uppercase tracking-wide text-info">
|
|
17
|
+
{{{icon "database" class="h-4 w-4"}}}
|
|
18
|
+
Connect PostgreSQL
|
|
19
|
+
</h2>
|
|
20
|
+
<span class="rounded bg-info/15 px-2 py-0.5 text-[10px] font-bold text-info">Remote / Local</span>
|
|
15
21
|
</div>
|
|
16
|
-
|
|
17
|
-
<
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
</
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
<div class="space-y-3">
|
|
23
|
+
<div>
|
|
24
|
+
<label class="field-label" for="pg-conn-name">Connection Name <span class="text-base-content/40">(optional)</span></label>
|
|
25
|
+
<input id="pg-conn-name" class="field-input font-mono text-xs" placeholder="e.g. prod_postgres" autocomplete="off" spellcheck="false" />
|
|
26
|
+
</div>
|
|
27
|
+
<div>
|
|
28
|
+
<label class="field-label" for="pg-conn-uri">Connection URI <span class="chip chip-type">required</span></label>
|
|
29
|
+
<input id="pg-conn-uri" class="field-input font-mono text-xs" placeholder="postgresql://user:password@localhost:5432/mydb" autocomplete="off" spellcheck="false" />
|
|
30
|
+
</div>
|
|
31
|
+
<div>
|
|
32
|
+
<label class="flex items-center gap-2 cursor-pointer pt-0.5">
|
|
33
|
+
<input type="checkbox" id="pg-conn-readonly" class="checkbox checkbox-xs checkbox-primary rounded" />
|
|
34
|
+
<span class="text-xs font-medium text-base-content/75">Open as Read-only (block writes & schema changes)</span>
|
|
35
|
+
</label>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="pt-1">
|
|
38
|
+
{{#unless readonly}}
|
|
39
|
+
<button id="connect-pg" type="button" class="btn btn-info btn-sm gap-1.5 w-full sm:w-auto">
|
|
40
|
+
{{{icon "plus" class="h-4 w-4"}}}
|
|
41
|
+
Connect PostgreSQL
|
|
42
|
+
</button>
|
|
43
|
+
{{else}}
|
|
44
|
+
<span class="text-xs font-medium text-warning">Read-only mode — connecting databases is disabled.</span>
|
|
45
|
+
{{/unless}}
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
<p class="mt-3 text-[11px] text-base-content/45 leading-relaxed">
|
|
49
|
+
Credentials are encrypted in-memory and sanitized in the UI. Passwords are never sent to the client.
|
|
50
|
+
</p>
|
|
24
51
|
</div>
|
|
25
|
-
<p class="mt-2 text-xs text-base-content/40">
|
|
26
|
-
New databases are created in <code class="font-mono">{{dbDir}}</code>. Files already there are picked up
|
|
27
|
-
automatically, and any explicitly configured database paths appear here too.
|
|
28
|
-
</p>
|
|
29
|
-
</div>
|
|
30
52
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
<input id="fs-path" class="field-input font-mono sm:!w-96" placeholder="Absolute path to a folder, e.g. C:\data" autocomplete="off" spellcheck="false" />
|
|
40
|
-
<button id="fs-go" type="button" class="btn btn-outline btn-sm gap-1.5">
|
|
41
|
-
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /></svg>
|
|
42
|
-
Go
|
|
43
|
-
</button>
|
|
44
|
-
<button id="fs-up" type="button" class="btn btn-ghost btn-sm gap-1.5">
|
|
45
|
-
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 10h13M3 10l4-4m-4 4l4 4" /></svg>
|
|
46
|
-
Up
|
|
47
|
-
</button>
|
|
53
|
+
<!-- Create SQLite Database -->
|
|
54
|
+
<div class="app-card p-5 border border-emerald-500/30 bg-emerald-500/[0.02]">
|
|
55
|
+
<div class="mb-3 flex items-center justify-between">
|
|
56
|
+
<h2 class="flex items-center gap-2 text-sm font-bold uppercase tracking-wide text-emerald-600 dark:text-emerald-400">
|
|
57
|
+
{{{icon "plus" class="h-4 w-4"}}}
|
|
58
|
+
Create SQLite Database
|
|
59
|
+
</h2>
|
|
60
|
+
<span class="rounded bg-emerald-500/15 px-2 py-0.5 text-[10px] font-bold text-emerald-600 dark:text-emerald-400">File-based</span>
|
|
48
61
|
</div>
|
|
49
|
-
<div class="
|
|
50
|
-
<div
|
|
51
|
-
|
|
62
|
+
<div class="space-y-3">
|
|
63
|
+
<div>
|
|
64
|
+
<label class="field-label" for="new-db-name">Database Name <span class="chip chip-type">required</span></label>
|
|
65
|
+
<input id="new-db-name" class="field-input font-mono text-xs" placeholder="e.g. analytics" autocomplete="off" spellcheck="false" />
|
|
66
|
+
</div>
|
|
67
|
+
<div class="pt-1">
|
|
68
|
+
{{#unless readonly}}
|
|
69
|
+
<button id="create-db" type="button" class="btn btn-primary btn-sm gap-1.5 w-full sm:w-auto">
|
|
70
|
+
{{{icon "plus" class="h-4 w-4"}}}
|
|
71
|
+
Create SQLite DB
|
|
72
|
+
</button>
|
|
73
|
+
{{else}}
|
|
74
|
+
<span class="text-xs font-medium text-warning">Read-only — creating databases is disabled.</span>
|
|
75
|
+
{{/unless}}
|
|
76
|
+
</div>
|
|
52
77
|
</div>
|
|
53
|
-
<p class="mt-
|
|
54
|
-
|
|
55
|
-
switch between databases freely.
|
|
56
|
-
{{#if browseRoot}}
|
|
57
|
-
<span class="font-medium text-base-content/60">Browsing is limited to <code class="font-mono">{{browseRoot}}</code>.</span>
|
|
58
|
-
{{/if}}
|
|
59
|
-
<span class="font-medium text-warning">This server has no authentication — treat it like a remote filesystem & database shell.</span>
|
|
78
|
+
<p class="mt-3 text-[11px] text-base-content/45 leading-relaxed">
|
|
79
|
+
Files are saved to <code class="font-mono">{{dbDir}}</code>. Any <code class="font-mono">.db</code> file dropped there is auto-discovered.
|
|
60
80
|
</p>
|
|
61
81
|
</div>
|
|
62
|
-
|
|
63
|
-
<div class="app-card p-5">
|
|
64
|
-
<p class="text-sm text-base-content/60">
|
|
65
|
-
<b class="text-base-content/80">File browsing is disabled.</b>
|
|
66
|
-
This server was started with specific database files, so the filesystem browser is turned off — use the
|
|
67
|
-
list of available databases below.
|
|
68
|
-
</p>
|
|
69
|
-
</div>
|
|
70
|
-
{{/if}}
|
|
82
|
+
</div>
|
|
71
83
|
|
|
72
84
|
<!-- List -->
|
|
73
85
|
<div>
|
|
@@ -83,9 +95,10 @@
|
|
|
83
95
|
<thead>
|
|
84
96
|
<tr class="bg-base-200/70 text-xs uppercase tracking-wide text-base-content/50">
|
|
85
97
|
<th class="font-semibold">Name</th>
|
|
98
|
+
<th class="font-semibold">Mode</th>
|
|
86
99
|
<th class="text-right font-semibold">Tables</th>
|
|
87
100
|
<th class="text-right font-semibold">Size</th>
|
|
88
|
-
<th class="font-semibold">Modified</th>
|
|
101
|
+
<th class="font-semibold">Status / Modified</th>
|
|
89
102
|
<th class="text-right font-semibold">Actions</th>
|
|
90
103
|
</tr>
|
|
91
104
|
</thead>
|
|
@@ -94,31 +107,76 @@
|
|
|
94
107
|
<tr class="group hover:bg-primary/[0.04]">
|
|
95
108
|
<td>
|
|
96
109
|
<a href="{{../basePath}}/{{this.id}}" class="inline-flex items-center gap-2.5">
|
|
97
|
-
<span class="grid h-8 w-8 shrink-0 place-items-center rounded-lg bg-
|
|
98
|
-
|
|
110
|
+
<span class="grid h-8 w-8 shrink-0 place-items-center rounded-lg {{#if this.isPostgres}}bg-info/10 text-info group-hover:bg-info/20{{else}}bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 group-hover:bg-emerald-500/20{{/if}} transition-colors">
|
|
111
|
+
{{{icon "database" class="h-4 w-4"}}}
|
|
99
112
|
</span>
|
|
100
113
|
<span class="min-w-0">
|
|
101
|
-
<
|
|
102
|
-
|
|
114
|
+
<div class="flex items-center gap-1.5">
|
|
115
|
+
<span class="truncate font-mono text-[13.5px] font-semibold">{{this.name}}</span>
|
|
116
|
+
{{#if this.isPostgres}}
|
|
117
|
+
<span class="rounded bg-info/15 px-1.5 py-0.2 text-[10px] font-bold text-info">PostgreSQL</span>
|
|
118
|
+
{{else}}
|
|
119
|
+
<span class="rounded bg-emerald-500/15 px-1.5 py-0.2 text-[10px] font-bold text-emerald-600 dark:text-emerald-400">SQLite</span>
|
|
120
|
+
{{/if}}
|
|
121
|
+
</div>
|
|
122
|
+
<span class="block max-w-[260px] truncate font-mono text-[11px] text-base-content/40" title="{{this.path}}">{{this.path}}</span>
|
|
103
123
|
</span>
|
|
104
124
|
</a>
|
|
105
125
|
</td>
|
|
126
|
+
<td class="align-middle">
|
|
127
|
+
{{#if ../readonly}}
|
|
128
|
+
<span class="rounded bg-warning/20 px-2 py-0.5 text-[10px] font-bold uppercase text-warning">Read-only</span>
|
|
129
|
+
{{else}}
|
|
130
|
+
<button type="button" class="js-toggle-db-mode rounded px-2 py-0.5 text-[10px] font-bold uppercase transition hover:opacity-80 {{#if this.readonly}}bg-warning/20 text-warning{{else}}bg-success/20 text-success{{/if}}"
|
|
131
|
+
data-id="{{this.id}}" data-readonly="{{#if this.readonly}}true{{else}}false{{/if}}" title="Click to toggle between Writable and Read-only">
|
|
132
|
+
{{#if this.readonly}}Read-only{{else}}Writable{{/if}} ⇄
|
|
133
|
+
</button>
|
|
134
|
+
{{/if}}
|
|
135
|
+
</td>
|
|
106
136
|
<td class="text-right tabular-nums text-base-content/60">{{this.tables}}</td>
|
|
107
137
|
<td class="text-right tabular-nums text-base-content/60">{{this.sizeLabel}}</td>
|
|
108
138
|
<td class="text-[13px] text-base-content/55">{{this.modifiedLabel}}</td>
|
|
109
139
|
<td class="whitespace-nowrap text-right">
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
140
|
+
<div class="row-actions">
|
|
141
|
+
<div class="join">
|
|
142
|
+
<a href="{{../basePath}}/{{this.id}}" class="btn btn-ghost btn-xs join-item gap-1 text-base-content/70 hover:text-primary">
|
|
143
|
+
{{{icon "arrowRight" class="h-3.5 w-3.5"}}}
|
|
113
144
|
Open
|
|
114
145
|
</a>
|
|
115
|
-
|
|
116
|
-
<
|
|
117
|
-
|
|
146
|
+
<div class="dropdown dropdown-end">
|
|
147
|
+
<label tabindex="0" role="button" class="btn btn-ghost btn-xs join-item px-1 text-base-content/60 hover:text-base-content" title="Open options">
|
|
148
|
+
{{{icon "chevronDown" class="h-3 w-3"}}}
|
|
149
|
+
</label>
|
|
150
|
+
<ul tabindex="0" class="dropdown-content menu z-50 w-44 rounded-xl border border-base-300 bg-base-100 p-1.5 shadow-lift text-xs">
|
|
151
|
+
<li>
|
|
152
|
+
<a href="{{../basePath}}/{{this.id}}?readonly=0" class="flex items-center gap-1.5 text-success">
|
|
153
|
+
{{{icon "check" class="h-3.5 w-3.5"}}}
|
|
154
|
+
Open Writable
|
|
155
|
+
</a>
|
|
156
|
+
</li>
|
|
157
|
+
<li>
|
|
158
|
+
<a href="{{../basePath}}/{{this.id}}?readonly=1" class="flex items-center gap-1.5 text-warning">
|
|
159
|
+
{{{icon "lock" class="h-3.5 w-3.5"}}}
|
|
160
|
+
Open Read-only
|
|
161
|
+
</a>
|
|
162
|
+
</li>
|
|
163
|
+
</ul>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
{{#unless ../readonly}}
|
|
167
|
+
{{#if this.isPostgres}}
|
|
168
|
+
<button type="button" class="btn btn-ghost btn-xs gap-1 text-warning js-disconnect-db" data-id="{{this.id}}" data-name="{{this.name}}" title="Disconnect this database from the manager list">
|
|
169
|
+
{{{icon "logout" class="h-3.5 w-3.5"}}}
|
|
170
|
+
Disconnect
|
|
171
|
+
</button>
|
|
172
|
+
{{else}}
|
|
173
|
+
<button type="button" class="btn btn-ghost btn-xs gap-1 text-error js-delete-db" data-id="{{this.id}}" title="Delete database file from disk">
|
|
174
|
+
{{{icon "trash" class="h-3.5 w-3.5"}}}
|
|
118
175
|
Delete
|
|
119
176
|
</button>
|
|
120
|
-
{{/
|
|
121
|
-
|
|
177
|
+
{{/if}}
|
|
178
|
+
{{/unless}}
|
|
179
|
+
</div>
|
|
122
180
|
</td>
|
|
123
181
|
</tr>
|
|
124
182
|
{{/each}}
|
|
@@ -128,16 +186,66 @@
|
|
|
128
186
|
</div>
|
|
129
187
|
{{else}}
|
|
130
188
|
<div class="empty-state">
|
|
131
|
-
<span class="empty-icon">
|
|
132
|
-
<svg xmlns="http://www.w3.org/2000/svg" class="h-7 w-7" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 7v10c0 1.1.9 2 2 2h12a2 2 0 002-2V7M4 7c0-1.1.9-2 2-2h12a2 2 0 012 2M4 7c0 1.1.9 2 2 2h12a2 2 0 002-2" /></svg>
|
|
133
|
-
</span>
|
|
189
|
+
<span class="empty-icon">{{{icon "database" class="h-7 w-7"}}}</span>
|
|
134
190
|
<p class="text-sm font-medium text-base-content/70">No databases yet</p>
|
|
135
191
|
<p class="max-w-sm text-sm text-base-content/45">
|
|
136
|
-
|
|
137
|
-
<code class="font-mono">{{dbDir}}</code> and refresh.
|
|
192
|
+
Connect a PostgreSQL database or create a new SQLite database above to get started.
|
|
138
193
|
</p>
|
|
139
194
|
</div>
|
|
140
195
|
{{/if}}
|
|
141
196
|
</div>
|
|
197
|
+
|
|
198
|
+
<!-- Open an existing database file -->
|
|
199
|
+
{{#if allowBrowse}}
|
|
200
|
+
<div class="app-card p-5">
|
|
201
|
+
<div class="mb-3 flex flex-wrap items-center justify-between gap-2">
|
|
202
|
+
<h2 class="text-sm font-semibold uppercase tracking-wide text-base-content/45">Open an existing SQLite file</h2>
|
|
203
|
+
<span class="text-xs text-base-content/40">.db · .sqlite · .sqlite3</span>
|
|
204
|
+
</div>
|
|
205
|
+
<div class="flex flex-wrap items-center gap-2">
|
|
206
|
+
<input id="fs-path" class="field-input font-mono sm:!w-96" placeholder="Absolute path to a folder, e.g. C:\data" autocomplete="off" spellcheck="false" />
|
|
207
|
+
<button id="fs-go" type="button" class="btn btn-outline btn-sm gap-1.5">
|
|
208
|
+
{{{icon "search" class="h-4 w-4"}}}
|
|
209
|
+
Go
|
|
210
|
+
</button>
|
|
211
|
+
<button id="fs-up" type="button" class="btn btn-ghost btn-sm gap-1.5">
|
|
212
|
+
{{{icon "arrowUp" class="h-4 w-4"}}}
|
|
213
|
+
Up
|
|
214
|
+
</button>
|
|
215
|
+
</div>
|
|
216
|
+
<div class="mt-2">
|
|
217
|
+
<label class="flex items-center gap-2 cursor-pointer">
|
|
218
|
+
<input type="checkbox" id="fs-readonly" class="checkbox checkbox-xs checkbox-primary rounded" />
|
|
219
|
+
<span class="text-xs font-medium text-base-content/70">Open selected file in Read-only mode</span>
|
|
220
|
+
</label>
|
|
221
|
+
</div>
|
|
222
|
+
<div class="mt-3 overflow-hidden rounded-xl border border-base-300">
|
|
223
|
+
<div id="fs-current" class="border-b border-base-200 bg-base-200/50 px-3 py-2 font-mono text-xs text-base-content/60"></div>
|
|
224
|
+
<div id="fs-listing" class="max-h-80 divide-y divide-base-200/70 overflow-auto"></div>
|
|
225
|
+
</div>
|
|
226
|
+
<p class="mt-2.5 text-xs text-base-content/45">
|
|
227
|
+
Browse the filesystem to select an existing database; opening it adds it to the list above.
|
|
228
|
+
{{#if browseRoot}}
|
|
229
|
+
<span class="font-medium text-base-content/60">Browsing is limited to <code class="font-mono">{{browseRoot}}</code>.</span>
|
|
230
|
+
{{/if}}
|
|
231
|
+
</p>
|
|
232
|
+
</div>
|
|
233
|
+
{{/if}}
|
|
234
|
+
|
|
235
|
+
<!-- Security Responsibility Notice -->
|
|
236
|
+
<div class="rounded-xl border border-warning/30 bg-warning/[0.04] p-4 text-xs text-base-content/75 leading-relaxed">
|
|
237
|
+
<div class="flex items-start gap-2.5">
|
|
238
|
+
<span class="text-warning shrink-0 mt-0.5">
|
|
239
|
+
{{{icon "warning" class="h-4 w-4"}}}
|
|
240
|
+
</span>
|
|
241
|
+
<div>
|
|
242
|
+
<span class="font-bold text-warning">Security & Protection Notice:</span>
|
|
243
|
+
AdminDB's native authentication provides basic single-user password protection. For production environments and internet-facing networks, <strong>it is entirely your responsibility to secure this interface</strong> by placing it behind your web application's own authentication system (e.g., custom Express/Next.js auth middleware, SSO/OAuth, NextAuth), a secure VPN, or an IP-whitelisted reverse proxy with HTTPS.
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
</div>
|
|
247
|
+
|
|
142
248
|
</div>
|
|
143
249
|
<script src="{{basePath}}/js/databases.js" defer></script>
|
|
250
|
+
|
|
251
|
+
|