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.
Files changed (119) hide show
  1. package/README.md +368 -335
  2. package/dist/app.js +227 -1
  3. package/dist/auth/config.d.ts +1 -1
  4. package/dist/auth/config.js +109 -1
  5. package/dist/auth/crypto.js +98 -1
  6. package/dist/auth/index.js +21 -1
  7. package/dist/auth/middleware.js +78 -1
  8. package/dist/auth/routes.js +64 -1
  9. package/dist/auth/types.js +7 -1
  10. package/dist/cli/args.d.ts +1 -1
  11. package/dist/cli/args.js +309 -1
  12. package/dist/cli/config.js +118 -1
  13. package/dist/cli/index.js +20 -1
  14. package/dist/cli/runner.js +208 -1
  15. package/dist/cli.js +4 -1
  16. package/dist/data/chain.d.ts +1 -0
  17. package/dist/data/chain.js +130 -0
  18. package/dist/data/datasets.d.ts +1 -1
  19. package/dist/data/datasets.js +171 -1
  20. package/dist/data/detector.d.ts +1 -1
  21. package/dist/data/detector.js +535 -1
  22. package/dist/data/engine.d.ts +1 -1
  23. package/dist/data/engine.js +586 -1
  24. package/dist/data/index.d.ts +1 -1
  25. package/dist/data/index.js +30 -1
  26. package/dist/data/prng.d.ts +1 -0
  27. package/dist/data/prng.js +73 -0
  28. package/dist/data/registry.d.ts +1 -0
  29. package/dist/data/registry.js +805 -0
  30. package/dist/data/schema-graph.d.ts +1 -0
  31. package/dist/data/schema-graph.js +210 -0
  32. package/dist/data/strategies.d.ts +1 -1
  33. package/dist/data/strategies.js +100 -1
  34. package/dist/data/templates.d.ts +1 -0
  35. package/dist/data/templates.js +134 -0
  36. package/dist/data/types.d.ts +1 -1
  37. package/dist/data/types.js +5 -1
  38. package/dist/data/validator.d.ts +1 -0
  39. package/dist/data/validator.js +160 -0
  40. package/dist/db/database.d.ts +1 -1
  41. package/dist/db/database.js +472 -1
  42. package/dist/db/export.d.ts +1 -1
  43. package/dist/db/export.js +67 -1
  44. package/dist/db/filters.d.ts +1 -1
  45. package/dist/db/filters.js +119 -1
  46. package/dist/db/index.js +24 -1
  47. package/dist/db/introspection.js +164 -1
  48. package/dist/db/manager.js +327 -1
  49. package/dist/db/migrations.js +100 -1
  50. package/dist/db/postgres.d.ts +1 -1
  51. package/dist/db/postgres.js +687 -1
  52. package/dist/db/types.d.ts +1 -1
  53. package/dist/db/types.js +6 -1
  54. package/dist/index.d.ts +1 -1
  55. package/dist/index.js +52 -1
  56. package/dist/public/css/app.css +1 -1
  57. package/dist/public/js/api.js +1 -1
  58. package/dist/public/js/browse.js +1 -1
  59. package/dist/public/js/common.js +1 -0
  60. package/dist/public/js/databases.js +1 -1
  61. package/dist/public/js/designer.js +1 -1
  62. package/dist/public/js/forms.js +1 -1
  63. package/dist/public/js/home.js +1 -0
  64. package/dist/public/js/inspector.js +1 -1
  65. package/dist/public/js/query.js +1 -1
  66. package/dist/public/js/schema.js +1 -1
  67. package/dist/public/js/seed.js +1 -1
  68. package/dist/routes/api/erd.d.ts +1 -0
  69. package/dist/routes/api/erd.js +45 -0
  70. package/dist/routes/api/helpers.d.ts +1 -1
  71. package/dist/routes/api/helpers.js +213 -1
  72. package/dist/routes/api/import-export.js +82 -1
  73. package/dist/routes/api/index.js +48 -1
  74. package/dist/routes/api/query.js +74 -1
  75. package/dist/routes/api/rows.js +358 -1
  76. package/dist/routes/api/seed.js +167 -1
  77. package/dist/routes/api/tables.js +216 -1
  78. package/dist/routes/databases.js +210 -1
  79. package/dist/routes/index.js +19 -1
  80. package/dist/routes/pages.js +446 -1
  81. package/dist/serverless.js +149 -1
  82. package/dist/sql/classifier.js +24 -1
  83. package/dist/sql/error-analyzer.d.ts +1 -0
  84. package/dist/sql/error-analyzer.js +550 -0
  85. package/dist/sql/generator.d.ts +1 -1
  86. package/dist/sql/generator.js +245 -1
  87. package/dist/sql/index.js +18 -1
  88. package/dist/types/api.d.ts +1 -1
  89. package/dist/types/api.js +2 -1
  90. package/dist/utils/colors.js +54 -1
  91. package/dist/utils/common.d.ts +1 -1
  92. package/dist/utils/common.js +185 -1
  93. package/dist/utils/csv.d.ts +1 -1
  94. package/dist/utils/csv.js +61 -1
  95. package/dist/utils/datatype.js +167 -1
  96. package/dist/utils/icons.js +81 -1
  97. package/dist/utils/index.js +20 -1
  98. package/dist/utils/logger.js +36 -1
  99. package/dist/views/layouts/main.hbs +1 -74
  100. package/dist/views/pages/databases.hbs +1 -233
  101. package/dist/views/pages/designer.hbs +1 -89
  102. package/dist/views/pages/erd.hbs +1 -0
  103. package/dist/views/pages/error.hbs +1 -10
  104. package/dist/views/pages/form.hbs +1 -59
  105. package/dist/views/pages/home.hbs +1 -124
  106. package/dist/views/pages/info.hbs +1 -0
  107. package/dist/views/pages/login.hbs +1 -98
  108. package/dist/views/pages/query.hbs +1 -87
  109. package/dist/views/pages/schema.hbs +1 -298
  110. package/dist/views/pages/seed-select.hbs +251 -0
  111. package/dist/views/pages/seed.hbs +273 -167
  112. package/dist/views/pages/table.hbs +1 -327
  113. package/dist/views/partials/navbar.hbs +1 -83
  114. package/dist/views/partials/sidebar.hbs +1 -117
  115. package/docs/API.md +149 -144
  116. package/docs/EXAMPLES.md +579 -576
  117. package/docs/SECURITY.md +265 -265
  118. package/package.json +79 -78
  119. package/dist/public/js/icons.js +0 -1
@@ -1 +1,7 @@
1
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.SESSION_COOKIE_NAME=exports.DEFAULT_SESSION_DURATION_MS=exports.DEFAULT_PASSWORD_HASH=exports.DEFAULT_USERNAME=void 0,exports.DEFAULT_USERNAME="admin",exports.DEFAULT_PASSWORD_HASH="scrypt:d9f2e64b8a1c3d5e7f0a2b4c6e801357:cb3032b16f29c8d44f75c779f070c61c846b17eb333d07596ceb8470fc1b4c06cc720c08796ebc86937dab28a3ef580ced38a71c940fd4a169fd2e9cb9fa40e2",exports.DEFAULT_SESSION_DURATION_MS=6048e5,exports.SESSION_COOKIE_NAME="admindb_session";
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';
@@ -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 function getPackageVersion():string;export declare function versionText():string;export declare function parseArgs(argv:string[]):{args:CliArgs;error?:string;};
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
- var __importDefault=this&&this.__importDefault||function(mod){return mod&&mod.__esModule?mod:{default:mod}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.helpText=function(){return["AdminDB — browser-based SQLite & PostgreSQL administration tool.","","Usage:"," admindb [options] [path|connection_url|config.json]","","Starts a local server and opens a web UI where you can browse, select and","manage SQLite databases (.db / .sqlite / .sqlite3) and PostgreSQL databases.","",'With no path or options it runs in "manager" mode: the landing page lets',"you browse the filesystem and open any database file, or create new ones.","","Arguments:"," path Path to a database file, PostgreSQL connection URL, or"," JSON configuration file containing database credentials.","","Options & Environment Variables:"," -C, --config <file.json> Load database credentials & settings from a JSON file"," -p, --port <port> Port to listen on (default: 45531) [PORT / ADMINDB_PORT]"," -H, --host <host> Host/interface to bind (default: 0.0.0.0) [HOST / ADMINDB_HOST]"," -c, --connection, --pg <uri> Open a PostgreSQL database directly [DATABASE_URL / ADMINDB_CONNECTION]"," -o, --open, --db-path <file> Open a single database file directly [DB_PATH / ADMINDB_DB_PATH]"," -d, --dir, --db-dir <dir> Folder of database files to manage [DB_DIR / ADMINDB_DB_DIR]"," --files, --db-files <list> Comma-separated database file paths [DB_FILES / ADMINDB_DB_FILES]"," -b, --base-path, --base <p> URL prefix to serve under (default: /) [BASE_PATH / ADMINDB_BASE_PATH]"," -r, --readonly, --read-only Open databases read-only (writes disabled) [READONLY / ADMINDB_READONLY]"," --serverless Enable serverless mode (enforces read-only, disables writes) [SERVERLESS / ADMINDB_SERVERLESS]"," --auth Enable authentication (default: on) [ADMINDB_AUTH=true]"," --no-auth, --disable-auth Disable authentication completely [ADMINDB_NO_AUTH=1 / ADMINDB_AUTH=false]"," -u, --username, --user <user> Admin username (default: admin) [ADMINDB_USERNAME / ADMINDB_USER]"," -P, --password, --pass <pass> Admin password or hash [ADMINDB_PASSWORD / ADMINDB_PASS]"," --auth-secret <sec> Secret key used to sign session cookies [ADMINDB_SECRET / SESSION_SECRET]"," -l, --log-level <level> debug | info | warn | error (default: info) [LOG_LEVEL / ADMINDB_LOG_LEVEL]"," -h, --help Show this help message"," -v, --version Show version","","Examples:"," admindb name.postgres.json # load database connections from a JSON file"," admindb postgresql://user:pass@host:5432/db # open a PostgreSQL database directly"," admindb ./data/app.db # open a SQLite database file"," admindb --no-auth # run with authentication turned off"," admindb -C ./connections.json # run with JSON connections config","","See docs/EXAMPLES.md for full configuration reference and deployment recipes."].join("\n")},exports.getPackageVersion=function(){return packageVersion()},exports.versionText=function(){const v=packageVersion();return v?`admindb v${v}`:"admindb"},exports.parseArgs=function(argv){const args={help:!1,version:!1,readonly:!1},positional=[];let i=0;const invalid=error=>({args:args,error:error}),takeValue=flag=>{const eq=argv[i].indexOf("=");return-1!==eq?argv[i].slice(eq+1):(i+=1,argv[i])};for(;i<argv.length;){const tok=argv[i];if("-h"===tok||"--help"===tok)args.help=!0;else if("-v"===tok||"--version"===tok)args.version=!0;else if(isFlag(tok,"-C","--config","--json")){const v=takeValue();if(void 0===v)return invalid("Missing value for --config.");args.configPath=v;try{const fileConf=(0,config_1.parseConfigFile)(v);fileConf&&(fileConf.connections&&(args.connections=fileConf.connections),fileConf.connection&&(args.connection=fileConf.connection),void 0!==fileConf.port&&(args.port=fileConf.port),void 0!==fileConf.host&&(args.host=fileConf.host),void 0!==fileConf.basePath&&(args.basePath=fileConf.basePath),void 0!==fileConf.readonly&&(args.readonly=fileConf.readonly),void 0!==fileConf.serverless&&(args.serverless=fileConf.serverless),void 0!==fileConf.logLevel&&(args.logLevel=fileConf.logLevel),"boolean"==typeof fileConf.auth?args.auth=fileConf.auth:fileConf.auth&&"object"==typeof fileConf.auth&&(args.auth=!0,fileConf.auth.username&&(args.authUsername=fileConf.auth.username),fileConf.auth.password&&(args.authPassword=fileConf.auth.password),fileConf.auth.secret&&(args.authSecret=fileConf.auth.secret)))}catch(err){return invalid(err.message)}}else if(isFlag(tok,"-p","--port")){const v=takeValue();if(void 0===v)return invalid("Missing value for --port.");const n=Number.parseInt(v,10);if(!Number.isFinite(n)||n<=0)return invalid(`Invalid port: "${v}".`);args.port=n}else if(isFlag(tok,"-H","--host")){const v=takeValue();if(void 0===v)return invalid("Missing value for --host.");args.host=v}else if(isFlag(tok,"-c","--connection","--conn","--pg")){const v=takeValue();if(void 0===v)return invalid("Missing value for --connection.");args.connection=v,args.dbPath=v}else if(isFlag(tok,"-o","--open","--db","-f","--file","--db-path","--path")){const v=takeValue();if(void 0===v)return invalid("Missing value for --open / --db-path.");args.dbPath=v,(v.startsWith("postgres://")||v.startsWith("postgresql://"))&&(args.connection=v)}else if(isFlag(tok,"-d","--dir","--folder","--db-dir")){const v=takeValue();if(void 0===v)return invalid("Missing value for --dir / --db-dir.");args.dbDir=v}else if(isFlag(tok,"--files","--db-files")){const v=takeValue();if(void 0===v)return invalid("Missing value for --files / --db-files.");args.dbFiles=v.split(",").map(s=>s.trim()).filter(Boolean)}else if(isFlag(tok,"-b","--base-path","--base")){const v=takeValue();if(void 0===v)return invalid("Missing value for --base-path.");args.basePath=v}else if(isFlag(tok,"-l","--log-level")){const v=takeValue();if(void 0===v)return invalid("Missing value for --log-level.");if(!LOG_LEVELS.includes(v))return invalid(`Invalid log level: "${v}". Expected one of: ${LOG_LEVELS.join(", ")}.`);args.logLevel=v}else if("-r"===tok||"--readonly"===tok||"--read-only"===tok)args.readonly=!0;else if("--serverless"===tok)args.serverless=!0,args.readonly=!0;else if("--no-auth"===tok||"--disable-auth"===tok)args.auth=!1;else if("--auth"===tok)args.auth=!0;else if(isFlag(tok,"-u","--username","--user","--auth-username")){const v=takeValue();if(void 0===v)return invalid("Missing value for --username.");args.authUsername=v}else if(isFlag(tok,"-P","--password","--pass","--auth-password")){const v=takeValue();if(void 0===v)return invalid("Missing value for --password.");args.authPassword=v}else if(isFlag(tok,"--auth-secret","--secret","--session-secret")){const v=takeValue();if(void 0===v)return invalid("Missing value for --auth-secret.");args.authSecret=v}else{if(tok.startsWith("-")&&tok.length>1)return invalid(`Unknown option: "${tok}".`);positional.push(tok)}i+=1}if(positional.length>1)return invalid(`Unexpected extra arguments: ${positional.slice(1).join(" ")}.`);const p=positional[0];if(p)if(p.startsWith("postgres://")||p.startsWith("postgresql://"))args.connection=p,args.dbPath=p;else if(p.endsWith(".json")||(0,node_fs_1.existsSync)(p))try{if(p.endsWith(".json")||(0,node_fs_1.statSync)(p).isFile()&&p.includes(".json")){args.configPath=p;const fileConf=(0,config_1.parseConfigFile)(p);fileConf&&(fileConf.connections&&(args.connections=fileConf.connections),fileConf.connection&&(args.connection=fileConf.connection),void 0!==fileConf.port&&void 0===args.port&&(args.port=fileConf.port),void 0!==fileConf.host&&void 0===args.host&&(args.host=fileConf.host),void 0!==fileConf.basePath&&void 0===args.basePath&&(args.basePath=fileConf.basePath),void 0!==fileConf.readonly&&(args.readonly=fileConf.readonly),void 0!==fileConf.serverless&&(args.serverless=fileConf.serverless),void 0!==fileConf.logLevel&&void 0===args.logLevel&&(args.logLevel=fileConf.logLevel),void 0===args.auth&&("boolean"==typeof fileConf.auth?args.auth=fileConf.auth:fileConf.auth&&"object"==typeof fileConf.auth&&(args.auth=!0,fileConf.auth.username&&!args.authUsername&&(args.authUsername=fileConf.auth.username),fileConf.auth.password&&!args.authPassword&&(args.authPassword=fileConf.auth.password),fileConf.auth.secret&&!args.authSecret&&(args.authSecret=fileConf.auth.secret))))}else(0,node_fs_1.statSync)(p).isDirectory()?args.dbDir=p:args.dbPath=p}catch(err){if(p.endsWith(".json"))return invalid(err.message);args.dbPath=p}else args.dbPath=p;return{args:args}};const node_fs_1=require("node:fs"),node_path_1=__importDefault(require("node:path")),config_1=require("./config"),LOG_LEVELS=["debug","info","warn","error"];function packageVersion(){try{const candidates=[node_path_1.default.join(__dirname,"..","..","package.json"),node_path_1.default.join(__dirname,"..","package.json"),node_path_1.default.join(__dirname,"package.json")];for(const p of candidates)if((0,node_fs_1.existsSync)(p)){const raw=(0,node_fs_1.readFileSync)(p,"utf8"),pkg=JSON.parse(raw);if(pkg.version)return pkg.version}return""}catch{return""}}function isFlag(tok,...names){return names.includes(tok)||names.some(n=>n.length>2&&tok.startsWith(n+"="))}
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
+ }
@@ -1 +1,118 @@
1
- var __importDefault=this&&this.__importDefault||function(mod){return mod&&mod.__esModule?mod:{default:mod}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseConfigFile=parseConfigFile,exports.loadConfig=function(env=process.env){const portRaw=env.ADMINDB_PORT??env.PORT??"45531",port=Number.parseInt(portRaw,10),authDisabled=["0","false","no","off"].includes(String(env.ADMINDB_AUTH??"").trim().toLowerCase())||["1","true","yes"].includes(String(env.ADMINDB_NO_AUTH??env.ADMINDB_DISABLE_AUTH??"").trim().toLowerCase()),dbDirRaw=env.ADMINDB_DB_DIR??env.ADMINDB_DIR??env.DB_DIR,dbFilesRaw=env.ADMINDB_DB_FILES??env.DB_FILES,connectionRaw=env.ADMINDB_CONNECTION??env.DATABASE_URL??env.PG_CONNECTION??env.POSTGRES_URL,dbPathRaw=env.ADMINDB_DB_PATH??env.ADMINDB_PATH??env.DB_PATH??connectionRaw,basePathRaw=env.ADMINDB_BASE_PATH??env.BASE_PATH??"",logLevelRaw=env.ADMINDB_LOG_LEVEL??env.LOG_LEVEL??"info",serverlessRaw=env.ADMINDB_SERVERLESS??env.SERVERLESS??env.IS_SERVERLESS??"",serverless=["1","true","yes","on"].includes(String(serverlessRaw).trim().toLowerCase())||(0,serverless_1.isServerlessEnvironment)(env),readonlyRaw=env.ADMINDB_READONLY??env.READONLY??"",readonly=serverless||["1","true","yes","on"].includes(String(readonlyRaw).trim().toLowerCase());let connections;const configJsonRaw=env.ADMINDB_CONFIG_JSON??env.ADMINDB_CONNECTIONS;if(configJsonRaw)try{const parsed=JSON.parse(configJsonRaw);parsed&&"object"==typeof parsed&&!Array.isArray(parsed)&&(connections=parsed)}catch{}const configPath=env.ADMINDB_CONFIG;if(configPath&&(0,node_fs_1.existsSync)(configPath)){const fileConf=parseConfigFile(configPath);fileConf?.connections&&(connections={...connections??{},...fileConf.connections})}return{host:env.ADMINDB_HOST??env.HOST??"0.0.0.0",port:Number.isFinite(port)?port:45531,dbPath:dbPathRaw?String(dbPathRaw):"admindb.db",connection:connectionRaw?String(connectionRaw):void 0,connections:connections,dbDir:dbDirRaw?String(dbDirRaw):void 0,dbFiles:dbFilesRaw?String(dbFilesRaw).split(",").map(s=>s.trim()).filter(Boolean):void 0,basePath:String(basePathRaw).replace(/\/+$/,""),logLevel:logLevelRaw,readonly:readonly,serverless:serverless,auth:!authDisabled,authUsername:env.ADMINDB_USERNAME??env.ADMINDB_USER?String(env.ADMINDB_USERNAME??env.ADMINDB_USER).trim():void 0,authPassword:env.ADMINDB_PASSWORD??env.ADMINDB_PASS?String(env.ADMINDB_PASSWORD??env.ADMINDB_PASS).trim():void 0,authSecret:env.ADMINDB_SECRET??env.SESSION_SECRET?String(env.ADMINDB_SECRET??env.SESSION_SECRET).trim():void 0}};const node_fs_1=require("node:fs"),node_path_1=__importDefault(require("node:path")),serverless_1=require("../serverless"),common_1=require("../utils/common");function parseConfigFile(filePath){try{const absPath=node_path_1.default.resolve(filePath);if(!(0,node_fs_1.existsSync)(absPath))return null;const content=(0,node_fs_1.readFileSync)(absPath,"utf8"),parsed=JSON.parse(content);if(!parsed||"object"!=typeof parsed||Array.isArray(parsed))return null;const result={},conns={},topDbs=parsed.databases||parsed.connections;if(topDbs&&"object"==typeof topDbs&&!Array.isArray(topDbs))for(const[k,v]of Object.entries(topDbs))"string"==typeof v&&v.trim()?conns[k.trim()]=v.trim():v&&"object"==typeof v&&"string"==typeof v.connection&&(conns[k.trim()]=v.connection.trim());for(const[k,v]of Object.entries(parsed))["databases","connections","port","host","basePath","readonly","serverless","auth","logLevel","username","password","secret"].includes(k)||("string"==typeof v&&v.trim()?conns[k.trim()]=v.trim():v&&"object"==typeof v&&"string"==typeof v.connection&&(conns[k.trim()]=v.connection.trim()));return"string"==typeof parsed.connection&&parsed.connection.trim()&&(result.connection=parsed.connection.trim()),"number"==typeof parsed.port&&(result.port=parsed.port),"string"==typeof parsed.host&&(result.host=parsed.host),"string"==typeof parsed.basePath&&(result.basePath=parsed.basePath),"boolean"==typeof parsed.readonly&&(result.readonly=parsed.readonly),"boolean"==typeof parsed.serverless&&(result.serverless=parsed.serverless),("boolean"==typeof parsed.auth||parsed.auth&&"object"==typeof parsed.auth)&&(result.auth=parsed.auth),"string"==typeof parsed.logLevel&&(result.logLevel=parsed.logLevel),Object.keys(conns).length>0&&(result.connections=conns),result}catch(err){throw new Error(`Failed to parse configuration file "${filePath}": ${(0,common_1.errorMessage)(err)}`)}}
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
- var __createBinding=this&&this.__createBinding||(Object.create?function(o,m,k,k2){void 0===k2&&(k2=k);var desc=Object.getOwnPropertyDescriptor(m,k);desc&&!("get"in desc?!m.__esModule:desc.writable||desc.configurable)||(desc={enumerable:!0,get:function(){return m[k]}}),Object.defineProperty(o,k2,desc)}:function(o,m,k,k2){void 0===k2&&(k2=k),o[k2]=m[k]}),__exportStar=this&&this.__exportStar||function(m,exports){for(var p in m)"default"===p||Object.prototype.hasOwnProperty.call(exports,p)||__createBinding(exports,m,p)};Object.defineProperty(exports,"__esModule",{value:!0}),__exportStar(require("./args"),exports),__exportStar(require("../utils/colors"),exports),__exportStar(require("./config"),exports),__exportStar(require("./runner"),exports);
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);