@carllee1983/dbcli 9.1.2 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor/rules/dbcli.mdc +55 -17
- package/.cursor/skills/dbcli/reference.md +71 -18
- package/.cursor-plugin/plugin.json +1 -1
- package/.github/skills/dbcli/SKILL.md +55 -17
- package/.github/skills/dbcli/reference.md +71 -18
- package/CHANGELOG.md +107 -0
- package/README.dev.md +19 -6
- package/README.md +50 -11
- package/README.zh-TW.md +45 -12
- package/assets/SKILL.md +55 -17
- package/assets/reference.md +71 -18
- package/assets/ui-template.html +17 -17
- package/dist/cli-runtime.mjs +173 -76
- package/dist/cli.mjs +2 -2
- package/dist/core.d.ts +7 -9
- package/dist/core.mjs +40 -18
- package/gemini-extension.json +1 -1
- package/package.json +2 -2
- package/plugins/dbcli-agent/.codex-plugin/plugin.json +1 -1
- package/plugins/dbcli-agent/skills/dbcli/SKILL.md +55 -17
- package/plugins/dbcli-agent/skills/dbcli/reference.md +71 -18
- package/scripts/postinstall-check-bun.mjs +1 -1
- package/skills/dbcli/SKILL.md +55 -17
- package/skills/dbcli/reference.md +71 -18
package/dist/cli-runtime.mjs
CHANGED
|
@@ -2132,7 +2132,7 @@ var package_default;
|
|
|
2132
2132
|
var init_package = __esm(() => {
|
|
2133
2133
|
package_default = {
|
|
2134
2134
|
name: "@carllee1983/dbcli",
|
|
2135
|
-
version: "
|
|
2135
|
+
version: "10.0.0",
|
|
2136
2136
|
description: "Database CLI for AI agents",
|
|
2137
2137
|
type: "module",
|
|
2138
2138
|
publishConfig: {
|
|
@@ -2173,7 +2173,7 @@ var init_package = __esm(() => {
|
|
|
2173
2173
|
"blacklist"
|
|
2174
2174
|
],
|
|
2175
2175
|
engines: {
|
|
2176
|
-
bun: ">=1.
|
|
2176
|
+
bun: ">=1.4.0"
|
|
2177
2177
|
},
|
|
2178
2178
|
files: [
|
|
2179
2179
|
"dist/",
|
|
@@ -6503,7 +6503,7 @@ var init_validation = __esm(() => {
|
|
|
6503
6503
|
}, NamedConnectionUnion);
|
|
6504
6504
|
DbcliConfigV2Schema = objectType({
|
|
6505
6505
|
version: literalType(2),
|
|
6506
|
-
default: stringType().min(1),
|
|
6506
|
+
default: stringType().min(1).optional(),
|
|
6507
6507
|
connections: recordType(NamedConnectionSchema).refine((conns) => Object.keys(conns).length > 0, {
|
|
6508
6508
|
message: "At least one connection is required"
|
|
6509
6509
|
}),
|
|
@@ -6513,7 +6513,7 @@ var init_validation = __esm(() => {
|
|
|
6513
6513
|
blacklist: BlacklistConfigSchema,
|
|
6514
6514
|
audit: AuditConfigSchema,
|
|
6515
6515
|
redis: RedisConfigSchema
|
|
6516
|
-
}).refine((config) =>
|
|
6516
|
+
}).refine((config) => config.default === undefined || Object.hasOwn(config.connections, config.default), {
|
|
6517
6517
|
message: "Default connection must exist in connections",
|
|
6518
6518
|
path: ["default"]
|
|
6519
6519
|
});
|
|
@@ -7053,14 +7053,20 @@ function findSimilarConnectionNames(requestedName, availableNames) {
|
|
|
7053
7053
|
}).filter(({ isSimilar }) => isSimilar).sort((a, b) => a.distance - b.distance || a.name.localeCompare(b.name)).slice(0, 3).map(({ name }) => name);
|
|
7054
7054
|
}
|
|
7055
7055
|
function connectionNotFoundMessage(requestedName, availableNames) {
|
|
7056
|
+
if (requestedName === undefined) {
|
|
7057
|
+
return "\u5C1A\u672A\u8A2D\u5B9A\u9810\u8A2D\u9023\u7DDA\u3002\u8ACB\u4F7F\u7528 --use <name> \u6216\u8A2D\u5B9A DBCLI_CONNECTION \u660E\u78BA\u6307\u5B9A\u9023\u7DDA\u3002" + ` \u53EF\u7528\u9023\u7DDA\uFF1A${availableNames.join(", ")}`;
|
|
7058
|
+
}
|
|
7056
7059
|
const suggestions = findSimilarConnectionNames(requestedName, availableNames);
|
|
7057
7060
|
const suggestion = suggestions.length > 0 ? ` \u4F60\u662F\u5426\u8981\u4F7F\u7528\uFF1A${suggestions.join("\u3001")}\uFF1F` : "";
|
|
7058
7061
|
return `\u9023\u7DDA '${requestedName}' \u4E0D\u5B58\u5728\u3002${suggestion} \u53EF\u7528\u9023\u7DDA\uFF1A${availableNames.join(", ")}`;
|
|
7059
7062
|
}
|
|
7060
7063
|
function resolveConnection(config, name) {
|
|
7061
7064
|
const connectionName = name ?? config.default;
|
|
7065
|
+
if (connectionName === undefined) {
|
|
7066
|
+
throw new ConnectionSelectionRequiredError(Object.keys(config.connections));
|
|
7067
|
+
}
|
|
7062
7068
|
const conn = config.connections[connectionName];
|
|
7063
|
-
if (!conn) {
|
|
7069
|
+
if (!Object.hasOwn(config.connections, connectionName) || !conn) {
|
|
7064
7070
|
throw new ConfigError(connectionNotFoundMessage(connectionName, Object.keys(config.connections)));
|
|
7065
7071
|
}
|
|
7066
7072
|
const { permission, envFile, environment, ...connectionFields } = conn;
|
|
@@ -7078,7 +7084,7 @@ async function loadConnectionEnv(resolved, basePath) {
|
|
|
7078
7084
|
await loadEnvFile(envPath);
|
|
7079
7085
|
}
|
|
7080
7086
|
}
|
|
7081
|
-
async function
|
|
7087
|
+
async function readV2ConfigDocument(path) {
|
|
7082
7088
|
const storagePath = await resolveConfigStoragePath(path);
|
|
7083
7089
|
const configPath = join3(storagePath, "config.json");
|
|
7084
7090
|
const file = Bun.file(configPath);
|
|
@@ -7088,8 +7094,20 @@ async function readV2Config(path) {
|
|
|
7088
7094
|
await assertAgentReadableFile(configPath);
|
|
7089
7095
|
const content = await file.text();
|
|
7090
7096
|
await assertConfigIntegrity(storagePath, content, { requireRecord: true });
|
|
7091
|
-
|
|
7092
|
-
|
|
7097
|
+
return JSON.parse(content);
|
|
7098
|
+
}
|
|
7099
|
+
async function readV2Config(path) {
|
|
7100
|
+
return DbcliConfigV2Schema.parse(await readV2ConfigDocument(path));
|
|
7101
|
+
}
|
|
7102
|
+
async function clearDefaultConnection(path) {
|
|
7103
|
+
assertConfigMutationApproved();
|
|
7104
|
+
const raw = await readV2ConfigDocument(path);
|
|
7105
|
+
const config = DbcliConfigV2Schema.parse(raw);
|
|
7106
|
+
if (config.default === undefined)
|
|
7107
|
+
return;
|
|
7108
|
+
const updated = { ...raw };
|
|
7109
|
+
delete updated.default;
|
|
7110
|
+
await writeV2Config(path, updated);
|
|
7093
7111
|
}
|
|
7094
7112
|
async function writeV2Config(path, config) {
|
|
7095
7113
|
assertConfigMutationApproved();
|
|
@@ -7114,6 +7132,7 @@ async function isV2Config(dbcliPath) {
|
|
|
7114
7132
|
return false;
|
|
7115
7133
|
}
|
|
7116
7134
|
}
|
|
7135
|
+
var ConnectionSelectionRequiredError;
|
|
7117
7136
|
var init_config_v2 = __esm(() => {
|
|
7118
7137
|
init_validation();
|
|
7119
7138
|
init_errors3();
|
|
@@ -7121,6 +7140,11 @@ var init_config_v2 = __esm(() => {
|
|
|
7121
7140
|
init_config_integrity();
|
|
7122
7141
|
init_env_loader2();
|
|
7123
7142
|
init_config_binding();
|
|
7143
|
+
ConnectionSelectionRequiredError = class ConnectionSelectionRequiredError extends ConfigError {
|
|
7144
|
+
constructor(availableNames) {
|
|
7145
|
+
super(connectionNotFoundMessage(undefined, availableNames));
|
|
7146
|
+
}
|
|
7147
|
+
};
|
|
7124
7148
|
});
|
|
7125
7149
|
|
|
7126
7150
|
// src/agent-core/applied-limit.ts
|
|
@@ -8686,6 +8710,8 @@ var init_messages = __esm(() => {
|
|
|
8686
8710
|
init: {
|
|
8687
8711
|
description: "Initialize dbcli configuration with .env parsing and interactive prompts",
|
|
8688
8712
|
welcome: "Welcome to dbcli",
|
|
8713
|
+
prompt_connection_name: "Connection name",
|
|
8714
|
+
connection_name_required: "Connection name is required. Provide --conn-name <name> (this is separate from the database --name).",
|
|
8689
8715
|
select_system: "Select database system:",
|
|
8690
8716
|
prompt_host: "Database host: ",
|
|
8691
8717
|
prompt_port: "Database port: ",
|
|
@@ -8710,7 +8736,7 @@ var init_messages = __esm(() => {
|
|
|
8710
8736
|
config_exists_use_force: ".dbcli exists. Use --force option to overwrite.",
|
|
8711
8737
|
connection_added: "Connection '{name}' added",
|
|
8712
8738
|
connection_removed: "Connection '{name}' removed",
|
|
8713
|
-
|
|
8739
|
+
connection_removed_default_cleared: "Connection '{name}' removed. Default connection cleared. Specify --use <name> or DBCLI_CONNECTION for database commands.",
|
|
8714
8740
|
connection_renamed: "Connection '{oldName}' renamed to '{newName}'",
|
|
8715
8741
|
v1_migration_prompt: "Detected old config format. Create new format and import existing connection as 'default'?",
|
|
8716
8742
|
config_saved_v2: "V2 configuration saved to .dbcli",
|
|
@@ -8748,6 +8774,9 @@ var init_messages = __esm(() => {
|
|
|
8748
8774
|
description: "Switch or display the default database connection",
|
|
8749
8775
|
switched: "Switched default connection to {name}",
|
|
8750
8776
|
current: "Current default connection: {name}",
|
|
8777
|
+
current_none: "No default connection. Specify --use <name> or DBCLI_CONNECTION.",
|
|
8778
|
+
unset: "Default connection cleared. Specify --use <name> or DBCLI_CONNECTION for database commands.",
|
|
8779
|
+
unset_conflict: "--unset cannot be combined with a connection name, --list, --confirm-production, or --format json",
|
|
8751
8780
|
requires_v2: "This feature requires v2 config format. Use 'dbcli init --conn-name <name>' to create one",
|
|
8752
8781
|
available: "Available connections"
|
|
8753
8782
|
},
|
|
@@ -9022,6 +9051,8 @@ var init_messages2 = __esm(() => {
|
|
|
9022
9051
|
init: {
|
|
9023
9052
|
description: "\u521D\u59CB\u5316 dbcli \u914D\u7F6E\uFF0C\u89E3\u6790 .env \u4E26\u9032\u884C\u4E92\u52D5\u5F0F\u63D0\u793A",
|
|
9024
9053
|
welcome: "\u6B61\u8FCE\u4F7F\u7528 dbcli",
|
|
9054
|
+
prompt_connection_name: "\u9023\u7DDA\u540D\u7A31",
|
|
9055
|
+
connection_name_required: "\u9023\u7DDA\u540D\u7A31\u4E0D\u53EF\u7A7A\u767D\uFF0C\u8ACB\u63D0\u4F9B --conn-name <name>\uFF08\u8207\u8CC7\u6599\u5EAB\u540D\u7A31 --name \u4E0D\u540C\uFF09\u3002",
|
|
9025
9056
|
select_system: "\u9078\u64C7\u8CC7\u6599\u5EAB\u7CFB\u7D71\uFF1A",
|
|
9026
9057
|
prompt_host: "\u8CC7\u6599\u5EAB\u4E3B\u6A5F\uFF1A",
|
|
9027
9058
|
prompt_port: "\u8CC7\u6599\u5EAB\u57E0\u865F\uFF1A",
|
|
@@ -9046,7 +9077,7 @@ var init_messages2 = __esm(() => {
|
|
|
9046
9077
|
config_exists_use_force: ".dbcli \u5DF2\u5B58\u5728\u3002\u4F7F\u7528 --force \u9078\u9805\u8986\u84CB\u3002",
|
|
9047
9078
|
connection_added: "\u5DF2\u65B0\u589E\u9023\u7DDA '{name}'",
|
|
9048
9079
|
connection_removed: "\u5DF2\u79FB\u9664\u9023\u7DDA '{name}'",
|
|
9049
|
-
|
|
9080
|
+
connection_removed_default_cleared: "\u5DF2\u79FB\u9664\u9023\u7DDA '{name}'\uFF0C\u9810\u8A2D\u9023\u7DDA\u5DF2\u6E05\u7A7A\u3002\u57F7\u884C\u8CC7\u6599\u5EAB\u6307\u4EE4\u6642\u8ACB\u4F7F\u7528 --use <name> \u6216\u8A2D\u5B9A DBCLI_CONNECTION\u3002",
|
|
9050
9081
|
connection_renamed: "\u5DF2\u5C07\u9023\u7DDA '{oldName}' \u91CD\u65B0\u547D\u540D\u70BA '{newName}'",
|
|
9051
9082
|
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",
|
|
9052
9083
|
config_saved_v2: "V2 \u8A2D\u5B9A\u5DF2\u5132\u5B58\u81F3 .dbcli",
|
|
@@ -9084,6 +9115,9 @@ var init_messages2 = __esm(() => {
|
|
|
9084
9115
|
description: "\u5207\u63DB\u6216\u986F\u793A\u9810\u8A2D\u8CC7\u6599\u5EAB\u9023\u7DDA",
|
|
9085
9116
|
switched: "\u5DF2\u5207\u63DB\u9810\u8A2D\u9023\u7DDA\u70BA {name}",
|
|
9086
9117
|
current: "\u76EE\u524D\u7684\u9810\u8A2D\u9023\u7DDA\uFF1A{name}",
|
|
9118
|
+
current_none: "\u76EE\u524D\u6C92\u6709\u9810\u8A2D\u9023\u7DDA\u3002\u8ACB\u4F7F\u7528 --use <name> \u6216\u8A2D\u5B9A DBCLI_CONNECTION\u3002",
|
|
9119
|
+
unset: "\u9810\u8A2D\u9023\u7DDA\u5DF2\u6E05\u7A7A\u3002\u57F7\u884C\u8CC7\u6599\u5EAB\u6307\u4EE4\u6642\u8ACB\u4F7F\u7528 --use <name> \u6216\u8A2D\u5B9A DBCLI_CONNECTION\u3002",
|
|
9120
|
+
unset_conflict: "--unset \u4E0D\u53EF\u8207\u9023\u7DDA\u540D\u7A31\u3001--list\u3001--confirm-production \u6216 --format json \u540C\u6642\u4F7F\u7528",
|
|
9087
9121
|
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",
|
|
9088
9122
|
available: "\u53EF\u7528\u9023\u7DDA"
|
|
9089
9123
|
},
|
|
@@ -9803,6 +9837,28 @@ var init_env_parser = __esm(() => {
|
|
|
9803
9837
|
init_errors3();
|
|
9804
9838
|
});
|
|
9805
9839
|
|
|
9840
|
+
// src/core/config-v2-mutations.ts
|
|
9841
|
+
function envVarNameFor(connName, field) {
|
|
9842
|
+
const slug = connName.toUpperCase().replace(/[^A-Z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
9843
|
+
return `DBCLI_${slug}_${field.toUpperCase()}`;
|
|
9844
|
+
}
|
|
9845
|
+
function removeConnection(config, name) {
|
|
9846
|
+
if (!Object.hasOwn(config.connections, name))
|
|
9847
|
+
throw new Error(`\u9023\u7DDA '${name}' \u4E0D\u5B58\u5728`);
|
|
9848
|
+
const rest = { ...config.connections };
|
|
9849
|
+
delete rest[name];
|
|
9850
|
+
const remaining = Object.keys(rest);
|
|
9851
|
+
if (remaining.length === 0)
|
|
9852
|
+
throw new Error("\u7121\u6CD5\u522A\u9664\u6700\u5F8C\u4E00\u689D\u9023\u7DDA");
|
|
9853
|
+
const updated = { ...config, connections: rest };
|
|
9854
|
+
if (config.default === name)
|
|
9855
|
+
delete updated.default;
|
|
9856
|
+
return updated;
|
|
9857
|
+
}
|
|
9858
|
+
var init_config_v2_mutations = __esm(() => {
|
|
9859
|
+
init_validation();
|
|
9860
|
+
});
|
|
9861
|
+
|
|
9806
9862
|
// src/utils/prompts.ts
|
|
9807
9863
|
async function loadInquirer() {
|
|
9808
9864
|
try {
|
|
@@ -11139,7 +11195,7 @@ class PostgreSQLAdapter {
|
|
|
11139
11195
|
const enumQuery = `
|
|
11140
11196
|
SELECT
|
|
11141
11197
|
c.column_name as name,
|
|
11142
|
-
array_agg(e.enumlabel ORDER BY e.enumsortorder) as enum_values
|
|
11198
|
+
array_agg(e.enumlabel::text ORDER BY e.enumsortorder) as enum_values
|
|
11143
11199
|
FROM information_schema.columns c
|
|
11144
11200
|
JOIN pg_catalog.pg_type AS enum_type
|
|
11145
11201
|
ON enum_type.typname = c.udt_name
|
|
@@ -11160,10 +11216,10 @@ class PostgreSQLAdapter {
|
|
|
11160
11216
|
const fkQuery = `
|
|
11161
11217
|
SELECT
|
|
11162
11218
|
constraint_info.conname as name,
|
|
11163
|
-
array_agg(source_column.attname ORDER BY source_key.ordinality) as columns,
|
|
11219
|
+
array_agg(source_column.attname::text ORDER BY source_key.ordinality) as columns,
|
|
11164
11220
|
referenced_schema.nspname as ref_schema,
|
|
11165
11221
|
referenced_table.relname as ref_table,
|
|
11166
|
-
array_agg(referenced_column.attname ORDER BY source_key.ordinality) as ref_columns
|
|
11222
|
+
array_agg(referenced_column.attname::text ORDER BY source_key.ordinality) as ref_columns
|
|
11167
11223
|
FROM pg_catalog.pg_constraint AS constraint_info
|
|
11168
11224
|
JOIN pg_catalog.pg_class AS source_table
|
|
11169
11225
|
ON source_table.oid = constraint_info.conrelid
|
|
@@ -11205,7 +11261,7 @@ class PostgreSQLAdapter {
|
|
|
11205
11261
|
const indexQuery = `
|
|
11206
11262
|
SELECT
|
|
11207
11263
|
i.relname as name,
|
|
11208
|
-
array_agg(a.attname ORDER BY array_position(ix.indkey, a.attnum)) as columns,
|
|
11264
|
+
array_agg(a.attname::text ORDER BY array_position(ix.indkey, a.attnum)) as columns,
|
|
11209
11265
|
ix.indisunique as is_unique
|
|
11210
11266
|
FROM pg_index ix
|
|
11211
11267
|
JOIN pg_class t ON t.oid = ix.indrelid
|
|
@@ -11233,7 +11289,7 @@ class PostgreSQLAdapter {
|
|
|
11233
11289
|
const estimateResults = estimateResult.rows;
|
|
11234
11290
|
const pkQuery = `
|
|
11235
11291
|
SELECT
|
|
11236
|
-
array_agg(primary_key_column.attname ORDER BY primary_key.ordinality) as columns
|
|
11292
|
+
array_agg(primary_key_column.attname::text ORDER BY primary_key.ordinality) as columns
|
|
11237
11293
|
FROM pg_catalog.pg_index AS index_info
|
|
11238
11294
|
JOIN pg_catalog.pg_class AS source_table
|
|
11239
11295
|
ON source_table.oid = index_info.indrelid
|
|
@@ -14542,7 +14598,22 @@ async function checkOverwrite(configPath, shouldPrompt, force) {
|
|
|
14542
14598
|
}
|
|
14543
14599
|
throw new Error(t("init.config_exists_use_force"));
|
|
14544
14600
|
}
|
|
14601
|
+
async function assertV2InitImportSupported(configPath) {
|
|
14602
|
+
if (isGlobalConfigPath(configPath))
|
|
14603
|
+
return;
|
|
14604
|
+
const projectConfig = Bun.file(join10(configPath, "config.json"));
|
|
14605
|
+
if (!await projectConfig.exists())
|
|
14606
|
+
return;
|
|
14607
|
+
const raw = JSON.parse(await projectConfig.text());
|
|
14608
|
+
if (detectConfigVersion(raw) !== 2)
|
|
14609
|
+
return;
|
|
14610
|
+
const config = await readV2Config(configPath);
|
|
14611
|
+
if (Object.values(config.connections).some((connection) => connection.envFile && connection.envFile !== ".env.local")) {
|
|
14612
|
+
throw new Error("\u6B64\u820A\u7248\u5C08\u6848 V2 \u8A2D\u5B9A\u5305\u542B\u81EA\u8A02 envFile\u3002\u65B0\u589E\u9023\u7DDA\u6703\u642C\u79FB\u8A2D\u5B9A\uFF0C\u4F46\u76EE\u524D\u50C5\u652F\u63F4\u642C\u79FB .env.local\u3002" + "\u8ACB\u5148\u7531\u7BA1\u7406\u54E1\u5B8C\u6210\u8A2D\u5B9A\u8207\u81EA\u8A02 envFile \u7684 home storage \u9077\u79FB\uFF0C\u518D\u91CD\u8A66\u3002\u539F\u8A2D\u5B9A\u8207 env \u6A94\u6848\u672A\u8B8A\u66F4\u3002");
|
|
14613
|
+
}
|
|
14614
|
+
}
|
|
14545
14615
|
async function writeV2InitConfig(configPath, connectionName, connection, permission, envFile) {
|
|
14616
|
+
await assertV2InitImportSupported(configPath);
|
|
14546
14617
|
const globalConfig = isGlobalConfigPath(configPath);
|
|
14547
14618
|
const storagePath = globalConfig ? configPath : getProjectStoragePath(configPath);
|
|
14548
14619
|
const configJsonPath = join10(storagePath, "config.json");
|
|
@@ -14574,22 +14645,7 @@ async function writeV2InitConfig(configPath, connectionName, connection, permiss
|
|
|
14574
14645
|
} else if (await projectConfigFile.exists()) {
|
|
14575
14646
|
const raw = JSON.parse(await projectConfigFile.text());
|
|
14576
14647
|
if (detectConfigVersion(raw) === 2) {
|
|
14577
|
-
|
|
14578
|
-
existingV2 = {
|
|
14579
|
-
version: 2,
|
|
14580
|
-
default: "default",
|
|
14581
|
-
connections: {
|
|
14582
|
-
default: {
|
|
14583
|
-
...v1Config.connection,
|
|
14584
|
-
permission: v1Config.permission
|
|
14585
|
-
}
|
|
14586
|
-
},
|
|
14587
|
-
schema: v1Config.schema || {},
|
|
14588
|
-
schemas: { default: v1Config.schema || {} },
|
|
14589
|
-
metadata: v1Config.metadata || { version: "1.0" },
|
|
14590
|
-
blacklist: v1Config.blacklist || { tables: [], columns: {} },
|
|
14591
|
-
audit: v1Config.audit
|
|
14592
|
-
};
|
|
14648
|
+
existingV2 = await readV2Config(configPath);
|
|
14593
14649
|
} else {
|
|
14594
14650
|
const v1Config = await configModule.read(configPath);
|
|
14595
14651
|
existingV2 = {
|
|
@@ -14996,16 +15052,10 @@ async function handleRemove(configPath, name) {
|
|
|
14996
15052
|
if (connectionCount <= 1) {
|
|
14997
15053
|
throw new Error(t("init.cannot_remove_last"));
|
|
14998
15054
|
}
|
|
14999
|
-
const
|
|
15000
|
-
const newDefault = config.default === name ? Object.keys(remaining)[0] : config.default;
|
|
15001
|
-
const updated = {
|
|
15002
|
-
...config,
|
|
15003
|
-
default: newDefault,
|
|
15004
|
-
connections: remaining
|
|
15005
|
-
};
|
|
15055
|
+
const updated = removeConnection(config, name);
|
|
15006
15056
|
await writeV2Config(storagePath, updated);
|
|
15007
15057
|
if (config.default === name) {
|
|
15008
|
-
console.log(t_vars("init.
|
|
15058
|
+
console.log(t_vars("init.connection_removed_default_cleared", { name }));
|
|
15009
15059
|
} else {
|
|
15010
15060
|
console.log(t_vars("init.connection_removed", { name }));
|
|
15011
15061
|
}
|
|
@@ -15050,13 +15100,36 @@ async function initCommandHandler(options, command) {
|
|
|
15050
15100
|
await handleRename(configPath, options.rename);
|
|
15051
15101
|
return;
|
|
15052
15102
|
}
|
|
15053
|
-
const isGlobalConfig = isGlobalConfigPath(configPath);
|
|
15054
|
-
const isV2Init = !!(options.connName || options.envFile || isGlobalConfig);
|
|
15055
|
-
const connectionName = options.connName || "default";
|
|
15056
|
-
const existingConfig = await configModule.read(configPath);
|
|
15057
15103
|
const isUsingEnvRefs = options.useEnvRefs;
|
|
15058
15104
|
const hasAllEnvOptions = isUsingEnvRefs && options.envHost && options.envPort && options.envUser && options.envPassword && options.envDatabase;
|
|
15059
15105
|
const shouldPrompt = options.interactive !== false && !hasAllEnvOptions;
|
|
15106
|
+
let connectionName;
|
|
15107
|
+
if (typeof options.connName === "string") {
|
|
15108
|
+
if (!options.connName.trim())
|
|
15109
|
+
throw new Error(t("init.connection_name_required"));
|
|
15110
|
+
connectionName = options.connName;
|
|
15111
|
+
} else {
|
|
15112
|
+
if (!shouldPrompt || !process.stdin.isTTY) {
|
|
15113
|
+
throw new Error(t("init.connection_name_required"));
|
|
15114
|
+
}
|
|
15115
|
+
for (;; ) {
|
|
15116
|
+
if (process.stdin.readableEnded || process.stdin.destroyed) {
|
|
15117
|
+
throw new Error(t("init.connection_name_required"));
|
|
15118
|
+
}
|
|
15119
|
+
connectionName = (await promptUser.text(t("init.prompt_connection_name"))).trim();
|
|
15120
|
+
if (connectionName)
|
|
15121
|
+
break;
|
|
15122
|
+
console.error(t("init.connection_name_required"));
|
|
15123
|
+
}
|
|
15124
|
+
}
|
|
15125
|
+
const isGlobalConfig = isGlobalConfigPath(configPath);
|
|
15126
|
+
const isV2Init = true;
|
|
15127
|
+
await assertV2InitImportSupported(configPath);
|
|
15128
|
+
const existingConfig = await configModule.read(configPath, undefined, { loadLayeredSchema: false }).catch((error) => {
|
|
15129
|
+
if (error instanceof ConnectionSelectionRequiredError)
|
|
15130
|
+
return;
|
|
15131
|
+
throw error;
|
|
15132
|
+
});
|
|
15060
15133
|
let envConfig = null;
|
|
15061
15134
|
try {
|
|
15062
15135
|
envConfig = parseEnvDatabase(process.env);
|
|
@@ -15127,10 +15200,11 @@ async function initCommandHandler(options, command) {
|
|
|
15127
15200
|
if (!VALID_PERMISSIONS3.includes(permission)) {
|
|
15128
15201
|
throw new Error(t_vars("errors.invalid_permission", { permission }));
|
|
15129
15202
|
}
|
|
15130
|
-
const
|
|
15203
|
+
const updates = {
|
|
15131
15204
|
connection: configForWrite,
|
|
15132
15205
|
permission
|
|
15133
|
-
}
|
|
15206
|
+
};
|
|
15207
|
+
const newConfig = existingConfig ? configModule.merge(existingConfig, updates) : configModule.validate(updates);
|
|
15134
15208
|
const canProceed = await checkOverwrite(configPath, shouldPrompt, !!options.force);
|
|
15135
15209
|
if (!canProceed)
|
|
15136
15210
|
return;
|
|
@@ -15203,10 +15277,11 @@ async function initCommandHandler(options, command) {
|
|
|
15203
15277
|
database: { $env: envDatabase }
|
|
15204
15278
|
};
|
|
15205
15279
|
}
|
|
15206
|
-
const
|
|
15280
|
+
const updates = {
|
|
15207
15281
|
connection: configForWrite,
|
|
15208
15282
|
permission
|
|
15209
|
-
}
|
|
15283
|
+
};
|
|
15284
|
+
const newConfig = existingConfig ? configModule.merge(existingConfig, updates) : configModule.validate(updates);
|
|
15210
15285
|
const canProceed = await checkOverwrite(configPath, shouldPrompt, !!options.force);
|
|
15211
15286
|
if (!canProceed)
|
|
15212
15287
|
return;
|
|
@@ -15274,6 +15349,7 @@ var init_init = __esm(() => {
|
|
|
15274
15349
|
init_env_parser();
|
|
15275
15350
|
init_config();
|
|
15276
15351
|
init_config_v2();
|
|
15352
|
+
init_config_v2_mutations();
|
|
15277
15353
|
init_prompts();
|
|
15278
15354
|
init_redaction();
|
|
15279
15355
|
init_adapters();
|
|
@@ -15285,7 +15361,7 @@ var init_init = __esm(() => {
|
|
|
15285
15361
|
init_init_sqlite();
|
|
15286
15362
|
INIT_SYSTEM_CHOICES = DATABASE_SYSTEMS;
|
|
15287
15363
|
VALID_PERMISSIONS3 = ["query-only", "read-write", "data-admin", "admin"];
|
|
15288
|
-
initCommand = new Command2("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, mongodb, redis, elasticsearch)").option("--file <path>", "SQLite database file path (the database must already exist)").option("--cloud-id <id>", "Elasticsearch Cloud ID").option("--api-key <key>", "Elasticsearch API Key").option("--uri <uri>", "MongoDB connection URI (mongodb://user:pass@host:27017/db?authSource=admin)").option("--auth-source <authSource>", "MongoDB auth database (default: admin when user/password are set)").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 (
|
|
15364
|
+
initCommand = new Command2("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, mongodb, redis, elasticsearch)").option("--file <path>", "SQLite database file path (the database must already exist)").option("--cloud-id <id>", "Elasticsearch Cloud ID").option("--api-key <key>", "Elasticsearch API Key").option("--uri <uri>", "MongoDB connection URI (mongodb://user:pass@host:27017/db?authSource=admin)").option("--auth-source <authSource>", "MongoDB auth database (default: admin when user/password are set)").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 (required in non-interactive mode)").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) => {
|
|
15289
15365
|
try {
|
|
15290
15366
|
await initCommandHandler(options, initCommand);
|
|
15291
15367
|
} catch (error) {
|
|
@@ -31320,6 +31396,7 @@ async function updateCommand(table, options, command) {
|
|
|
31320
31396
|
await adapter.disconnect();
|
|
31321
31397
|
}
|
|
31322
31398
|
}
|
|
31399
|
+
enforcePermissionForType("UPDATE", config.permission);
|
|
31323
31400
|
let whereConditions;
|
|
31324
31401
|
try {
|
|
31325
31402
|
whereConditions = parseWhereClause(options.where);
|
|
@@ -42349,7 +42426,14 @@ var init_doctor = __esm(() => {
|
|
|
42349
42426
|
});
|
|
42350
42427
|
return results;
|
|
42351
42428
|
}
|
|
42352
|
-
if (
|
|
42429
|
+
if (config.default === undefined) {
|
|
42430
|
+
results.push({
|
|
42431
|
+
group: "Configuration",
|
|
42432
|
+
label: "Default connection",
|
|
42433
|
+
status: "pass",
|
|
42434
|
+
message: "\u672A\u8A2D\u5B9A\u9810\u8A2D\u9023\u7DDA\uFF1B\u8ACB\u4F7F\u7528 --use <name> \u6216\u8A2D\u5B9A DBCLI_CONNECTION \u660E\u78BA\u6307\u5B9A\u9023\u7DDA"
|
|
42435
|
+
});
|
|
42436
|
+
} else if (!config.connections[config.default]) {
|
|
42353
42437
|
results.push({
|
|
42354
42438
|
group: "Configuration",
|
|
42355
42439
|
label: "Default connection",
|
|
@@ -42412,7 +42496,7 @@ var init_doctor = __esm(() => {
|
|
|
42412
42496
|
const configPath = resolveConfigPath(doctorCommand);
|
|
42413
42497
|
const storagePath = await resolveConfigStoragePath(configPath);
|
|
42414
42498
|
const bunVersion = process.versions.bun ?? "unknown";
|
|
42415
|
-
const requiredBun = package_default.engines?.bun?.replace(">=", "") ?? "1.
|
|
42499
|
+
const requiredBun = package_default.engines?.bun?.replace(">=", "") ?? "1.4.0";
|
|
42416
42500
|
results.push(runDoctorChecks.checkRuntime(await collectRuntimeInfo(package_default.version)));
|
|
42417
42501
|
results.push(runDoctorChecks.checkBunVersion(bunVersion, requiredBun));
|
|
42418
42502
|
results.push(await runDoctorChecks.checkLatestVersion(package_default.version));
|
|
@@ -42508,12 +42592,28 @@ var init_doctor = __esm(() => {
|
|
|
42508
42592
|
});
|
|
42509
42593
|
}
|
|
42510
42594
|
} catch (error) {
|
|
42511
|
-
|
|
42512
|
-
|
|
42513
|
-
|
|
42514
|
-
|
|
42515
|
-
|
|
42516
|
-
|
|
42595
|
+
if (error instanceof ConnectionSelectionRequiredError) {
|
|
42596
|
+
results.push({
|
|
42597
|
+
group: "Configuration",
|
|
42598
|
+
label: "Config valid",
|
|
42599
|
+
status: "pass",
|
|
42600
|
+
message: "Config valid"
|
|
42601
|
+
});
|
|
42602
|
+
results.push(...await runDoctorChecks.checkV2Config(configPath));
|
|
42603
|
+
results.push({
|
|
42604
|
+
group: "Configuration",
|
|
42605
|
+
label: "Connection selection",
|
|
42606
|
+
status: "error",
|
|
42607
|
+
message: error.message
|
|
42608
|
+
});
|
|
42609
|
+
} else {
|
|
42610
|
+
results.push({
|
|
42611
|
+
group: "Configuration",
|
|
42612
|
+
label: "Config valid",
|
|
42613
|
+
status: "error",
|
|
42614
|
+
message: `Config invalid: ${error.message}`
|
|
42615
|
+
});
|
|
42616
|
+
}
|
|
42517
42617
|
}
|
|
42518
42618
|
}
|
|
42519
42619
|
const hasError = results.some((r) => r.status === "error");
|
|
@@ -51106,7 +51206,7 @@ var init_migrate = __esm(() => {
|
|
|
51106
51206
|
import { join as join41 } from "path";
|
|
51107
51207
|
async function switchDefault(configPath, name, config, options = {}) {
|
|
51108
51208
|
const connection = config.connections[name];
|
|
51109
|
-
if (!connection) {
|
|
51209
|
+
if (!Object.hasOwn(config.connections, name) || !connection) {
|
|
51110
51210
|
throw new ConfigError(connectionNotFoundMessage(name, Object.keys(config.connections)));
|
|
51111
51211
|
}
|
|
51112
51212
|
assertProductionDefaultConfirmation(name, connection.environment, options.confirmProduction);
|
|
@@ -51151,7 +51251,7 @@ function listConnectionIdentities(config) {
|
|
|
51151
51251
|
};
|
|
51152
51252
|
});
|
|
51153
51253
|
}
|
|
51154
|
-
async function ensureV2Config(configPath) {
|
|
51254
|
+
async function ensureV2Config(configPath, allowV1 = true) {
|
|
51155
51255
|
const storagePath = await resolveConfigStoragePath(configPath);
|
|
51156
51256
|
const configFile = Bun.file(join41(storagePath, "config.json"));
|
|
51157
51257
|
const legacyFile = Bun.file(configPath);
|
|
@@ -51165,6 +51265,8 @@ async function ensureV2Config(configPath) {
|
|
|
51165
51265
|
return JSON.parse(await legacyFile.text());
|
|
51166
51266
|
})();
|
|
51167
51267
|
if (!raw.version || raw.version !== 2 || !raw.connections) {
|
|
51268
|
+
if (!allowV1)
|
|
51269
|
+
throw new ConfigError(t("use.requires_v2"));
|
|
51168
51270
|
const v1Config = await configModule.read(configPath);
|
|
51169
51271
|
return {
|
|
51170
51272
|
version: 2,
|
|
@@ -51200,11 +51302,19 @@ var init_use = __esm(() => {
|
|
|
51200
51302
|
init_config_binding();
|
|
51201
51303
|
init_validation();
|
|
51202
51304
|
ALLOWED_FORMATS20 = ["text", "json"];
|
|
51203
|
-
useCommand = new Command2("use").description("
|
|
51305
|
+
useCommand = new Command2("use").description("Set, unset, or display the default database connection (v2 config)").argument("[name]", "Connection name to switch to").option("--list", "List all connections").option("--unset", "Clear the default connection and require explicit selection (v2 only)").option("--format <format>", "Output format: text (default) or json", "text").option("--confirm-production <name>", "Confirm changing the persisted default to this production connection by repeating its name").action(async (name, options) => {
|
|
51204
51306
|
try {
|
|
51205
51307
|
validateFormat(String(options.format), ALLOWED_FORMATS20, "use");
|
|
51308
|
+
if (options.unset && (name !== undefined || options.list || options.confirmProduction !== undefined || options.format === "json")) {
|
|
51309
|
+
throw new ConfigError(t("use.unset_conflict"));
|
|
51310
|
+
}
|
|
51206
51311
|
const configPath = resolveConfigPath(useCommand);
|
|
51207
|
-
const config = await ensureV2Config(configPath);
|
|
51312
|
+
const config = await ensureV2Config(configPath, !options.unset);
|
|
51313
|
+
if (options.unset) {
|
|
51314
|
+
await clearDefaultConnection(configPath);
|
|
51315
|
+
console.log(t("use.unset"));
|
|
51316
|
+
return;
|
|
51317
|
+
}
|
|
51208
51318
|
if (name && !options.list && options.format === "json") {
|
|
51209
51319
|
throw new ConfigError("--format json is only supported with --list");
|
|
51210
51320
|
}
|
|
@@ -51214,7 +51324,7 @@ var init_use = __esm(() => {
|
|
|
51214
51324
|
return;
|
|
51215
51325
|
}
|
|
51216
51326
|
if (!name) {
|
|
51217
|
-
console.log(t_vars("use.current", { name: config.default }));
|
|
51327
|
+
console.log(config.default === undefined ? t("use.current_none") : t_vars("use.current", { name: config.default }));
|
|
51218
51328
|
}
|
|
51219
51329
|
console.log("");
|
|
51220
51330
|
for (const line of listConnectionsForDisplay(config)) {
|
|
@@ -51237,15 +51347,6 @@ var init_use = __esm(() => {
|
|
|
51237
51347
|
});
|
|
51238
51348
|
});
|
|
51239
51349
|
|
|
51240
|
-
// src/core/config-v2-mutations.ts
|
|
51241
|
-
function envVarNameFor(connName, field) {
|
|
51242
|
-
const slug = connName.toUpperCase().replace(/[^A-Z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
51243
|
-
return `DBCLI_${slug}_${field.toUpperCase()}`;
|
|
51244
|
-
}
|
|
51245
|
-
var init_config_v2_mutations = __esm(() => {
|
|
51246
|
-
init_validation();
|
|
51247
|
-
});
|
|
51248
|
-
|
|
51249
51350
|
// src/core/env-file-writer.ts
|
|
51250
51351
|
import { chmod as chmod2, mkdir as mkdir19, readFile as readFile9, writeFile as writeFile9 } from "fs/promises";
|
|
51251
51352
|
import { dirname as dirname16 } from "path";
|
|
@@ -51315,15 +51416,11 @@ async function resolvePasswordTarget(projectPath, connectionName) {
|
|
|
51315
51416
|
};
|
|
51316
51417
|
}
|
|
51317
51418
|
const config = await readV2Config(projectPath);
|
|
51318
|
-
const targetName
|
|
51319
|
-
const connection = config.connections[targetName];
|
|
51320
|
-
if (!connection) {
|
|
51321
|
-
throw new ConfigError(connectionNotFoundMessage(targetName, Object.keys(config.connections)));
|
|
51322
|
-
}
|
|
51419
|
+
const { name: targetName, connection, envFile } = resolveConnection(config, connectionName);
|
|
51323
51420
|
const referencedVar = envRefName(connection.password);
|
|
51324
51421
|
return {
|
|
51325
51422
|
connection: targetName,
|
|
51326
|
-
envFile:
|
|
51423
|
+
envFile: envFile ?? DEFAULT_ENV_FILE,
|
|
51327
51424
|
varName: referencedVar ?? envVarNameFor(targetName, "password"),
|
|
51328
51425
|
convertedToEnvRef: referencedVar === undefined
|
|
51329
51426
|
};
|
package/dist/cli.mjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// package.json
|
|
4
4
|
var package_default = {
|
|
5
5
|
name: "@carllee1983/dbcli",
|
|
6
|
-
version: "
|
|
6
|
+
version: "10.0.0",
|
|
7
7
|
description: "Database CLI for AI agents",
|
|
8
8
|
type: "module",
|
|
9
9
|
publishConfig: {
|
|
@@ -44,7 +44,7 @@ var package_default = {
|
|
|
44
44
|
"blacklist"
|
|
45
45
|
],
|
|
46
46
|
engines: {
|
|
47
|
-
bun: ">=1.
|
|
47
|
+
bun: ">=1.4.0"
|
|
48
48
|
},
|
|
49
49
|
files: [
|
|
50
50
|
"dist/",
|
package/dist/core.d.ts
CHANGED
|
@@ -1827,7 +1827,7 @@ declare const DbcliConfigSchema: z.ZodObject<{
|
|
|
1827
1827
|
type DbcliConfig$1 = z.infer<typeof DbcliConfigSchema>;
|
|
1828
1828
|
declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
1829
1829
|
version: z.ZodLiteral<2>;
|
|
1830
|
-
default: z.ZodString
|
|
1830
|
+
default: z.ZodOptional<z.ZodString>;
|
|
1831
1831
|
connections: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodUnion<[
|
|
1832
1832
|
z.ZodObject<{
|
|
1833
1833
|
timeout: z.ZodOptional<z.ZodNumber>;
|
|
@@ -2898,7 +2898,6 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
2898
2898
|
};
|
|
2899
2899
|
};
|
|
2900
2900
|
version: 2;
|
|
2901
|
-
default: string;
|
|
2902
2901
|
metadata: {
|
|
2903
2902
|
version: string;
|
|
2904
2903
|
createdAt?: string | undefined;
|
|
@@ -3047,9 +3046,9 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
3047
3046
|
fields?: string[] | undefined;
|
|
3048
3047
|
}[];
|
|
3049
3048
|
} | undefined;
|
|
3049
|
+
default?: string | undefined;
|
|
3050
3050
|
}, {
|
|
3051
3051
|
version: 2;
|
|
3052
|
-
default: string;
|
|
3053
3052
|
connections: Record<string, unknown>;
|
|
3054
3053
|
redis?: {
|
|
3055
3054
|
mask?: {
|
|
@@ -3070,6 +3069,7 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
3070
3069
|
max_entries?: number | undefined;
|
|
3071
3070
|
} | undefined;
|
|
3072
3071
|
} | undefined;
|
|
3072
|
+
default?: string | undefined;
|
|
3073
3073
|
metadata?: {
|
|
3074
3074
|
version?: string | undefined;
|
|
3075
3075
|
createdAt?: string | undefined;
|
|
@@ -3092,7 +3092,6 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
3092
3092
|
};
|
|
3093
3093
|
};
|
|
3094
3094
|
version: 2;
|
|
3095
|
-
default: string;
|
|
3096
3095
|
metadata: {
|
|
3097
3096
|
version: string;
|
|
3098
3097
|
createdAt?: string | undefined;
|
|
@@ -3241,9 +3240,9 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
3241
3240
|
fields?: string[] | undefined;
|
|
3242
3241
|
}[];
|
|
3243
3242
|
} | undefined;
|
|
3243
|
+
default?: string | undefined;
|
|
3244
3244
|
}, {
|
|
3245
3245
|
version: 2;
|
|
3246
|
-
default: string;
|
|
3247
3246
|
connections: Record<string, unknown>;
|
|
3248
3247
|
redis?: {
|
|
3249
3248
|
mask?: {
|
|
@@ -3264,6 +3263,7 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
3264
3263
|
max_entries?: number | undefined;
|
|
3265
3264
|
} | undefined;
|
|
3266
3265
|
} | undefined;
|
|
3266
|
+
default?: string | undefined;
|
|
3267
3267
|
metadata?: {
|
|
3268
3268
|
version?: string | undefined;
|
|
3269
3269
|
createdAt?: string | undefined;
|
|
@@ -3630,9 +3630,7 @@ export declare function resolveConnection(config: DbcliConfigV2, name: string |
|
|
|
3630
3630
|
* Load env file for a connection if specified
|
|
3631
3631
|
*/
|
|
3632
3632
|
export declare function loadConnectionEnv(resolved: ResolvedConnection, basePath: string): Promise<void>;
|
|
3633
|
-
/**
|
|
3634
|
-
* Read and validate a v2 config from disk
|
|
3635
|
-
*/
|
|
3633
|
+
/** Read and validate a v2 config from disk. */
|
|
3636
3634
|
export declare function readV2Config(path: string): Promise<DbcliConfigV2>;
|
|
3637
3635
|
/**
|
|
3638
3636
|
* Write a v2 config and its integrity records as one recoverable publication.
|
|
@@ -3675,7 +3673,7 @@ export interface ConnectionInput {
|
|
|
3675
3673
|
user: string;
|
|
3676
3674
|
database: string;
|
|
3677
3675
|
}
|
|
3678
|
-
/** 刪除連線(immutable)
|
|
3676
|
+
/** 刪除連線(immutable)。刪預設則清空預設;刪最後一條則擋下(v2 需至少一條)。 */
|
|
3679
3677
|
export declare function removeConnection(config: DbcliConfigV2, name: string): DbcliConfigV2;
|
|
3680
3678
|
/** 設定預設連線(immutable)。 */
|
|
3681
3679
|
export declare function setDefaultConnection(config: DbcliConfigV2, name: string): DbcliConfigV2;
|