admindb 2.1.1 → 2.3.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 +368 -335
- package/dist/app.js +227 -1
- package/dist/auth/config.d.ts +1 -1
- package/dist/auth/config.js +109 -1
- package/dist/auth/crypto.js +98 -1
- package/dist/auth/index.js +21 -1
- package/dist/auth/middleware.js +78 -1
- package/dist/auth/routes.js +64 -1
- package/dist/auth/types.js +7 -1
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.js +309 -1
- package/dist/cli/config.js +118 -1
- package/dist/cli/index.js +20 -1
- package/dist/cli/runner.js +208 -1
- package/dist/cli.js +4 -1
- package/dist/data/chain.d.ts +1 -0
- package/dist/data/chain.js +130 -0
- package/dist/data/datasets.d.ts +1 -1
- package/dist/data/datasets.js +171 -1
- package/dist/data/detector.d.ts +1 -1
- package/dist/data/detector.js +535 -1
- package/dist/data/engine.d.ts +1 -1
- package/dist/data/engine.js +586 -1
- package/dist/data/index.d.ts +1 -1
- package/dist/data/index.js +30 -1
- package/dist/data/prng.d.ts +1 -0
- package/dist/data/prng.js +73 -0
- package/dist/data/registry.d.ts +1 -0
- package/dist/data/registry.js +805 -0
- package/dist/data/schema-graph.d.ts +1 -0
- package/dist/data/schema-graph.js +210 -0
- package/dist/data/strategies.d.ts +1 -1
- package/dist/data/strategies.js +100 -1
- package/dist/data/templates.d.ts +1 -0
- package/dist/data/templates.js +134 -0
- package/dist/data/types.d.ts +1 -1
- package/dist/data/types.js +5 -1
- package/dist/data/validator.d.ts +1 -0
- package/dist/data/validator.js +160 -0
- package/dist/db/database.d.ts +1 -1
- package/dist/db/database.js +472 -1
- package/dist/db/export.d.ts +1 -1
- package/dist/db/export.js +67 -1
- package/dist/db/filters.d.ts +1 -1
- package/dist/db/filters.js +119 -1
- package/dist/db/index.js +24 -1
- package/dist/db/introspection.js +164 -1
- package/dist/db/manager.js +327 -1
- package/dist/db/migrations.js +100 -1
- package/dist/db/postgres.d.ts +1 -1
- package/dist/db/postgres.js +687 -1
- package/dist/db/types.d.ts +1 -1
- package/dist/db/types.js +6 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +52 -1
- package/dist/public/css/app.css +1 -1
- package/dist/public/js/api.js +1 -1
- package/dist/public/js/browse.js +1 -1
- package/dist/public/js/common.js +1 -0
- package/dist/public/js/databases.js +1 -1
- package/dist/public/js/designer.js +1 -1
- package/dist/public/js/forms.js +1 -1
- package/dist/public/js/home.js +1 -0
- package/dist/public/js/inspector.js +1 -1
- package/dist/public/js/query.js +1 -1
- package/dist/public/js/schema.js +1 -1
- package/dist/public/js/seed.js +1 -1
- package/dist/routes/api/erd.d.ts +1 -0
- package/dist/routes/api/erd.js +45 -0
- package/dist/routes/api/helpers.d.ts +1 -1
- package/dist/routes/api/helpers.js +213 -1
- package/dist/routes/api/import-export.js +82 -1
- package/dist/routes/api/index.js +48 -1
- package/dist/routes/api/query.js +74 -1
- package/dist/routes/api/rows.js +358 -1
- package/dist/routes/api/seed.js +167 -1
- package/dist/routes/api/tables.js +216 -1
- package/dist/routes/databases.js +210 -1
- package/dist/routes/index.js +19 -1
- package/dist/routes/pages.js +446 -1
- package/dist/serverless.js +149 -1
- package/dist/sql/classifier.js +24 -1
- package/dist/sql/error-analyzer.d.ts +1 -0
- package/dist/sql/error-analyzer.js +550 -0
- package/dist/sql/generator.d.ts +1 -1
- package/dist/sql/generator.js +245 -1
- package/dist/sql/index.js +18 -1
- package/dist/types/api.d.ts +1 -1
- package/dist/types/api.js +2 -1
- package/dist/utils/colors.js +54 -1
- package/dist/utils/common.d.ts +1 -1
- package/dist/utils/common.js +185 -1
- package/dist/utils/csv.d.ts +1 -1
- package/dist/utils/csv.js +61 -1
- package/dist/utils/datatype.js +167 -1
- package/dist/utils/icons.js +81 -1
- package/dist/utils/index.js +20 -1
- package/dist/utils/logger.js +36 -1
- package/dist/views/layouts/main.hbs +1 -74
- package/dist/views/pages/databases.hbs +1 -233
- package/dist/views/pages/designer.hbs +1 -89
- package/dist/views/pages/erd.hbs +1 -0
- package/dist/views/pages/error.hbs +1 -10
- package/dist/views/pages/form.hbs +1 -59
- package/dist/views/pages/home.hbs +1 -124
- package/dist/views/pages/info.hbs +1 -0
- package/dist/views/pages/login.hbs +1 -98
- package/dist/views/pages/query.hbs +1 -87
- package/dist/views/pages/schema.hbs +1 -298
- package/dist/views/pages/seed-select.hbs +251 -0
- package/dist/views/pages/seed.hbs +273 -167
- package/dist/views/pages/table.hbs +1 -327
- package/dist/views/partials/navbar.hbs +1 -83
- package/dist/views/partials/sidebar.hbs +1 -117
- package/docs/API.md +149 -144
- package/docs/EXAMPLES.md +579 -576
- package/docs/SECURITY.md +265 -265
- package/package.json +79 -78
- package/dist/public/js/icons.js +0 -1
package/dist/auth/types.js
CHANGED
|
@@ -1 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SESSION_COOKIE_NAME = exports.DEFAULT_SESSION_DURATION_MS = exports.DEFAULT_PASSWORD_HASH = exports.DEFAULT_USERNAME = void 0;
|
|
4
|
+
exports.DEFAULT_USERNAME = 'admin';
|
|
5
|
+
exports.DEFAULT_PASSWORD_HASH = 'scrypt:d9f2e64b8a1c3d5e7f0a2b4c6e801357:cb3032b16f29c8d44f75c779f070c61c846b17eb333d07596ceb8470fc1b4c06cc720c08796ebc86937dab28a3ef580ced38a71c940fd4a169fd2e9cb9fa40e2';
|
|
6
|
+
exports.DEFAULT_SESSION_DURATION_MS = 7 * 24 * 60 * 60 * 1000;
|
|
7
|
+
exports.SESSION_COOKIE_NAME = 'admindb_session';
|
package/dist/cli/args.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import type {LogLevel} from '../utils/logger';export interface CliArgs{help:boolean;version:boolean;host?:string;port?:number;dbPath?:string;connection?:string;connections?:Record<string,string>;configPath?:string;dbDir?:string;dbFiles?:string[];basePath?:string;logLevel?:LogLevel;readonly :boolean;serverless?:boolean;auth?:boolean;authUsername?:string;authPassword?:string;authSecret?:string;}export declare function helpText():string;export declare
|
|
1
|
+
import type {LogLevel} from '../utils/logger';export interface CliArgs{help:boolean;version:boolean;host?:string;port?:number;dbPath?:string;connection?:string;connections?:Record<string,string>;configPath?:string;dbDir?:string;dbFiles?:string[];basePath?:string;logLevel?:LogLevel;readonly :boolean;serverless?:boolean;auth?:boolean;authUsername?:string;authPassword?:string;authSecret?:string;}export declare function helpText():string;export declare const getPackageVersion:()=>string;export declare const versionText:()=>string;export declare function parseArgs(argv:string[]):{args:CliArgs;error?:string;};
|
package/dist/cli/args.js
CHANGED
|
@@ -1 +1,309 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.versionText = exports.getPackageVersion = void 0;
|
|
7
|
+
exports.helpText = helpText;
|
|
8
|
+
exports.parseArgs = parseArgs;
|
|
9
|
+
const node_fs_1 = require("node:fs");
|
|
10
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
11
|
+
const common_1 = require("../utils/common");
|
|
12
|
+
const config_1 = require("./config");
|
|
13
|
+
const LOG_LEVELS = ['debug', 'info', 'warn', 'error'];
|
|
14
|
+
function helpText() {
|
|
15
|
+
return [
|
|
16
|
+
'AdminDB — browser-based SQLite & PostgreSQL administration tool.',
|
|
17
|
+
'',
|
|
18
|
+
'Usage:',
|
|
19
|
+
' admindb [options] [path|connection_url|config.json]',
|
|
20
|
+
'',
|
|
21
|
+
'Starts a local server and opens a web UI where you can browse, select and',
|
|
22
|
+
'manage SQLite databases (.db / .sqlite / .sqlite3) and PostgreSQL databases.',
|
|
23
|
+
'',
|
|
24
|
+
'With no path or options it runs in "manager" mode: the landing page lets',
|
|
25
|
+
'you browse the filesystem and open any database file, or create new ones.',
|
|
26
|
+
'',
|
|
27
|
+
'Arguments:',
|
|
28
|
+
' path Path to a database file, PostgreSQL connection URL, or',
|
|
29
|
+
' JSON configuration file containing database credentials.',
|
|
30
|
+
'',
|
|
31
|
+
'Options & Environment Variables:',
|
|
32
|
+
' -C, --config <file.json> Load database credentials & settings from a JSON file',
|
|
33
|
+
' -p, --port <port> Port to listen on (default: 45531) [PORT / ADMINDB_PORT]',
|
|
34
|
+
' -H, --host <host> Host/interface to bind (default: 0.0.0.0) [HOST / ADMINDB_HOST]',
|
|
35
|
+
' -c, --connection, --pg <uri> Open a PostgreSQL database directly [DATABASE_URL / ADMINDB_CONNECTION]',
|
|
36
|
+
' -o, --open, --db-path <file> Open a single database file directly [DB_PATH / ADMINDB_DB_PATH]',
|
|
37
|
+
' -d, --dir, --db-dir <dir> Folder of database files to manage [DB_DIR / ADMINDB_DB_DIR]',
|
|
38
|
+
' --files, --db-files <list> Comma-separated database file paths [DB_FILES / ADMINDB_DB_FILES]',
|
|
39
|
+
' -b, --base-path, --base <p> URL prefix to serve under (default: /) [BASE_PATH / ADMINDB_BASE_PATH]',
|
|
40
|
+
' -r, --readonly, --read-only Open databases read-only (writes disabled) [READONLY / ADMINDB_READONLY]',
|
|
41
|
+
' --serverless Enable serverless mode (enforces read-only, disables writes) [SERVERLESS / ADMINDB_SERVERLESS]',
|
|
42
|
+
' --auth Enable authentication (default: on) [ADMINDB_AUTH=true]',
|
|
43
|
+
' --no-auth, --disable-auth Disable authentication completely [ADMINDB_NO_AUTH=1 / ADMINDB_AUTH=false]',
|
|
44
|
+
' -u, --username, --user <user> Admin username (default: admin) [ADMINDB_USERNAME / ADMINDB_USER]',
|
|
45
|
+
' -P, --password, --pass <pass> Admin password or hash [ADMINDB_PASSWORD / ADMINDB_PASS]',
|
|
46
|
+
' --auth-secret <sec> Secret key used to sign session cookies [ADMINDB_SECRET / SESSION_SECRET]',
|
|
47
|
+
' -l, --log-level <level> debug | info | warn | error (default: info) [LOG_LEVEL / ADMINDB_LOG_LEVEL]',
|
|
48
|
+
' -h, --help Show this help message',
|
|
49
|
+
' -v, --version Show version',
|
|
50
|
+
'',
|
|
51
|
+
'Examples:',
|
|
52
|
+
' admindb name.postgres.json # load database connections from a JSON file',
|
|
53
|
+
' admindb postgresql://user:pass@host:5432/db # open a PostgreSQL database directly',
|
|
54
|
+
' admindb ./data/app.db # open a SQLite database file',
|
|
55
|
+
' admindb --no-auth # run with authentication turned off',
|
|
56
|
+
' admindb -C ./connections.json # run with JSON connections config',
|
|
57
|
+
'',
|
|
58
|
+
'See docs/EXAMPLES.md for full configuration reference and deployment recipes.',
|
|
59
|
+
].join('\n');
|
|
60
|
+
}
|
|
61
|
+
function packageVersion() {
|
|
62
|
+
try {
|
|
63
|
+
const candidates = [
|
|
64
|
+
node_path_1.default.join(__dirname, '..', '..', 'package.json'),
|
|
65
|
+
node_path_1.default.join(__dirname, '..', 'package.json'),
|
|
66
|
+
node_path_1.default.join(__dirname, 'package.json'),
|
|
67
|
+
];
|
|
68
|
+
for (const p of candidates) {
|
|
69
|
+
if ((0, node_fs_1.existsSync)(p)) {
|
|
70
|
+
const pkg = JSON.parse((0, node_fs_1.readFileSync)(p, 'utf8'));
|
|
71
|
+
if (pkg.version)
|
|
72
|
+
return pkg.version;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch { }
|
|
77
|
+
return '';
|
|
78
|
+
}
|
|
79
|
+
const getPackageVersion = () => packageVersion();
|
|
80
|
+
exports.getPackageVersion = getPackageVersion;
|
|
81
|
+
const versionText = () => {
|
|
82
|
+
const v = packageVersion();
|
|
83
|
+
return v ? `admindb v${v}` : 'admindb';
|
|
84
|
+
};
|
|
85
|
+
exports.versionText = versionText;
|
|
86
|
+
const isFlag = (tok, ...names) => names.includes(tok) || names.some((n) => n.length > 2 && tok.startsWith(`${n}=`));
|
|
87
|
+
function parseArgs(argv) {
|
|
88
|
+
const args = { help: false, version: false, readonly: false };
|
|
89
|
+
const positional = [];
|
|
90
|
+
let i = 0;
|
|
91
|
+
const invalid = (error) => ({ args, error });
|
|
92
|
+
const takeValue = (flag) => {
|
|
93
|
+
const eq = argv[i].indexOf('=');
|
|
94
|
+
if (eq !== -1)
|
|
95
|
+
return argv[i].slice(eq + 1);
|
|
96
|
+
i++;
|
|
97
|
+
return argv[i];
|
|
98
|
+
};
|
|
99
|
+
while (i < argv.length) {
|
|
100
|
+
const tok = argv[i];
|
|
101
|
+
if (tok === '-h' || tok === '--help') {
|
|
102
|
+
args.help = true;
|
|
103
|
+
}
|
|
104
|
+
else if (tok === '-v' || tok === '--version') {
|
|
105
|
+
args.version = true;
|
|
106
|
+
}
|
|
107
|
+
else if (isFlag(tok, '-C', '--config', '--json')) {
|
|
108
|
+
const v = takeValue('--config');
|
|
109
|
+
if (v === undefined)
|
|
110
|
+
return invalid('Missing value for --config.');
|
|
111
|
+
args.configPath = v;
|
|
112
|
+
try {
|
|
113
|
+
const fileConf = (0, config_1.parseConfigFile)(v);
|
|
114
|
+
if (fileConf) {
|
|
115
|
+
if (fileConf.connections)
|
|
116
|
+
args.connections = fileConf.connections;
|
|
117
|
+
if (fileConf.connection)
|
|
118
|
+
args.connection = fileConf.connection;
|
|
119
|
+
if (fileConf.port !== undefined)
|
|
120
|
+
args.port = fileConf.port;
|
|
121
|
+
if (fileConf.host !== undefined)
|
|
122
|
+
args.host = fileConf.host;
|
|
123
|
+
if (fileConf.basePath !== undefined)
|
|
124
|
+
args.basePath = fileConf.basePath;
|
|
125
|
+
if (fileConf.readonly !== undefined)
|
|
126
|
+
args.readonly = fileConf.readonly;
|
|
127
|
+
if (fileConf.serverless !== undefined)
|
|
128
|
+
args.serverless = fileConf.serverless;
|
|
129
|
+
if (fileConf.logLevel !== undefined)
|
|
130
|
+
args.logLevel = fileConf.logLevel;
|
|
131
|
+
if (typeof fileConf.auth === 'boolean')
|
|
132
|
+
args.auth = fileConf.auth;
|
|
133
|
+
else if (fileConf.auth && typeof fileConf.auth === 'object') {
|
|
134
|
+
args.auth = true;
|
|
135
|
+
if (fileConf.auth.username)
|
|
136
|
+
args.authUsername = fileConf.auth.username;
|
|
137
|
+
if (fileConf.auth.password)
|
|
138
|
+
args.authPassword = fileConf.auth.password;
|
|
139
|
+
if (fileConf.auth.secret)
|
|
140
|
+
args.authSecret = fileConf.auth.secret;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
return invalid(err.message);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else if (isFlag(tok, '-p', '--port')) {
|
|
149
|
+
const v = takeValue('--port');
|
|
150
|
+
if (v === undefined)
|
|
151
|
+
return invalid('Missing value for --port.');
|
|
152
|
+
const n = Number.parseInt(v, 10);
|
|
153
|
+
if (!Number.isFinite(n) || n <= 0)
|
|
154
|
+
return invalid(`Invalid port: "${v}".`);
|
|
155
|
+
args.port = n;
|
|
156
|
+
}
|
|
157
|
+
else if (isFlag(tok, '-H', '--host')) {
|
|
158
|
+
const v = takeValue('--host');
|
|
159
|
+
if (v === undefined)
|
|
160
|
+
return invalid('Missing value for --host.');
|
|
161
|
+
args.host = v;
|
|
162
|
+
}
|
|
163
|
+
else if (isFlag(tok, '-c', '--connection', '--conn', '--pg')) {
|
|
164
|
+
const v = takeValue('--connection');
|
|
165
|
+
if (v === undefined)
|
|
166
|
+
return invalid('Missing value for --connection.');
|
|
167
|
+
args.connection = v;
|
|
168
|
+
args.dbPath = v;
|
|
169
|
+
}
|
|
170
|
+
else if (isFlag(tok, '-o', '--open', '--db', '-f', '--file', '--db-path', '--path')) {
|
|
171
|
+
const v = takeValue('--open');
|
|
172
|
+
if (v === undefined)
|
|
173
|
+
return invalid('Missing value for --open / --db-path.');
|
|
174
|
+
args.dbPath = v;
|
|
175
|
+
if ((0, common_1.isPostgresConnectionString)(v))
|
|
176
|
+
args.connection = v;
|
|
177
|
+
}
|
|
178
|
+
else if (isFlag(tok, '-d', '--dir', '--folder', '--db-dir')) {
|
|
179
|
+
const v = takeValue('--dir');
|
|
180
|
+
if (v === undefined)
|
|
181
|
+
return invalid('Missing value for --dir / --db-dir.');
|
|
182
|
+
args.dbDir = v;
|
|
183
|
+
}
|
|
184
|
+
else if (isFlag(tok, '--files', '--db-files')) {
|
|
185
|
+
const v = takeValue('--files');
|
|
186
|
+
if (v === undefined)
|
|
187
|
+
return invalid('Missing value for --files / --db-files.');
|
|
188
|
+
args.dbFiles = v.split(',').map((s) => s.trim()).filter(Boolean);
|
|
189
|
+
}
|
|
190
|
+
else if (isFlag(tok, '-b', '--base-path', '--base')) {
|
|
191
|
+
const v = takeValue('--base-path');
|
|
192
|
+
if (v === undefined)
|
|
193
|
+
return invalid('Missing value for --base-path.');
|
|
194
|
+
args.basePath = v;
|
|
195
|
+
}
|
|
196
|
+
else if (isFlag(tok, '-l', '--log-level')) {
|
|
197
|
+
const v = takeValue('--log-level');
|
|
198
|
+
if (v === undefined)
|
|
199
|
+
return invalid('Missing value for --log-level.');
|
|
200
|
+
if (!LOG_LEVELS.includes(v)) {
|
|
201
|
+
return invalid(`Invalid log level: "${v}". Expected one of: ${LOG_LEVELS.join(', ')}.`);
|
|
202
|
+
}
|
|
203
|
+
args.logLevel = v;
|
|
204
|
+
}
|
|
205
|
+
else if (tok === '-r' || tok === '--readonly' || tok === '--read-only') {
|
|
206
|
+
args.readonly = true;
|
|
207
|
+
}
|
|
208
|
+
else if (tok === '--serverless') {
|
|
209
|
+
args.serverless = true;
|
|
210
|
+
args.readonly = true;
|
|
211
|
+
}
|
|
212
|
+
else if (tok === '--no-auth' || tok === '--disable-auth') {
|
|
213
|
+
args.auth = false;
|
|
214
|
+
}
|
|
215
|
+
else if (tok === '--auth') {
|
|
216
|
+
args.auth = true;
|
|
217
|
+
}
|
|
218
|
+
else if (isFlag(tok, '-u', '--username', '--user', '--auth-username')) {
|
|
219
|
+
const v = takeValue('--username');
|
|
220
|
+
if (v === undefined)
|
|
221
|
+
return invalid('Missing value for --username.');
|
|
222
|
+
args.authUsername = v;
|
|
223
|
+
}
|
|
224
|
+
else if (isFlag(tok, '-P', '--password', '--pass', '--auth-password')) {
|
|
225
|
+
const v = takeValue('--password');
|
|
226
|
+
if (v === undefined)
|
|
227
|
+
return invalid('Missing value for --password.');
|
|
228
|
+
args.authPassword = v;
|
|
229
|
+
}
|
|
230
|
+
else if (isFlag(tok, '--auth-secret', '--secret', '--session-secret')) {
|
|
231
|
+
const v = takeValue('--auth-secret');
|
|
232
|
+
if (v === undefined)
|
|
233
|
+
return invalid('Missing value for --auth-secret.');
|
|
234
|
+
args.authSecret = v;
|
|
235
|
+
}
|
|
236
|
+
else if (tok.startsWith('-') && tok.length > 1) {
|
|
237
|
+
return invalid(`Unknown option: "${tok}".`);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
positional.push(tok);
|
|
241
|
+
}
|
|
242
|
+
i++;
|
|
243
|
+
}
|
|
244
|
+
if (positional.length > 1) {
|
|
245
|
+
return invalid(`Unexpected extra arguments: ${positional.slice(1).join(' ')}.`);
|
|
246
|
+
}
|
|
247
|
+
const p = positional[0];
|
|
248
|
+
if (p) {
|
|
249
|
+
if ((0, common_1.isPostgresConnectionString)(p)) {
|
|
250
|
+
args.connection = p;
|
|
251
|
+
args.dbPath = p;
|
|
252
|
+
}
|
|
253
|
+
else if (p.endsWith('.json') || (0, node_fs_1.existsSync)(p)) {
|
|
254
|
+
try {
|
|
255
|
+
const isJson = p.endsWith('.json');
|
|
256
|
+
if (isJson || ((0, node_fs_1.statSync)(p).isFile() && p.includes('.json'))) {
|
|
257
|
+
args.configPath = p;
|
|
258
|
+
const fileConf = (0, config_1.parseConfigFile)(p);
|
|
259
|
+
if (fileConf) {
|
|
260
|
+
if (fileConf.connections)
|
|
261
|
+
args.connections = fileConf.connections;
|
|
262
|
+
if (fileConf.connection)
|
|
263
|
+
args.connection = fileConf.connection;
|
|
264
|
+
if (fileConf.port !== undefined && args.port === undefined)
|
|
265
|
+
args.port = fileConf.port;
|
|
266
|
+
if (fileConf.host !== undefined && args.host === undefined)
|
|
267
|
+
args.host = fileConf.host;
|
|
268
|
+
if (fileConf.basePath !== undefined && args.basePath === undefined)
|
|
269
|
+
args.basePath = fileConf.basePath;
|
|
270
|
+
if (fileConf.readonly !== undefined)
|
|
271
|
+
args.readonly = fileConf.readonly;
|
|
272
|
+
if (fileConf.serverless !== undefined)
|
|
273
|
+
args.serverless = fileConf.serverless;
|
|
274
|
+
if (fileConf.logLevel !== undefined && args.logLevel === undefined)
|
|
275
|
+
args.logLevel = fileConf.logLevel;
|
|
276
|
+
if (args.auth === undefined) {
|
|
277
|
+
if (typeof fileConf.auth === 'boolean')
|
|
278
|
+
args.auth = fileConf.auth;
|
|
279
|
+
else if (fileConf.auth && typeof fileConf.auth === 'object') {
|
|
280
|
+
args.auth = true;
|
|
281
|
+
if (fileConf.auth.username && !args.authUsername)
|
|
282
|
+
args.authUsername = fileConf.auth.username;
|
|
283
|
+
if (fileConf.auth.password && !args.authPassword)
|
|
284
|
+
args.authPassword = fileConf.auth.password;
|
|
285
|
+
if (fileConf.auth.secret && !args.authSecret)
|
|
286
|
+
args.authSecret = fileConf.auth.secret;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
else if ((0, node_fs_1.statSync)(p).isDirectory()) {
|
|
292
|
+
args.dbDir = p;
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
args.dbPath = p;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
catch (err) {
|
|
299
|
+
if (p.endsWith('.json'))
|
|
300
|
+
return invalid(err.message);
|
|
301
|
+
args.dbPath = p;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
args.dbPath = p;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return { args };
|
|
309
|
+
}
|
package/dist/cli/config.js
CHANGED
|
@@ -1 +1,118 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseConfigFile = parseConfigFile;
|
|
7
|
+
exports.loadConfig = loadConfig;
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const serverless_1 = require("../serverless");
|
|
11
|
+
const common_1 = require("../utils/common");
|
|
12
|
+
function parseConfigFile(filePath) {
|
|
13
|
+
try {
|
|
14
|
+
const absPath = node_path_1.default.resolve(filePath);
|
|
15
|
+
if (!(0, node_fs_1.existsSync)(absPath))
|
|
16
|
+
return null;
|
|
17
|
+
const content = (0, node_fs_1.readFileSync)(absPath, 'utf8');
|
|
18
|
+
const parsed = JSON.parse(content);
|
|
19
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
20
|
+
return null;
|
|
21
|
+
const result = {};
|
|
22
|
+
const conns = {};
|
|
23
|
+
const topDbs = parsed.databases || parsed.connections;
|
|
24
|
+
if (topDbs && typeof topDbs === 'object' && !Array.isArray(topDbs)) {
|
|
25
|
+
for (const [k, v] of Object.entries(topDbs)) {
|
|
26
|
+
if (typeof v === 'string' && v.trim())
|
|
27
|
+
conns[k.trim()] = v.trim();
|
|
28
|
+
else if (v && typeof v === 'object' && typeof v.connection === 'string') {
|
|
29
|
+
conns[k.trim()] = v.connection.trim();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
34
|
+
if (['databases', 'connections', 'port', 'host', 'basePath', 'readonly', 'serverless', 'auth', 'logLevel', 'username', 'password', 'secret'].includes(k)) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (typeof v === 'string' && v.trim()) {
|
|
38
|
+
conns[k.trim()] = v.trim();
|
|
39
|
+
}
|
|
40
|
+
else if (v && typeof v === 'object' && typeof v.connection === 'string') {
|
|
41
|
+
conns[k.trim()] = v.connection.trim();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (typeof parsed.connection === 'string' && parsed.connection.trim())
|
|
45
|
+
result.connection = parsed.connection.trim();
|
|
46
|
+
if (typeof parsed.port === 'number')
|
|
47
|
+
result.port = parsed.port;
|
|
48
|
+
if (typeof parsed.host === 'string')
|
|
49
|
+
result.host = parsed.host;
|
|
50
|
+
if (typeof parsed.basePath === 'string')
|
|
51
|
+
result.basePath = parsed.basePath;
|
|
52
|
+
if (typeof parsed.readonly === 'boolean')
|
|
53
|
+
result.readonly = parsed.readonly;
|
|
54
|
+
if (typeof parsed.serverless === 'boolean')
|
|
55
|
+
result.serverless = parsed.serverless;
|
|
56
|
+
if (typeof parsed.auth === 'boolean' || (parsed.auth && typeof parsed.auth === 'object'))
|
|
57
|
+
result.auth = parsed.auth;
|
|
58
|
+
if (typeof parsed.logLevel === 'string')
|
|
59
|
+
result.logLevel = parsed.logLevel;
|
|
60
|
+
if (Object.keys(conns).length > 0)
|
|
61
|
+
result.connections = conns;
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
throw new Error(`Failed to parse configuration file "${filePath}": ${(0, common_1.errorMessage)(err)}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function loadConfig(env = process.env) {
|
|
69
|
+
const portRaw = env.ADMINDB_PORT ?? env.PORT ?? '45531';
|
|
70
|
+
const port = Number.parseInt(portRaw, 10);
|
|
71
|
+
const authDisabled = ['0', 'false', 'no', 'off'].includes(String(env.ADMINDB_AUTH ?? '').trim().toLowerCase()) ||
|
|
72
|
+
['1', 'true', 'yes'].includes(String(env.ADMINDB_NO_AUTH ?? env.ADMINDB_DISABLE_AUTH ?? '').trim().toLowerCase());
|
|
73
|
+
const dbDirRaw = env.ADMINDB_DB_DIR ?? env.ADMINDB_DIR ?? env.DB_DIR;
|
|
74
|
+
const dbFilesRaw = env.ADMINDB_DB_FILES ?? env.DB_FILES;
|
|
75
|
+
const connectionRaw = env.ADMINDB_CONNECTION ?? env.DATABASE_URL ?? env.PG_CONNECTION ?? env.POSTGRES_URL;
|
|
76
|
+
const dbPathRaw = env.ADMINDB_DB_PATH ?? env.ADMINDB_PATH ?? env.DB_PATH ?? connectionRaw;
|
|
77
|
+
const basePathRaw = env.ADMINDB_BASE_PATH ?? env.BASE_PATH ?? '';
|
|
78
|
+
const logLevelRaw = env.ADMINDB_LOG_LEVEL ?? env.LOG_LEVEL ?? 'info';
|
|
79
|
+
const serverlessRaw = env.ADMINDB_SERVERLESS ?? env.SERVERLESS ?? env.IS_SERVERLESS ?? '';
|
|
80
|
+
const serverless = ['1', 'true', 'yes', 'on'].includes(String(serverlessRaw).trim().toLowerCase()) ||
|
|
81
|
+
(0, serverless_1.isServerlessEnvironment)(env);
|
|
82
|
+
const readonlyRaw = env.ADMINDB_READONLY ?? env.READONLY ?? '';
|
|
83
|
+
const readonly = serverless || ['1', 'true', 'yes', 'on'].includes(String(readonlyRaw).trim().toLowerCase());
|
|
84
|
+
let connections;
|
|
85
|
+
const configJsonRaw = env.ADMINDB_CONFIG_JSON ?? env.ADMINDB_CONNECTIONS;
|
|
86
|
+
if (configJsonRaw) {
|
|
87
|
+
try {
|
|
88
|
+
const parsed = JSON.parse(configJsonRaw);
|
|
89
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))
|
|
90
|
+
connections = parsed;
|
|
91
|
+
}
|
|
92
|
+
catch { }
|
|
93
|
+
}
|
|
94
|
+
const configPath = env.ADMINDB_CONFIG;
|
|
95
|
+
if (configPath && (0, node_fs_1.existsSync)(configPath)) {
|
|
96
|
+
const fileConf = parseConfigFile(configPath);
|
|
97
|
+
if (fileConf?.connections) {
|
|
98
|
+
connections = { ...(connections ?? {}), ...fileConf.connections };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
host: env.ADMINDB_HOST ?? env.HOST ?? '0.0.0.0',
|
|
103
|
+
port: Number.isFinite(port) ? port : 45531,
|
|
104
|
+
dbPath: dbPathRaw ? String(dbPathRaw) : 'admindb.db',
|
|
105
|
+
connection: connectionRaw ? String(connectionRaw) : undefined,
|
|
106
|
+
connections,
|
|
107
|
+
dbDir: dbDirRaw ? String(dbDirRaw) : undefined,
|
|
108
|
+
dbFiles: dbFilesRaw ? String(dbFilesRaw).split(',').map((s) => s.trim()).filter(Boolean) : undefined,
|
|
109
|
+
basePath: String(basePathRaw).replace(/\/+$/, ''),
|
|
110
|
+
logLevel: logLevelRaw,
|
|
111
|
+
readonly,
|
|
112
|
+
serverless,
|
|
113
|
+
auth: !authDisabled,
|
|
114
|
+
authUsername: (env.ADMINDB_USERNAME ?? env.ADMINDB_USER) ? String(env.ADMINDB_USERNAME ?? env.ADMINDB_USER).trim() : undefined,
|
|
115
|
+
authPassword: (env.ADMINDB_PASSWORD ?? env.ADMINDB_PASS) ? String(env.ADMINDB_PASSWORD ?? env.ADMINDB_PASS).trim() : undefined,
|
|
116
|
+
authSecret: (env.ADMINDB_SECRET ?? env.SESSION_SECRET) ? String(env.ADMINDB_SECRET ?? env.SESSION_SECRET).trim() : undefined,
|
|
117
|
+
};
|
|
118
|
+
}
|
package/dist/cli/index.js
CHANGED
|
@@ -1 +1,20 @@
|
|
|
1
|
-
|
|
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("./args"), exports);
|
|
18
|
+
__exportStar(require("../utils/colors"), exports);
|
|
19
|
+
__exportStar(require("./config"), exports);
|
|
20
|
+
__exportStar(require("./runner"), exports);
|