@carllee1983/dbcli 1.1.0 → 1.2.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/CHANGELOG.md +23 -0
- package/README.md +240 -49
- package/README.zh-TW.md +951 -338
- package/assets/SKILL.md +33 -5
- package/dist/cli.mjs +481 -35
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -6105,7 +6105,9 @@ var exports_validation = {};
|
|
|
6105
6105
|
__export(exports_validation, {
|
|
6106
6106
|
validateFormat: () => validateFormat,
|
|
6107
6107
|
PermissionSchema: () => PermissionSchema,
|
|
6108
|
+
NamedConnectionSchema: () => NamedConnectionSchema,
|
|
6108
6109
|
MetadataSchema: () => MetadataSchema,
|
|
6110
|
+
DbcliConfigV2Schema: () => DbcliConfigV2Schema,
|
|
6109
6111
|
DbcliConfigSchema: () => DbcliConfigSchema,
|
|
6110
6112
|
ConnectionConfigSchema: () => ConnectionConfigSchema,
|
|
6111
6113
|
BlacklistConfigSchema: () => BlacklistConfigSchema
|
|
@@ -6116,7 +6118,7 @@ function validateFormat(value, allowedFormats, commandName) {
|
|
|
6116
6118
|
throw new Error(`Invalid format "${value}" for ${commandName}. Allowed: ${allowed}`);
|
|
6117
6119
|
}
|
|
6118
6120
|
}
|
|
6119
|
-
var EnvRefSchema, StringOrEnvRef, NumberOrEnvRef, ConnectionConfigSchema, PermissionSchema, MetadataSchema, BlacklistConfigSchema, DbcliConfigSchema;
|
|
6121
|
+
var EnvRefSchema, StringOrEnvRef, NumberOrEnvRef, ConnectionConfigSchema, PermissionSchema, MetadataSchema, BlacklistConfigSchema, DbcliConfigSchema, NamedConnectionSchema, DbcliConfigV2Schema;
|
|
6120
6122
|
var init_validation = __esm(() => {
|
|
6121
6123
|
init_zod();
|
|
6122
6124
|
EnvRefSchema = exports_external.object({
|
|
@@ -6154,6 +6156,18 @@ var init_validation = __esm(() => {
|
|
|
6154
6156
|
metadata: MetadataSchema,
|
|
6155
6157
|
blacklist: BlacklistConfigSchema
|
|
6156
6158
|
});
|
|
6159
|
+
NamedConnectionSchema = ConnectionConfigSchema.extend({
|
|
6160
|
+
permission: PermissionSchema,
|
|
6161
|
+
envFile: exports_external.string().optional()
|
|
6162
|
+
});
|
|
6163
|
+
DbcliConfigV2Schema = exports_external.object({
|
|
6164
|
+
version: exports_external.literal(2),
|
|
6165
|
+
default: exports_external.string().min(1),
|
|
6166
|
+
connections: exports_external.record(NamedConnectionSchema).refine((conns) => Object.keys(conns).length > 0, { message: "At least one connection is required" }),
|
|
6167
|
+
schema: exports_external.record(exports_external.any()).optional().default({}),
|
|
6168
|
+
metadata: MetadataSchema,
|
|
6169
|
+
blacklist: BlacklistConfigSchema
|
|
6170
|
+
}).refine((config) => (config.default in config.connections), { message: "Default connection must exist in connections", path: ["default"] });
|
|
6157
6171
|
});
|
|
6158
6172
|
|
|
6159
6173
|
// node_modules/@inquirer/core/dist/esm/lib/key.mjs
|
|
@@ -42998,7 +43012,7 @@ var require_named_placeholders = __commonJS((exports, module) => {
|
|
|
42998
43012
|
}
|
|
42999
43013
|
return s;
|
|
43000
43014
|
}
|
|
43001
|
-
function
|
|
43015
|
+
function join3(tree) {
|
|
43002
43016
|
if (tree.length === 1) {
|
|
43003
43017
|
return tree;
|
|
43004
43018
|
}
|
|
@@ -43024,7 +43038,7 @@ var require_named_placeholders = __commonJS((exports, module) => {
|
|
|
43024
43038
|
if (cache && (tree = cache.get(query))) {
|
|
43025
43039
|
return toArrayParams(tree, paramsObj);
|
|
43026
43040
|
}
|
|
43027
|
-
tree =
|
|
43041
|
+
tree = join3(parse(query));
|
|
43028
43042
|
if (cache) {
|
|
43029
43043
|
cache.set(query, tree);
|
|
43030
43044
|
}
|
|
@@ -46850,7 +46864,7 @@ var {
|
|
|
46850
46864
|
// package.json
|
|
46851
46865
|
var package_default = {
|
|
46852
46866
|
name: "@carllee1983/dbcli",
|
|
46853
|
-
version: "1.
|
|
46867
|
+
version: "1.2.0",
|
|
46854
46868
|
description: "Database CLI for AI agents",
|
|
46855
46869
|
type: "module",
|
|
46856
46870
|
publishConfig: {
|
|
@@ -46952,7 +46966,27 @@ var messages_default = {
|
|
|
46952
46966
|
skip_test_env_ref: "Skipping connection test in env-ref mode",
|
|
46953
46967
|
skip_test: "Skipping connection test (--skip-test)",
|
|
46954
46968
|
connection_hints: "Hints:",
|
|
46955
|
-
config_exists_use_force: ".dbcli exists. Use --force option to overwrite."
|
|
46969
|
+
config_exists_use_force: ".dbcli exists. Use --force option to overwrite.",
|
|
46970
|
+
connection_added: "Connection '{{name}}' added",
|
|
46971
|
+
connection_removed: "Connection '{{name}}' removed",
|
|
46972
|
+
connection_removed_switched: "Connection '{{name}}' removed. Default connection switched to '{{newDefault}}'",
|
|
46973
|
+
connection_renamed: "Connection '{{oldName}}' renamed to '{{newName}}'",
|
|
46974
|
+
v1_migration_prompt: "Detected old config format. Create new format and import existing connection as 'default'?",
|
|
46975
|
+
config_saved_v2: "V2 configuration saved to .dbcli",
|
|
46976
|
+
config_not_found: "Configuration file not found",
|
|
46977
|
+
requires_v2_remove: "Removing a connection requires V2 config format",
|
|
46978
|
+
requires_v2_rename: "Renaming a connection requires V2 config format",
|
|
46979
|
+
connection_not_found: "Connection '{{name}}' does not exist",
|
|
46980
|
+
cannot_remove_last: "Cannot remove the last connection",
|
|
46981
|
+
connection_already_exists: "Connection '{{name}}' already exists",
|
|
46982
|
+
rename_invalid_format: "Usage: --rename <old-name>:<new-name>"
|
|
46983
|
+
},
|
|
46984
|
+
use: {
|
|
46985
|
+
description: "Switch or display the default database connection",
|
|
46986
|
+
switched: "Switched default connection to {{name}}",
|
|
46987
|
+
current: "Current default connection: {{name}}",
|
|
46988
|
+
requires_v2: "This feature requires v2 config format. Use 'dbcli init --conn-name <name>' to create one",
|
|
46989
|
+
available: "Available connections"
|
|
46956
46990
|
},
|
|
46957
46991
|
schema: {
|
|
46958
46992
|
description: "Retrieve table structure or list all tables",
|
|
@@ -47104,7 +47138,27 @@ var messages_default2 = {
|
|
|
47104
47138
|
skip_test_env_ref: "\u8DF3\u904E\u9023\u7DDA\u6E2C\u8A66\uFF08\u74B0\u5883\u8B8A\u6578\u53C3\u7167\u6A21\u5F0F\uFF09",
|
|
47105
47139
|
skip_test: "\u8DF3\u904E\u9023\u7DDA\u6E2C\u8A66\uFF08--skip-test\uFF09",
|
|
47106
47140
|
connection_hints: "\u63D0\u793A\uFF1A",
|
|
47107
|
-
config_exists_use_force: ".dbcli \u5DF2\u5B58\u5728\u3002\u4F7F\u7528 --force \u9078\u9805\u8986\u84CB\u3002"
|
|
47141
|
+
config_exists_use_force: ".dbcli \u5DF2\u5B58\u5728\u3002\u4F7F\u7528 --force \u9078\u9805\u8986\u84CB\u3002",
|
|
47142
|
+
connection_added: "\u5DF2\u65B0\u589E\u9023\u7DDA '{{name}}'",
|
|
47143
|
+
connection_removed: "\u5DF2\u79FB\u9664\u9023\u7DDA '{{name}}'",
|
|
47144
|
+
connection_removed_switched: "\u5DF2\u79FB\u9664\u9023\u7DDA '{{name}}'\uFF0C\u9810\u8A2D\u9023\u7DDA\u5DF2\u5207\u63DB\u70BA '{{newDefault}}'",
|
|
47145
|
+
connection_renamed: "\u5DF2\u5C07\u9023\u7DDA '{{oldName}}' \u91CD\u65B0\u547D\u540D\u70BA '{{newName}}'",
|
|
47146
|
+
v1_migration_prompt: "\u5075\u6E2C\u5230\u820A\u683C\u5F0F\u8A2D\u5B9A\uFF0C\u5C07\u5EFA\u7ACB\u65B0\u683C\u5F0F\u4E26\u5C07\u73FE\u6709\u9023\u7DDA\u532F\u5165\u70BA 'default'\uFF0C\u662F\u5426\u7E7C\u7E8C\uFF1F",
|
|
47147
|
+
config_saved_v2: "V2 \u8A2D\u5B9A\u5DF2\u5132\u5B58\u81F3 .dbcli",
|
|
47148
|
+
config_not_found: "\u627E\u4E0D\u5230\u8A2D\u5B9A\u6A94",
|
|
47149
|
+
requires_v2_remove: "\u79FB\u9664\u9023\u7DDA\u9700\u8981 V2 \u683C\u5F0F\u8A2D\u5B9A",
|
|
47150
|
+
requires_v2_rename: "\u91CD\u65B0\u547D\u540D\u9023\u7DDA\u9700\u8981 V2 \u683C\u5F0F\u8A2D\u5B9A",
|
|
47151
|
+
connection_not_found: "\u9023\u7DDA '{{name}}' \u4E0D\u5B58\u5728",
|
|
47152
|
+
cannot_remove_last: "\u7121\u6CD5\u79FB\u9664\u6700\u5F8C\u4E00\u500B\u9023\u7DDA",
|
|
47153
|
+
connection_already_exists: "\u9023\u7DDA '{{name}}' \u5DF2\u5B58\u5728",
|
|
47154
|
+
rename_invalid_format: "\u7528\u6CD5\uFF1A--rename <\u820A\u540D\u7A31>:<\u65B0\u540D\u7A31>"
|
|
47155
|
+
},
|
|
47156
|
+
use: {
|
|
47157
|
+
description: "\u5207\u63DB\u6216\u986F\u793A\u9810\u8A2D\u8CC7\u6599\u5EAB\u9023\u7DDA",
|
|
47158
|
+
switched: "\u5DF2\u5207\u63DB\u9810\u8A2D\u9023\u7DDA\u70BA {{name}}",
|
|
47159
|
+
current: "\u76EE\u524D\u9810\u8A2D\u9023\u7DDA\uFF1A{{name}}",
|
|
47160
|
+
requires_v2: "\u6B64\u529F\u80FD\u9700\u8981\u65B0\u683C\u5F0F\u8A2D\u5B9A\u3002\u8ACB\u4F7F\u7528 dbcli init --conn-name <\u540D\u7A31> \u5EFA\u7ACB\u591A\u9023\u7DDA\u8A2D\u5B9A",
|
|
47161
|
+
available: "\u53EF\u7528\u9023\u7DDA"
|
|
47108
47162
|
},
|
|
47109
47163
|
schema: {
|
|
47110
47164
|
description: "\u6AA2\u7D22\u8868\u683C\u7D50\u69CB\u6216\u5217\u51FA\u6240\u6709\u8868\u683C",
|
|
@@ -47389,6 +47443,9 @@ function getLogger() {
|
|
|
47389
47443
|
return globalLogger;
|
|
47390
47444
|
}
|
|
47391
47445
|
|
|
47446
|
+
// src/commands/init.ts
|
|
47447
|
+
import { join as join3 } from "path";
|
|
47448
|
+
|
|
47392
47449
|
// src/utils/errors.ts
|
|
47393
47450
|
class EnvParseError extends Error {
|
|
47394
47451
|
constructor(message) {
|
|
@@ -47490,7 +47547,97 @@ function parseEnvDatabase(env) {
|
|
|
47490
47547
|
|
|
47491
47548
|
// src/core/config.ts
|
|
47492
47549
|
init_validation();
|
|
47550
|
+
|
|
47551
|
+
// src/core/config-v2.ts
|
|
47552
|
+
init_validation();
|
|
47553
|
+
|
|
47554
|
+
// src/core/env-loader.ts
|
|
47555
|
+
function parseEnvContent(content) {
|
|
47556
|
+
const entries = [];
|
|
47557
|
+
for (const line of content.split(`
|
|
47558
|
+
`)) {
|
|
47559
|
+
const trimmed = line.trim();
|
|
47560
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
47561
|
+
continue;
|
|
47562
|
+
const eqIndex = trimmed.indexOf("=");
|
|
47563
|
+
if (eqIndex === -1)
|
|
47564
|
+
continue;
|
|
47565
|
+
const key = trimmed.slice(0, eqIndex).trim();
|
|
47566
|
+
let value = trimmed.slice(eqIndex + 1);
|
|
47567
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
47568
|
+
value = value.slice(1, -1);
|
|
47569
|
+
}
|
|
47570
|
+
entries.push([key, value]);
|
|
47571
|
+
}
|
|
47572
|
+
return entries;
|
|
47573
|
+
}
|
|
47574
|
+
async function loadEnvFile(filePath) {
|
|
47575
|
+
const file = Bun.file(filePath);
|
|
47576
|
+
const exists = await file.exists();
|
|
47577
|
+
if (!exists) {
|
|
47578
|
+
throw new ConfigError(`\u627E\u4E0D\u5230 env \u6A94\u6848\uFF1A${filePath}`);
|
|
47579
|
+
}
|
|
47580
|
+
const content = await file.text();
|
|
47581
|
+
const entries = parseEnvContent(content);
|
|
47582
|
+
for (const [key, value] of entries) {
|
|
47583
|
+
if (process.env[key] === undefined) {
|
|
47584
|
+
process.env[key] = value;
|
|
47585
|
+
}
|
|
47586
|
+
}
|
|
47587
|
+
}
|
|
47588
|
+
|
|
47589
|
+
// src/core/config-v2.ts
|
|
47493
47590
|
import { join } from "path";
|
|
47591
|
+
function detectConfigVersion(raw) {
|
|
47592
|
+
if (typeof raw === "object" && raw !== null && "version" in raw && raw.version === 2 && "connections" in raw) {
|
|
47593
|
+
return 2;
|
|
47594
|
+
}
|
|
47595
|
+
return 1;
|
|
47596
|
+
}
|
|
47597
|
+
function resolveConnection(config, name) {
|
|
47598
|
+
const connectionName = name ?? config.default;
|
|
47599
|
+
const conn = config.connections[connectionName];
|
|
47600
|
+
if (!conn) {
|
|
47601
|
+
const available = Object.keys(config.connections).join(", ");
|
|
47602
|
+
throw new ConfigError(`\u9023\u7DDA '${connectionName}' \u4E0D\u5B58\u5728\u3002\u53EF\u7528\u9023\u7DDA\uFF1A${available}`);
|
|
47603
|
+
}
|
|
47604
|
+
const { permission, envFile, ...connectionFields } = conn;
|
|
47605
|
+
return {
|
|
47606
|
+
name: connectionName,
|
|
47607
|
+
connection: connectionFields,
|
|
47608
|
+
permission,
|
|
47609
|
+
envFile
|
|
47610
|
+
};
|
|
47611
|
+
}
|
|
47612
|
+
async function loadConnectionEnv(resolved, basePath) {
|
|
47613
|
+
if (resolved.envFile) {
|
|
47614
|
+
const envPath = join(basePath, "..", resolved.envFile);
|
|
47615
|
+
await loadEnvFile(envPath);
|
|
47616
|
+
}
|
|
47617
|
+
}
|
|
47618
|
+
async function readV2Config(path) {
|
|
47619
|
+
const configPath = join(path, "config.json");
|
|
47620
|
+
const file = Bun.file(configPath);
|
|
47621
|
+
if (!await file.exists()) {
|
|
47622
|
+
throw new ConfigError(`\u627E\u4E0D\u5230 V2 \u8A2D\u5B9A\u6A94\uFF1A${configPath}`);
|
|
47623
|
+
}
|
|
47624
|
+
const content = await file.text();
|
|
47625
|
+
const raw = JSON.parse(content);
|
|
47626
|
+
return DbcliConfigV2Schema.parse(raw);
|
|
47627
|
+
}
|
|
47628
|
+
async function writeV2Config(path, config) {
|
|
47629
|
+
DbcliConfigV2Schema.parse(config);
|
|
47630
|
+
const configPath = join(path, "config.json");
|
|
47631
|
+
const json = JSON.stringify(config, null, 2);
|
|
47632
|
+
await Bun.write(configPath, json);
|
|
47633
|
+
}
|
|
47634
|
+
|
|
47635
|
+
// src/core/config.ts
|
|
47636
|
+
import { join as join2 } from "path";
|
|
47637
|
+
var _globalConnectionName;
|
|
47638
|
+
function setGlobalConnectionName(name) {
|
|
47639
|
+
_globalConnectionName = name;
|
|
47640
|
+
}
|
|
47494
47641
|
var DEFAULT_CONFIG = {
|
|
47495
47642
|
connection: {
|
|
47496
47643
|
system: "postgresql",
|
|
@@ -47547,7 +47694,8 @@ function parseEnvPassword(content) {
|
|
|
47547
47694
|
return match ? match[1].trim() : null;
|
|
47548
47695
|
}
|
|
47549
47696
|
var configModule = {
|
|
47550
|
-
async read(path) {
|
|
47697
|
+
async read(path, connectionName) {
|
|
47698
|
+
const effectiveConnectionName = connectionName ?? _globalConnectionName;
|
|
47551
47699
|
try {
|
|
47552
47700
|
let isDirectory = false;
|
|
47553
47701
|
try {
|
|
@@ -47557,14 +47705,40 @@ var configModule = {
|
|
|
47557
47705
|
isDirectory = false;
|
|
47558
47706
|
}
|
|
47559
47707
|
if (isDirectory) {
|
|
47560
|
-
const configPath =
|
|
47708
|
+
const configPath = join2(path, "config.json");
|
|
47561
47709
|
const configFile = Bun.file(configPath);
|
|
47562
47710
|
const configExists = await configFile.exists();
|
|
47563
47711
|
if (configExists) {
|
|
47564
47712
|
const content = await configFile.text();
|
|
47565
47713
|
const config = JSON.parse(content);
|
|
47714
|
+
if (detectConfigVersion(config) === 2) {
|
|
47715
|
+
const v2Config = DbcliConfigV2Schema.parse(config);
|
|
47716
|
+
const resolved = resolveConnection(v2Config, effectiveConnectionName);
|
|
47717
|
+
await loadConnectionEnv(resolved, configPath);
|
|
47718
|
+
const envLocalPath = join2(path, ".env.local");
|
|
47719
|
+
const envLocalFile = Bun.file(envLocalPath);
|
|
47720
|
+
let legacyPassword = null;
|
|
47721
|
+
if (await envLocalFile.exists()) {
|
|
47722
|
+
const envContent = await envLocalFile.text();
|
|
47723
|
+
legacyPassword = parseEnvPassword(envContent);
|
|
47724
|
+
if (legacyPassword && !process.env.DBCLI_PASSWORD) {
|
|
47725
|
+
process.env.DBCLI_PASSWORD = legacyPassword;
|
|
47726
|
+
}
|
|
47727
|
+
}
|
|
47728
|
+
const resolvedConnection = resolveEnvReferences(resolved.connection, process.env, undefined, false);
|
|
47729
|
+
if (!resolvedConnection.password && legacyPassword) {
|
|
47730
|
+
resolvedConnection.password = legacyPassword;
|
|
47731
|
+
}
|
|
47732
|
+
return DbcliConfigSchema.parse({
|
|
47733
|
+
connection: resolvedConnection,
|
|
47734
|
+
permission: resolved.permission,
|
|
47735
|
+
schema: v2Config.schema,
|
|
47736
|
+
metadata: v2Config.metadata,
|
|
47737
|
+
blacklist: v2Config.blacklist
|
|
47738
|
+
});
|
|
47739
|
+
}
|
|
47566
47740
|
const resolvedConfig = resolveEnvReferences(config, process.env, undefined, false);
|
|
47567
|
-
const envPath =
|
|
47741
|
+
const envPath = join2(path, ".env.local");
|
|
47568
47742
|
const envFile = Bun.file(envPath);
|
|
47569
47743
|
if (await envFile.exists()) {
|
|
47570
47744
|
const envContent = await envFile.text();
|
|
@@ -47586,6 +47760,8 @@ var configModule = {
|
|
|
47586
47760
|
}
|
|
47587
47761
|
return { ...DEFAULT_CONFIG };
|
|
47588
47762
|
} catch (error) {
|
|
47763
|
+
if (error instanceof ConfigError)
|
|
47764
|
+
throw error;
|
|
47589
47765
|
if (error instanceof Error && error.message.includes("JSON")) {
|
|
47590
47766
|
throw new ConfigError(`Failed to parse .dbcli file: ${error.message}`);
|
|
47591
47767
|
}
|
|
@@ -47629,7 +47805,7 @@ var configModule = {
|
|
|
47629
47805
|
if (isDirectory || path.endsWith(".dbcli")) {
|
|
47630
47806
|
const hasEnvReferences = isEnvReference(config.connection.password);
|
|
47631
47807
|
if (hasEnvReferences) {
|
|
47632
|
-
const configPath =
|
|
47808
|
+
const configPath = join2(path, "config.json");
|
|
47633
47809
|
const configJson = JSON.stringify(config, null, 2);
|
|
47634
47810
|
await Bun.file(configPath).write(configJson);
|
|
47635
47811
|
} else {
|
|
@@ -47642,11 +47818,11 @@ var configModule = {
|
|
|
47642
47818
|
}
|
|
47643
47819
|
};
|
|
47644
47820
|
delete configWithoutPassword.connection.password;
|
|
47645
|
-
const configPath =
|
|
47821
|
+
const configPath = join2(path, "config.json");
|
|
47646
47822
|
const configJson = JSON.stringify(configWithoutPassword, null, 2);
|
|
47647
47823
|
await Bun.file(configPath).write(configJson);
|
|
47648
47824
|
if (password) {
|
|
47649
|
-
const envPath =
|
|
47825
|
+
const envPath = join2(path, ".env.local");
|
|
47650
47826
|
const envContent = `# Database Credentials - DO NOT commit to git
|
|
47651
47827
|
|
|
47652
47828
|
DBCLI_PASSWORD=${password}
|
|
@@ -48440,10 +48616,10 @@ class AdapterFactory {
|
|
|
48440
48616
|
}
|
|
48441
48617
|
// src/commands/init.ts
|
|
48442
48618
|
var VALID_PERMISSIONS = ["query-only", "read-write", "data-admin", "admin"];
|
|
48443
|
-
async function checkOverwrite(shouldPrompt, force) {
|
|
48444
|
-
const
|
|
48445
|
-
const
|
|
48446
|
-
if (!fileExists || force)
|
|
48619
|
+
async function checkOverwrite(configPath, shouldPrompt, force) {
|
|
48620
|
+
const fileExists = await Bun.file(configPath).exists();
|
|
48621
|
+
const dirConfigExists = await Bun.file(join3(configPath, "config.json")).exists();
|
|
48622
|
+
if (!fileExists && !dirConfigExists || force)
|
|
48447
48623
|
return true;
|
|
48448
48624
|
if (shouldPrompt) {
|
|
48449
48625
|
const overwrite = await promptUser.confirm(t("init.config_exists_overwrite"));
|
|
@@ -48455,7 +48631,140 @@ async function checkOverwrite(shouldPrompt, force) {
|
|
|
48455
48631
|
}
|
|
48456
48632
|
throw new Error(t("init.config_exists_use_force"));
|
|
48457
48633
|
}
|
|
48458
|
-
|
|
48634
|
+
async function handleRemove(configPath, name) {
|
|
48635
|
+
const configFile = Bun.file(join3(configPath, "config.json"));
|
|
48636
|
+
if (!await configFile.exists()) {
|
|
48637
|
+
throw new Error(t("init.config_not_found"));
|
|
48638
|
+
}
|
|
48639
|
+
const raw = JSON.parse(await configFile.text());
|
|
48640
|
+
if (detectConfigVersion(raw) !== 2) {
|
|
48641
|
+
throw new Error(t("init.requires_v2_remove"));
|
|
48642
|
+
}
|
|
48643
|
+
const config = await readV2Config(configPath);
|
|
48644
|
+
if (!config.connections[name]) {
|
|
48645
|
+
throw new Error(t_vars("init.connection_not_found", { name }));
|
|
48646
|
+
}
|
|
48647
|
+
const connectionCount = Object.keys(config.connections).length;
|
|
48648
|
+
if (connectionCount <= 1) {
|
|
48649
|
+
throw new Error(t("init.cannot_remove_last"));
|
|
48650
|
+
}
|
|
48651
|
+
const { [name]: _removed, ...remaining } = config.connections;
|
|
48652
|
+
const newDefault = config.default === name ? Object.keys(remaining)[0] : config.default;
|
|
48653
|
+
const updated = {
|
|
48654
|
+
...config,
|
|
48655
|
+
default: newDefault,
|
|
48656
|
+
connections: remaining
|
|
48657
|
+
};
|
|
48658
|
+
await writeV2Config(configPath, updated);
|
|
48659
|
+
if (config.default === name) {
|
|
48660
|
+
console.log(t_vars("init.connection_removed_switched", { name, newDefault }));
|
|
48661
|
+
} else {
|
|
48662
|
+
console.log(t_vars("init.connection_removed", { name }));
|
|
48663
|
+
}
|
|
48664
|
+
}
|
|
48665
|
+
async function handleRename(configPath, renameArg) {
|
|
48666
|
+
const [oldName, newName] = renameArg.split(":");
|
|
48667
|
+
if (!oldName || !newName) {
|
|
48668
|
+
throw new Error(t("init.rename_invalid_format"));
|
|
48669
|
+
}
|
|
48670
|
+
const configFile = Bun.file(join3(configPath, "config.json"));
|
|
48671
|
+
if (!await configFile.exists()) {
|
|
48672
|
+
throw new Error(t("init.config_not_found"));
|
|
48673
|
+
}
|
|
48674
|
+
const raw = JSON.parse(await configFile.text());
|
|
48675
|
+
if (detectConfigVersion(raw) !== 2) {
|
|
48676
|
+
throw new Error(t("init.requires_v2_rename"));
|
|
48677
|
+
}
|
|
48678
|
+
const config = await readV2Config(configPath);
|
|
48679
|
+
if (!config.connections[oldName]) {
|
|
48680
|
+
throw new Error(t_vars("init.connection_not_found", { name: oldName }));
|
|
48681
|
+
}
|
|
48682
|
+
if (config.connections[newName]) {
|
|
48683
|
+
throw new Error(t_vars("init.connection_already_exists", { name: newName }));
|
|
48684
|
+
}
|
|
48685
|
+
const entries = Object.entries(config.connections).map(([key2, value]) => [key2 === oldName ? newName : key2, value]);
|
|
48686
|
+
const updated = {
|
|
48687
|
+
...config,
|
|
48688
|
+
default: config.default === oldName ? newName : config.default,
|
|
48689
|
+
connections: Object.fromEntries(entries)
|
|
48690
|
+
};
|
|
48691
|
+
await writeV2Config(configPath, updated);
|
|
48692
|
+
console.log(t_vars("init.connection_renamed", { oldName, newName }));
|
|
48693
|
+
}
|
|
48694
|
+
async function writeV2InitConfig(configPath, connectionName, connection, permission, envFile) {
|
|
48695
|
+
const configJsonPath = join3(configPath, "config.json");
|
|
48696
|
+
const configFile = Bun.file(configJsonPath);
|
|
48697
|
+
let existingV2 = null;
|
|
48698
|
+
if (await configFile.exists()) {
|
|
48699
|
+
const raw = JSON.parse(await configFile.text());
|
|
48700
|
+
if (detectConfigVersion(raw) === 2) {
|
|
48701
|
+
existingV2 = await readV2Config(configPath);
|
|
48702
|
+
} else {
|
|
48703
|
+
const v1Config = await configModule.read(configPath);
|
|
48704
|
+
existingV2 = {
|
|
48705
|
+
version: 2,
|
|
48706
|
+
default: "default",
|
|
48707
|
+
connections: {
|
|
48708
|
+
default: {
|
|
48709
|
+
...v1Config.connection,
|
|
48710
|
+
permission: v1Config.permission
|
|
48711
|
+
}
|
|
48712
|
+
},
|
|
48713
|
+
schema: v1Config.schema || {},
|
|
48714
|
+
metadata: v1Config.metadata || { version: "1.0" },
|
|
48715
|
+
blacklist: v1Config.blacklist || { tables: [], columns: {} }
|
|
48716
|
+
};
|
|
48717
|
+
}
|
|
48718
|
+
} else {
|
|
48719
|
+
const legacyFile = Bun.file(configPath);
|
|
48720
|
+
if (await legacyFile.exists()) {
|
|
48721
|
+
const raw = JSON.parse(await legacyFile.text());
|
|
48722
|
+
if (detectConfigVersion(raw) !== 2) {
|
|
48723
|
+
const v1Config = await configModule.read(configPath);
|
|
48724
|
+
existingV2 = {
|
|
48725
|
+
version: 2,
|
|
48726
|
+
default: "default",
|
|
48727
|
+
connections: {
|
|
48728
|
+
default: {
|
|
48729
|
+
...v1Config.connection,
|
|
48730
|
+
permission: v1Config.permission
|
|
48731
|
+
}
|
|
48732
|
+
},
|
|
48733
|
+
schema: v1Config.schema || {},
|
|
48734
|
+
metadata: v1Config.metadata || { version: "1.0" },
|
|
48735
|
+
blacklist: v1Config.blacklist || { tables: [], columns: {} }
|
|
48736
|
+
};
|
|
48737
|
+
}
|
|
48738
|
+
}
|
|
48739
|
+
}
|
|
48740
|
+
const connEntry = {
|
|
48741
|
+
...connection,
|
|
48742
|
+
permission
|
|
48743
|
+
};
|
|
48744
|
+
if (envFile) {
|
|
48745
|
+
connEntry.envFile = envFile;
|
|
48746
|
+
}
|
|
48747
|
+
const v2Config = existingV2 ? {
|
|
48748
|
+
...existingV2,
|
|
48749
|
+
connections: {
|
|
48750
|
+
...existingV2.connections,
|
|
48751
|
+
[connectionName]: connEntry
|
|
48752
|
+
}
|
|
48753
|
+
} : {
|
|
48754
|
+
version: 2,
|
|
48755
|
+
default: connectionName,
|
|
48756
|
+
connections: {
|
|
48757
|
+
[connectionName]: connEntry
|
|
48758
|
+
},
|
|
48759
|
+
schema: {},
|
|
48760
|
+
metadata: { version: "1.0", createdAt: new Date().toISOString() },
|
|
48761
|
+
blacklist: { tables: [], columns: {} }
|
|
48762
|
+
};
|
|
48763
|
+
await Bun.$`mkdir -p ${configPath}`;
|
|
48764
|
+
await writeV2Config(configPath, v2Config);
|
|
48765
|
+
console.log(t("init.config_saved"));
|
|
48766
|
+
}
|
|
48767
|
+
var initCommand = new Command("init").description("Initialize dbcli configuration with .env parsing and interactive prompts").option("--host <host>", "Database host").option("--port <port>", "Database port").option("--user <user>", "Database user").option("--password <password>", "Database password").option("--name <name>", "Database name").option("--system <system>", "Database system (postgresql, mysql, mariadb)").option("--permission <permission>", "Permission level (query-only, read-write, data-admin, admin)", "query-only").option("--use-env-refs", "Store env var references in config instead of actual values (for CI/CD or multi-env)", false).option("--env-host <var>", "Env var name for host (with --use-env-refs)").option("--env-port <var>", "Env var name for port (with --use-env-refs)").option("--env-user <var>", "Env var name for user (with --use-env-refs)").option("--env-password <var>", "Env var name for password (with --use-env-refs)").option("--env-database <var>", "Env var name for database (with --use-env-refs)").option("--skip-test", "Skip database connection test").option("--no-interactive", "Non-interactive mode (requires all values via flags)").option("--force", "Skip overwrite confirmation if .dbcli exists").option("--conn-name <name>", "Connection name (creates v2 multi-connection config)").option("--env-file <path>", "Path to env file for this connection").option("--remove <name>", "Remove a named connection").option("--rename <names>", "Rename a connection (format: old:new)").action(async (options) => {
|
|
48459
48768
|
try {
|
|
48460
48769
|
await initCommandHandler(options);
|
|
48461
48770
|
} catch (error) {
|
|
@@ -48468,7 +48777,18 @@ var initCommand = new Command("init").description("Initialize dbcli configuratio
|
|
|
48468
48777
|
}
|
|
48469
48778
|
});
|
|
48470
48779
|
async function initCommandHandler(options) {
|
|
48471
|
-
const
|
|
48780
|
+
const configPath = initCommand.parent?.opts().config ?? ".dbcli";
|
|
48781
|
+
if (options.remove) {
|
|
48782
|
+
await handleRemove(configPath, options.remove);
|
|
48783
|
+
return;
|
|
48784
|
+
}
|
|
48785
|
+
if (options.rename) {
|
|
48786
|
+
await handleRename(configPath, options.rename);
|
|
48787
|
+
return;
|
|
48788
|
+
}
|
|
48789
|
+
const isV2Init = !!(options.connName || options.envFile);
|
|
48790
|
+
const connectionName = options.connName || "default";
|
|
48791
|
+
const existingConfig = await configModule.read(configPath);
|
|
48472
48792
|
const isUsingEnvRefs = options.useEnvRefs;
|
|
48473
48793
|
const hasAllEnvOptions = isUsingEnvRefs && options.envHost && options.envPort && options.envUser && options.envPassword && options.envDatabase;
|
|
48474
48794
|
const shouldPrompt = !options.noInteractive && !hasAllEnvOptions;
|
|
@@ -48526,11 +48846,15 @@ async function initCommandHandler(options) {
|
|
|
48526
48846
|
connection: configForWrite,
|
|
48527
48847
|
permission: permission2
|
|
48528
48848
|
});
|
|
48529
|
-
const canProceed2 = await checkOverwrite(shouldPrompt, !!options.force);
|
|
48849
|
+
const canProceed2 = await checkOverwrite(configPath, shouldPrompt, !!options.force);
|
|
48530
48850
|
if (!canProceed2)
|
|
48531
48851
|
return;
|
|
48532
48852
|
console.log(`\u23ED\uFE0F ${t("init.skip_test_env_ref")}`);
|
|
48533
|
-
|
|
48853
|
+
if (isV2Init) {
|
|
48854
|
+
await writeV2InitConfig(configPath, connectionName, configForWrite, permission2, options.envFile);
|
|
48855
|
+
return;
|
|
48856
|
+
}
|
|
48857
|
+
await configModule.write(configPath, newConfig2);
|
|
48534
48858
|
console.log(t("init.config_saved"));
|
|
48535
48859
|
return;
|
|
48536
48860
|
}
|
|
@@ -48585,7 +48909,7 @@ async function initCommandHandler(options) {
|
|
|
48585
48909
|
connection: configForWrite,
|
|
48586
48910
|
permission
|
|
48587
48911
|
});
|
|
48588
|
-
const canProceed = await checkOverwrite(shouldPrompt, !!options.force);
|
|
48912
|
+
const canProceed = await checkOverwrite(configPath, shouldPrompt, !!options.force);
|
|
48589
48913
|
if (!canProceed)
|
|
48590
48914
|
return;
|
|
48591
48915
|
if (!options.skipTest && !options.useEnvRefs) {
|
|
@@ -48631,7 +48955,11 @@ async function initCommandHandler(options) {
|
|
|
48631
48955
|
const msgKey = options.useEnvRefs ? "init.skip_test_env_ref" : "init.skip_test";
|
|
48632
48956
|
console.log(`\u23ED\uFE0F ${t(msgKey)}`);
|
|
48633
48957
|
}
|
|
48634
|
-
|
|
48958
|
+
if (isV2Init) {
|
|
48959
|
+
await writeV2InitConfig(configPath, connectionName, configForWrite, permission, options.envFile);
|
|
48960
|
+
return;
|
|
48961
|
+
}
|
|
48962
|
+
await configModule.write(configPath, newConfig);
|
|
48635
48963
|
console.log(t("init.config_saved"));
|
|
48636
48964
|
}
|
|
48637
48965
|
|
|
@@ -51287,7 +51615,7 @@ var statusCommand = new Command("status").description("Show current configuratio
|
|
|
51287
51615
|
|
|
51288
51616
|
// src/commands/doctor.ts
|
|
51289
51617
|
init_validation();
|
|
51290
|
-
import { join as
|
|
51618
|
+
import { join as join5 } from "path";
|
|
51291
51619
|
var ALLOWED_FORMATS7 = ["text", "json"];
|
|
51292
51620
|
var SENSITIVE_PATTERNS = [
|
|
51293
51621
|
"password",
|
|
@@ -51349,7 +51677,7 @@ var runDoctorChecks = {
|
|
|
51349
51677
|
}
|
|
51350
51678
|
},
|
|
51351
51679
|
async checkConfigExists(configPath, existsFn) {
|
|
51352
|
-
const exists = existsFn ? await existsFn(configPath) : await Bun.file(configPath).exists() || await Bun.file(
|
|
51680
|
+
const exists = existsFn ? await existsFn(configPath) : await Bun.file(configPath).exists() || await Bun.file(join5(configPath, "config.json")).exists();
|
|
51353
51681
|
return {
|
|
51354
51682
|
group: "Configuration",
|
|
51355
51683
|
label: "Config exists",
|
|
@@ -51441,6 +51769,60 @@ var runDoctorChecks = {
|
|
|
51441
51769
|
message: `Large tables: ${list}`
|
|
51442
51770
|
};
|
|
51443
51771
|
},
|
|
51772
|
+
async checkV2Config(configPath) {
|
|
51773
|
+
const results = [];
|
|
51774
|
+
const configFile = Bun.file(join5(configPath, "config.json"));
|
|
51775
|
+
if (!await configFile.exists())
|
|
51776
|
+
return results;
|
|
51777
|
+
let raw;
|
|
51778
|
+
try {
|
|
51779
|
+
raw = JSON.parse(await configFile.text());
|
|
51780
|
+
} catch {
|
|
51781
|
+
return results;
|
|
51782
|
+
}
|
|
51783
|
+
if (detectConfigVersion(raw) !== 2)
|
|
51784
|
+
return results;
|
|
51785
|
+
let config;
|
|
51786
|
+
try {
|
|
51787
|
+
config = DbcliConfigV2Schema.parse(raw);
|
|
51788
|
+
} catch {
|
|
51789
|
+
results.push({
|
|
51790
|
+
group: "Configuration",
|
|
51791
|
+
label: "V2 config validation",
|
|
51792
|
+
status: "error",
|
|
51793
|
+
message: "V2 \u8A2D\u5B9A\u6A94\u683C\u5F0F\u7121\u6548"
|
|
51794
|
+
});
|
|
51795
|
+
return results;
|
|
51796
|
+
}
|
|
51797
|
+
if (!config.connections[config.default]) {
|
|
51798
|
+
results.push({
|
|
51799
|
+
group: "Configuration",
|
|
51800
|
+
label: "Default connection",
|
|
51801
|
+
status: "error",
|
|
51802
|
+
message: `\u9810\u8A2D\u9023\u7DDA '${config.default}' \u4E0D\u5B58\u5728\u65BC connections \u4E2D`
|
|
51803
|
+
});
|
|
51804
|
+
} else {
|
|
51805
|
+
results.push({
|
|
51806
|
+
group: "Configuration",
|
|
51807
|
+
label: "Default connection",
|
|
51808
|
+
status: "pass",
|
|
51809
|
+
message: `\u9810\u8A2D\u9023\u7DDA '${config.default}' \u6709\u6548`
|
|
51810
|
+
});
|
|
51811
|
+
}
|
|
51812
|
+
for (const [name, conn] of Object.entries(config.connections)) {
|
|
51813
|
+
if (conn.envFile) {
|
|
51814
|
+
const envPath = join5(configPath, "..", conn.envFile);
|
|
51815
|
+
const exists = await Bun.file(envPath).exists();
|
|
51816
|
+
results.push({
|
|
51817
|
+
group: "Configuration",
|
|
51818
|
+
label: `Env file (${name})`,
|
|
51819
|
+
status: exists ? "pass" : "error",
|
|
51820
|
+
message: exists ? `${conn.envFile} \u5B58\u5728` : `\u9023\u7DDA '${name}' \u7684 env \u6A94\u6848 ${conn.envFile} \u4E0D\u5B58\u5728`
|
|
51821
|
+
});
|
|
51822
|
+
}
|
|
51823
|
+
}
|
|
51824
|
+
return results;
|
|
51825
|
+
},
|
|
51444
51826
|
formatTextOutput(results, version) {
|
|
51445
51827
|
const lines2 = [`dbcli doctor v${version}`, ""];
|
|
51446
51828
|
const groups = ["Environment", "Configuration", "Connection & Data"];
|
|
@@ -51489,6 +51871,8 @@ var doctorCommand = new Command("doctor").description("Run diagnostic checks on
|
|
|
51489
51871
|
status: "pass",
|
|
51490
51872
|
message: `Permission: ${config.permission}`
|
|
51491
51873
|
});
|
|
51874
|
+
const v2Results = await runDoctorChecks.checkV2Config(configPath);
|
|
51875
|
+
results.push(...v2Results);
|
|
51492
51876
|
const blacklistedColumns = new Map;
|
|
51493
51877
|
if (config.blacklist?.columns) {
|
|
51494
51878
|
for (const [table, cols] of Object.entries(config.blacklist.columns)) {
|
|
@@ -51523,7 +51907,7 @@ var doctorCommand = new Command("doctor").description("Run diagnostic checks on
|
|
|
51523
51907
|
logger.debug("Could not list tables for blacklist/large table check");
|
|
51524
51908
|
}
|
|
51525
51909
|
try {
|
|
51526
|
-
const indexPath =
|
|
51910
|
+
const indexPath = join5(configPath, "schemas", "index.json");
|
|
51527
51911
|
const indexFile = Bun.file(indexPath);
|
|
51528
51912
|
if (await indexFile.exists()) {
|
|
51529
51913
|
const indexContent = await indexFile.text();
|
|
@@ -51565,7 +51949,7 @@ var doctorCommand = new Command("doctor").description("Run diagnostic checks on
|
|
|
51565
51949
|
});
|
|
51566
51950
|
|
|
51567
51951
|
// src/commands/completion.ts
|
|
51568
|
-
import { join as
|
|
51952
|
+
import { join as join6 } from "path";
|
|
51569
51953
|
import { homedir as homedir2 } from "os";
|
|
51570
51954
|
function extractCommands(program2) {
|
|
51571
51955
|
return program2.commands.map((cmd) => ({
|
|
@@ -51670,11 +52054,11 @@ function getInstallPath2(shell) {
|
|
|
51670
52054
|
const home = homedir2();
|
|
51671
52055
|
switch (shell) {
|
|
51672
52056
|
case "bash":
|
|
51673
|
-
return
|
|
52057
|
+
return join6(home, ".bashrc");
|
|
51674
52058
|
case "zsh":
|
|
51675
|
-
return
|
|
52059
|
+
return join6(home, ".zshrc");
|
|
51676
52060
|
case "fish":
|
|
51677
|
-
return
|
|
52061
|
+
return join6(home, ".config", "fish", "completions", "dbcli.fish");
|
|
51678
52062
|
default:
|
|
51679
52063
|
throw new Error(`Unsupported shell: ${shell}. Supported: bash, zsh, fish`);
|
|
51680
52064
|
}
|
|
@@ -51694,7 +52078,7 @@ var MARKER_END = "# <<< dbcli completion <<<";
|
|
|
51694
52078
|
async function installCompletion(shell, script) {
|
|
51695
52079
|
const targetPath = getInstallPath2(shell);
|
|
51696
52080
|
if (shell === "fish") {
|
|
51697
|
-
const dir =
|
|
52081
|
+
const dir = join6(homedir2(), ".config", "fish", "completions");
|
|
51698
52082
|
await Bun.$`mkdir -p ${dir}`.quiet();
|
|
51699
52083
|
await Bun.file(targetPath).write(script);
|
|
51700
52084
|
console.log(colors.success(`\u2713 Fish completion installed to ${targetPath}`));
|
|
@@ -51897,7 +52281,7 @@ var upgradeCommand = new Command("upgrade").description("Check for updates and u
|
|
|
51897
52281
|
|
|
51898
52282
|
// src/commands/shell.ts
|
|
51899
52283
|
import { createInterface as createInterface2 } from "readline";
|
|
51900
|
-
import { join as
|
|
52284
|
+
import { join as join7 } from "path";
|
|
51901
52285
|
import { homedir as homedir3 } from "os";
|
|
51902
52286
|
|
|
51903
52287
|
// src/core/repl/types.ts
|
|
@@ -52585,7 +52969,7 @@ function matchWithSuffix(candidates, prefix) {
|
|
|
52585
52969
|
|
|
52586
52970
|
// src/commands/shell.ts
|
|
52587
52971
|
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
52588
|
-
var HISTORY_PATH =
|
|
52972
|
+
var HISTORY_PATH = join7(homedir3(), ".dbcli_history");
|
|
52589
52973
|
var shellCommand = new Command("shell").description("Interactive database shell with auto-completion and syntax highlighting").option("--sql", "SQL-only mode (skip dbcli command parsing)").action(async (options) => {
|
|
52590
52974
|
const globalOpts = shellCommand.optsWithGlobals?.() ?? {};
|
|
52591
52975
|
const configPath = globalOpts.config ?? ".dbcli";
|
|
@@ -53483,12 +53867,73 @@ addExecOpts(migrateCommand.command("drop-enum <name>").description(t("migrate.dr
|
|
|
53483
53867
|
}
|
|
53484
53868
|
});
|
|
53485
53869
|
|
|
53870
|
+
// src/commands/use.ts
|
|
53871
|
+
import { join as join8 } from "path";
|
|
53872
|
+
async function switchDefault(configPath, name, config) {
|
|
53873
|
+
if (!config.connections[name]) {
|
|
53874
|
+
const available = Object.keys(config.connections).join(", ");
|
|
53875
|
+
throw new ConfigError(`${t_vars("init.connection_not_found", { name })}. ${t("use.available")}: ${available}`);
|
|
53876
|
+
}
|
|
53877
|
+
const updated = {
|
|
53878
|
+
...config,
|
|
53879
|
+
default: name
|
|
53880
|
+
};
|
|
53881
|
+
await writeV2Config(configPath, updated);
|
|
53882
|
+
}
|
|
53883
|
+
function listConnectionsForDisplay(config) {
|
|
53884
|
+
return Object.entries(config.connections).map(([name, conn]) => {
|
|
53885
|
+
const marker = name === config.default ? "*" : " ";
|
|
53886
|
+
const host = typeof conn.host === "object" ? `\${${conn.host.$env}}` : conn.host;
|
|
53887
|
+
const port = typeof conn.port === "object" ? `\${${conn.port.$env}}` : conn.port;
|
|
53888
|
+
const db = typeof conn.database === "object" ? `\${${conn.database.$env}}` : conn.database;
|
|
53889
|
+
return `${marker} ${name.padEnd(12)} ${conn.system.padEnd(12)} ${host}:${port}/${db}`;
|
|
53890
|
+
});
|
|
53891
|
+
}
|
|
53892
|
+
async function ensureV2Config(configPath) {
|
|
53893
|
+
const configFile = Bun.file(join8(configPath, "config.json"));
|
|
53894
|
+
if (!await configFile.exists()) {
|
|
53895
|
+
throw new ConfigError(t("init.config_not_found"));
|
|
53896
|
+
}
|
|
53897
|
+
const raw = JSON.parse(await configFile.text());
|
|
53898
|
+
if (!raw.version || raw.version !== 2 || !raw.connections) {
|
|
53899
|
+
throw new ConfigError(t("use.requires_v2"));
|
|
53900
|
+
}
|
|
53901
|
+
return readV2Config(configPath);
|
|
53902
|
+
}
|
|
53903
|
+
var useCommand = new Command("use").description("Switch or display the default database connection (v2 config)").argument("[name]", "Connection name to switch to").option("--list", "List all connections").action(async (name, options) => {
|
|
53904
|
+
try {
|
|
53905
|
+
const configPath = useCommand.parent?.opts().config ?? ".dbcli";
|
|
53906
|
+
const config = await ensureV2Config(configPath);
|
|
53907
|
+
if (options.list || !name) {
|
|
53908
|
+
if (!name) {
|
|
53909
|
+
console.log(t_vars("use.current", { name: config.default }));
|
|
53910
|
+
}
|
|
53911
|
+
console.log("");
|
|
53912
|
+
for (const line of listConnectionsForDisplay(config)) {
|
|
53913
|
+
console.log(line);
|
|
53914
|
+
}
|
|
53915
|
+
return;
|
|
53916
|
+
}
|
|
53917
|
+
await switchDefault(configPath, name, config);
|
|
53918
|
+
console.log(t_vars("use.switched", { name }));
|
|
53919
|
+
} catch (error) {
|
|
53920
|
+
if (error instanceof Error) {
|
|
53921
|
+
console.error(error.message);
|
|
53922
|
+
} else {
|
|
53923
|
+
console.error(String(error));
|
|
53924
|
+
}
|
|
53925
|
+
process.exit(1);
|
|
53926
|
+
}
|
|
53927
|
+
});
|
|
53928
|
+
|
|
53486
53929
|
// src/cli.ts
|
|
53487
|
-
import { join as
|
|
53930
|
+
import { join as join9 } from "path";
|
|
53488
53931
|
var _bgVersionCheckResult;
|
|
53489
|
-
var program2 = new Command().name("dbcli").description("Database CLI for AI agents").version(package_default.version).option("--no-color", "Disable colored output").option("-v, --verbose", "Increase verbosity (-v verbose, -vv debug)", (_, prev) => prev + 1, 0).option("-q, --quiet", "Suppress non-essential output").option("--config <path>", "Path to .dbcli config file", ".dbcli");
|
|
53932
|
+
var program2 = new Command().name("dbcli").description("Database CLI for AI agents").version(package_default.version).option("--no-color", "Disable colored output").option("-v, --verbose", "Increase verbosity (-v verbose, -vv debug)", (_, prev) => prev + 1, 0).option("-q, --quiet", "Suppress non-essential output").option("--config <path>", "Path to .dbcli config file", ".dbcli").option("--use <connection>", "Use a specific named connection (v2 config)");
|
|
53490
53933
|
program2.hook("preAction", (thisCommand, actionCommand) => {
|
|
53491
53934
|
const opts = thisCommand.opts();
|
|
53935
|
+
const useConnection = opts.use;
|
|
53936
|
+
setGlobalConnectionName(useConnection);
|
|
53492
53937
|
if (opts.color === false) {
|
|
53493
53938
|
process.env.NO_COLOR = "1";
|
|
53494
53939
|
}
|
|
@@ -53508,7 +53953,7 @@ program2.hook("preAction", (thisCommand, actionCommand) => {
|
|
|
53508
53953
|
try {
|
|
53509
53954
|
let cache = null;
|
|
53510
53955
|
try {
|
|
53511
|
-
const cacheFile = Bun.file(
|
|
53956
|
+
const cacheFile = Bun.file(join9(configPath, "version-check.json"));
|
|
53512
53957
|
if (await cacheFile.exists()) {
|
|
53513
53958
|
cache = await cacheFile.json();
|
|
53514
53959
|
}
|
|
@@ -53589,6 +54034,7 @@ program2.addCommand(completionCommand);
|
|
|
53589
54034
|
program2.addCommand(upgradeCommand);
|
|
53590
54035
|
program2.addCommand(shellCommand);
|
|
53591
54036
|
program2.addCommand(migrateCommand);
|
|
54037
|
+
program2.addCommand(useCommand);
|
|
53592
54038
|
if (!process.argv.slice(2).length) {
|
|
53593
54039
|
program2.outputHelp();
|
|
53594
54040
|
}
|