@carllee1983/dbcli 9.1.2 → 11.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 +60 -21
- package/.cursor/skills/dbcli/reference.md +73 -20
- package/.cursor-plugin/plugin.json +1 -1
- package/.github/skills/dbcli/SKILL.md +60 -21
- package/.github/skills/dbcli/reference.md +73 -20
- package/CHANGELOG.md +144 -0
- package/README.dev.md +19 -6
- package/README.md +50 -11
- package/README.zh-TW.md +45 -12
- package/assets/SKILL.md +60 -21
- package/assets/reference.md +73 -20
- package/assets/ui-template.html +17 -17
- package/dist/cli-runtime.mjs +4663 -478
- package/dist/cli.mjs +3 -2
- package/dist/core.d.ts +23 -9
- package/dist/core.mjs +91 -18
- package/gemini-extension.json +1 -1
- package/package.json +3 -2
- package/plugins/dbcli-agent/.codex-plugin/plugin.json +1 -1
- package/plugins/dbcli-agent/skills/dbcli/SKILL.md +60 -21
- package/plugins/dbcli-agent/skills/dbcli/reference.md +73 -20
- package/scripts/postinstall-check-bun.mjs +1 -1
- package/skills/dbcli/SKILL.md +60 -21
- package/skills/dbcli/reference.md +73 -20
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: "11.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/",
|
|
@@ -103,6 +103,7 @@ var package_default = {
|
|
|
103
103
|
"lru-cache": "^11.4.0",
|
|
104
104
|
"lucide-react": "^1.16.0",
|
|
105
105
|
mongodb: "^7.2.0",
|
|
106
|
+
"mongodb-connection-string-url": "^7.0.1",
|
|
106
107
|
mysql2: "^3.24.3",
|
|
107
108
|
"node-sql-parser": "5",
|
|
108
109
|
open: "^11.0.0",
|
package/dist/core.d.ts
CHANGED
|
@@ -36,6 +36,8 @@ export interface ConnectionOptions {
|
|
|
36
36
|
replicaSet?: string;
|
|
37
37
|
/** MongoDB TLS switch (optional, field-based config; implied true when srv) */
|
|
38
38
|
tls?: boolean;
|
|
39
|
+
/** MongoDB extra driver options appended to the URI query string (field-based config, plain strings only) */
|
|
40
|
+
options?: Record<string, string>;
|
|
39
41
|
/** MongoDB SRV lookup — build a mongodb+srv:// URI from host (optional, field-based config) */
|
|
40
42
|
srv?: boolean;
|
|
41
43
|
/** Connection timeout in milliseconds (default: 5000) */
|
|
@@ -440,6 +442,8 @@ interface MongoDBConnectionConfig {
|
|
|
440
442
|
$env: string;
|
|
441
443
|
};
|
|
442
444
|
tls?: boolean;
|
|
445
|
+
/** Extra driver options appended to the URI query string; plain strings, no env-ref */
|
|
446
|
+
options?: Record<string, string>;
|
|
443
447
|
/** Build a mongodb+srv:// URI from host and expand it via DNS SRV lookup */
|
|
444
448
|
srv?: boolean;
|
|
445
449
|
}
|
|
@@ -1105,6 +1109,7 @@ declare const DbcliConfigSchema: z.ZodObject<{
|
|
|
1105
1109
|
}>
|
|
1106
1110
|
]>>;
|
|
1107
1111
|
tls: z.ZodOptional<z.ZodBoolean>;
|
|
1112
|
+
options: z.ZodOptional<z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodString>, Record<string, string>, Record<string, string>>>;
|
|
1108
1113
|
srv: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
1109
1114
|
}, "strip", z.ZodTypeAny, {
|
|
1110
1115
|
password: string | {
|
|
@@ -1134,6 +1139,7 @@ declare const DbcliConfigSchema: z.ZodObject<{
|
|
|
1134
1139
|
$env: string;
|
|
1135
1140
|
} | undefined;
|
|
1136
1141
|
tls?: boolean | undefined;
|
|
1142
|
+
options?: Record<string, string> | undefined;
|
|
1137
1143
|
timeout?: number | undefined;
|
|
1138
1144
|
statementTimeout?: number | undefined;
|
|
1139
1145
|
}, {
|
|
@@ -1163,6 +1169,7 @@ declare const DbcliConfigSchema: z.ZodObject<{
|
|
|
1163
1169
|
$env: string;
|
|
1164
1170
|
} | undefined;
|
|
1165
1171
|
tls?: boolean | undefined;
|
|
1172
|
+
options?: Record<string, string> | undefined;
|
|
1166
1173
|
srv?: boolean | undefined;
|
|
1167
1174
|
timeout?: number | undefined;
|
|
1168
1175
|
statementTimeout?: number | undefined;
|
|
@@ -1569,6 +1576,7 @@ declare const DbcliConfigSchema: z.ZodObject<{
|
|
|
1569
1576
|
$env: string;
|
|
1570
1577
|
} | undefined;
|
|
1571
1578
|
tls?: boolean | undefined;
|
|
1579
|
+
options?: Record<string, string> | undefined;
|
|
1572
1580
|
timeout?: number | undefined;
|
|
1573
1581
|
statementTimeout?: number | undefined;
|
|
1574
1582
|
} | {
|
|
@@ -1701,6 +1709,7 @@ declare const DbcliConfigSchema: z.ZodObject<{
|
|
|
1701
1709
|
$env: string;
|
|
1702
1710
|
} | undefined;
|
|
1703
1711
|
tls?: boolean | undefined;
|
|
1712
|
+
options?: Record<string, string> | undefined;
|
|
1704
1713
|
srv?: boolean | undefined;
|
|
1705
1714
|
timeout?: number | undefined;
|
|
1706
1715
|
statementTimeout?: number | undefined;
|
|
@@ -1827,7 +1836,7 @@ declare const DbcliConfigSchema: z.ZodObject<{
|
|
|
1827
1836
|
type DbcliConfig$1 = z.infer<typeof DbcliConfigSchema>;
|
|
1828
1837
|
declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
1829
1838
|
version: z.ZodLiteral<2>;
|
|
1830
|
-
default: z.ZodString
|
|
1839
|
+
default: z.ZodOptional<z.ZodString>;
|
|
1831
1840
|
connections: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodUnion<[
|
|
1832
1841
|
z.ZodObject<{
|
|
1833
1842
|
timeout: z.ZodOptional<z.ZodNumber>;
|
|
@@ -2154,6 +2163,7 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
2154
2163
|
}>
|
|
2155
2164
|
]>>;
|
|
2156
2165
|
tls: z.ZodOptional<z.ZodBoolean>;
|
|
2166
|
+
options: z.ZodOptional<z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodString>, Record<string, string>, Record<string, string>>>;
|
|
2157
2167
|
srv: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
2158
2168
|
} & {
|
|
2159
2169
|
permission: z.ZodDefault<z.ZodEnum<[
|
|
@@ -2193,6 +2203,7 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
2193
2203
|
$env: string;
|
|
2194
2204
|
} | undefined;
|
|
2195
2205
|
tls?: boolean | undefined;
|
|
2206
|
+
options?: Record<string, string> | undefined;
|
|
2196
2207
|
timeout?: number | undefined;
|
|
2197
2208
|
statementTimeout?: number | undefined;
|
|
2198
2209
|
envFile?: string | undefined;
|
|
@@ -2224,6 +2235,7 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
2224
2235
|
$env: string;
|
|
2225
2236
|
} | undefined;
|
|
2226
2237
|
tls?: boolean | undefined;
|
|
2238
|
+
options?: Record<string, string> | undefined;
|
|
2227
2239
|
srv?: boolean | undefined;
|
|
2228
2240
|
timeout?: number | undefined;
|
|
2229
2241
|
permission?: "admin" | "query-only" | "read-write" | "data-admin" | undefined;
|
|
@@ -2570,6 +2582,7 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
2570
2582
|
$env: string;
|
|
2571
2583
|
} | undefined;
|
|
2572
2584
|
tls?: boolean | undefined;
|
|
2585
|
+
options?: Record<string, string> | undefined;
|
|
2573
2586
|
timeout?: number | undefined;
|
|
2574
2587
|
statementTimeout?: number | undefined;
|
|
2575
2588
|
envFile?: string | undefined;
|
|
@@ -2704,6 +2717,7 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
2704
2717
|
$env: string;
|
|
2705
2718
|
} | undefined;
|
|
2706
2719
|
tls?: boolean | undefined;
|
|
2720
|
+
options?: Record<string, string> | undefined;
|
|
2707
2721
|
timeout?: number | undefined;
|
|
2708
2722
|
statementTimeout?: number | undefined;
|
|
2709
2723
|
envFile?: string | undefined;
|
|
@@ -2898,7 +2912,6 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
2898
2912
|
};
|
|
2899
2913
|
};
|
|
2900
2914
|
version: 2;
|
|
2901
|
-
default: string;
|
|
2902
2915
|
metadata: {
|
|
2903
2916
|
version: string;
|
|
2904
2917
|
createdAt?: string | undefined;
|
|
@@ -2981,6 +2994,7 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
2981
2994
|
$env: string;
|
|
2982
2995
|
} | undefined;
|
|
2983
2996
|
tls?: boolean | undefined;
|
|
2997
|
+
options?: Record<string, string> | undefined;
|
|
2984
2998
|
timeout?: number | undefined;
|
|
2985
2999
|
statementTimeout?: number | undefined;
|
|
2986
3000
|
envFile?: string | undefined;
|
|
@@ -3047,9 +3061,9 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
3047
3061
|
fields?: string[] | undefined;
|
|
3048
3062
|
}[];
|
|
3049
3063
|
} | undefined;
|
|
3064
|
+
default?: string | undefined;
|
|
3050
3065
|
}, {
|
|
3051
3066
|
version: 2;
|
|
3052
|
-
default: string;
|
|
3053
3067
|
connections: Record<string, unknown>;
|
|
3054
3068
|
redis?: {
|
|
3055
3069
|
mask?: {
|
|
@@ -3070,6 +3084,7 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
3070
3084
|
max_entries?: number | undefined;
|
|
3071
3085
|
} | undefined;
|
|
3072
3086
|
} | undefined;
|
|
3087
|
+
default?: string | undefined;
|
|
3073
3088
|
metadata?: {
|
|
3074
3089
|
version?: string | undefined;
|
|
3075
3090
|
createdAt?: string | undefined;
|
|
@@ -3092,7 +3107,6 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
3092
3107
|
};
|
|
3093
3108
|
};
|
|
3094
3109
|
version: 2;
|
|
3095
|
-
default: string;
|
|
3096
3110
|
metadata: {
|
|
3097
3111
|
version: string;
|
|
3098
3112
|
createdAt?: string | undefined;
|
|
@@ -3175,6 +3189,7 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
3175
3189
|
$env: string;
|
|
3176
3190
|
} | undefined;
|
|
3177
3191
|
tls?: boolean | undefined;
|
|
3192
|
+
options?: Record<string, string> | undefined;
|
|
3178
3193
|
timeout?: number | undefined;
|
|
3179
3194
|
statementTimeout?: number | undefined;
|
|
3180
3195
|
envFile?: string | undefined;
|
|
@@ -3241,9 +3256,9 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
3241
3256
|
fields?: string[] | undefined;
|
|
3242
3257
|
}[];
|
|
3243
3258
|
} | undefined;
|
|
3259
|
+
default?: string | undefined;
|
|
3244
3260
|
}, {
|
|
3245
3261
|
version: 2;
|
|
3246
|
-
default: string;
|
|
3247
3262
|
connections: Record<string, unknown>;
|
|
3248
3263
|
redis?: {
|
|
3249
3264
|
mask?: {
|
|
@@ -3264,6 +3279,7 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
3264
3279
|
max_entries?: number | undefined;
|
|
3265
3280
|
} | undefined;
|
|
3266
3281
|
} | undefined;
|
|
3282
|
+
default?: string | undefined;
|
|
3267
3283
|
metadata?: {
|
|
3268
3284
|
version?: string | undefined;
|
|
3269
3285
|
createdAt?: string | undefined;
|
|
@@ -3630,9 +3646,7 @@ export declare function resolveConnection(config: DbcliConfigV2, name: string |
|
|
|
3630
3646
|
* Load env file for a connection if specified
|
|
3631
3647
|
*/
|
|
3632
3648
|
export declare function loadConnectionEnv(resolved: ResolvedConnection, basePath: string): Promise<void>;
|
|
3633
|
-
/**
|
|
3634
|
-
* Read and validate a v2 config from disk
|
|
3635
|
-
*/
|
|
3649
|
+
/** Read and validate a v2 config from disk. */
|
|
3636
3650
|
export declare function readV2Config(path: string): Promise<DbcliConfigV2>;
|
|
3637
3651
|
/**
|
|
3638
3652
|
* Write a v2 config and its integrity records as one recoverable publication.
|
|
@@ -3675,7 +3689,7 @@ export interface ConnectionInput {
|
|
|
3675
3689
|
user: string;
|
|
3676
3690
|
database: string;
|
|
3677
3691
|
}
|
|
3678
|
-
/** 刪除連線(immutable)
|
|
3692
|
+
/** 刪除連線(immutable)。刪預設則清空預設;刪最後一條則擋下(v2 需至少一條)。 */
|
|
3679
3693
|
export declare function removeConnection(config: DbcliConfigV2, name: string): DbcliConfigV2;
|
|
3680
3694
|
/** 設定預設連線(immutable)。 */
|
|
3681
3695
|
export declare function setDefaultConnection(config: DbcliConfigV2, name: string): DbcliConfigV2;
|
package/dist/core.mjs
CHANGED
|
@@ -1251,6 +1251,8 @@ var messages_default = {
|
|
|
1251
1251
|
init: {
|
|
1252
1252
|
description: "Initialize dbcli configuration with .env parsing and interactive prompts",
|
|
1253
1253
|
welcome: "Welcome to dbcli",
|
|
1254
|
+
prompt_connection_name: "Connection name",
|
|
1255
|
+
connection_name_required: "Connection name is required. Provide --conn-name <name> (this is separate from the database --name).",
|
|
1254
1256
|
select_system: "Select database system:",
|
|
1255
1257
|
prompt_host: "Database host: ",
|
|
1256
1258
|
prompt_port: "Database port: ",
|
|
@@ -1259,6 +1261,22 @@ var messages_default = {
|
|
|
1259
1261
|
secret_alternatives_sql: "pass --password, supply the credential through .env or the process environment, or store a reference with --use-env-refs",
|
|
1260
1262
|
secret_alternatives_mongo_password: "pass --password, supply the credential through .env or the process environment, or paste the connection string with --uri",
|
|
1261
1263
|
secret_alternatives_mongo_uri: "pass the connection string with --uri",
|
|
1264
|
+
mongo_uri_conflicts_fields: "--uri cannot be combined with {flags}: the connection string already carries those settings. Use one or the other (--name may be combined to override the database name).",
|
|
1265
|
+
mongo_uri_with_env_refs: "--uri cannot be combined with --use-env-refs: the connection string is decomposed into config fields, and its credentials are not moved into environment variables. Either remove --use-env-refs so dbcli decomposes the string into the field config, or use the --env-* flags (--env-host, --env-user, --env-password, ...) to name one variable per field.",
|
|
1266
|
+
mongo_uri_fallback_warning: "\u26A0\uFE0F This connection string {reasons}, so it cannot become fields. It is stored as-is in uri, and its credentials will sit in plaintext in the config file.",
|
|
1267
|
+
mongo_uri_reason_multi_host: "contains more than one host (a field config holds only one)",
|
|
1268
|
+
mongo_uri_reason_secret_option: "contains secret option(s) ({keys}) that would land in plaintext options",
|
|
1269
|
+
mongo_uri_reason_duplicate_key: "repeats the query key(s) {keys} (a field config can hold only one value per key)",
|
|
1270
|
+
mongo_uri_reason_non_scram: "uses the non-SCRAM auth mechanism {mechanism} (field config cannot express it)",
|
|
1271
|
+
mongo_decomposed_header: "Connection string decomposed into these fields (password hidden):",
|
|
1272
|
+
mongo_paste_env_refs_warning: "\u26A0\uFE0F --use-env-refs does not apply to a pasted connection string: its credentials are written to the config file as they are, not as environment-variable references.",
|
|
1273
|
+
mongo_setup_mode_paste: "Paste a connection string (copied from Atlas / Compass)",
|
|
1274
|
+
mongo_string_invalid: "Not a valid MongoDB connection string (it is not echoed because it may carry credentials).",
|
|
1275
|
+
mongo_string_bad_host: "The connection string has an invalid host or port (the port must be an integer from 1 to 65535).",
|
|
1276
|
+
mongo_string_bad_credentials: "The connection string's credentials contain an unescaped reserved character such as @, : or /. Percent-encode it (for example @ as %40).",
|
|
1277
|
+
mongo_string_tls_conflict: "The connection string sets tls and ssl to different values.",
|
|
1278
|
+
mongo_string_bad_tls: "The connection string's {key} must be true or false.",
|
|
1279
|
+
mongo_string_empty_option: "The connection string sets {key} but leaves it empty. Give it a value or remove it.",
|
|
1262
1280
|
prompt_name: "Database name: ",
|
|
1263
1281
|
prompt_permission: "Permission level (query-only, read-write, data-admin, admin): ",
|
|
1264
1282
|
env_parse_note: "Note: Unable to parse .env configuration, using interactive prompts",
|
|
@@ -1275,7 +1293,7 @@ var messages_default = {
|
|
|
1275
1293
|
config_exists_use_force: ".dbcli exists. Use --force option to overwrite.",
|
|
1276
1294
|
connection_added: "Connection '{name}' added",
|
|
1277
1295
|
connection_removed: "Connection '{name}' removed",
|
|
1278
|
-
|
|
1296
|
+
connection_removed_default_cleared: "Connection '{name}' removed. Default connection cleared. Specify --use <name> or DBCLI_CONNECTION for database commands.",
|
|
1279
1297
|
connection_renamed: "Connection '{oldName}' renamed to '{newName}'",
|
|
1280
1298
|
v1_migration_prompt: "Detected old config format. Create new format and import existing connection as 'default'?",
|
|
1281
1299
|
config_saved_v2: "V2 configuration saved to .dbcli",
|
|
@@ -1313,6 +1331,9 @@ var messages_default = {
|
|
|
1313
1331
|
description: "Switch or display the default database connection",
|
|
1314
1332
|
switched: "Switched default connection to {name}",
|
|
1315
1333
|
current: "Current default connection: {name}",
|
|
1334
|
+
current_none: "No default connection. Specify --use <name> or DBCLI_CONNECTION.",
|
|
1335
|
+
unset: "Default connection cleared. Specify --use <name> or DBCLI_CONNECTION for database commands.",
|
|
1336
|
+
unset_conflict: "--unset cannot be combined with a connection name, --list, --confirm-production, or --format json",
|
|
1316
1337
|
requires_v2: "This feature requires v2 config format. Use 'dbcli init --conn-name <name>' to create one",
|
|
1317
1338
|
available: "Available connections"
|
|
1318
1339
|
},
|
|
@@ -1583,6 +1604,8 @@ var messages_default2 = {
|
|
|
1583
1604
|
init: {
|
|
1584
1605
|
description: "\u521D\u59CB\u5316 dbcli \u914D\u7F6E\uFF0C\u89E3\u6790 .env \u4E26\u9032\u884C\u4E92\u52D5\u5F0F\u63D0\u793A",
|
|
1585
1606
|
welcome: "\u6B61\u8FCE\u4F7F\u7528 dbcli",
|
|
1607
|
+
prompt_connection_name: "\u9023\u7DDA\u540D\u7A31",
|
|
1608
|
+
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",
|
|
1586
1609
|
select_system: "\u9078\u64C7\u8CC7\u6599\u5EAB\u7CFB\u7D71\uFF1A",
|
|
1587
1610
|
prompt_host: "\u8CC7\u6599\u5EAB\u4E3B\u6A5F\uFF1A",
|
|
1588
1611
|
prompt_port: "\u8CC7\u6599\u5EAB\u57E0\u865F\uFF1A",
|
|
@@ -1591,6 +1614,22 @@ var messages_default2 = {
|
|
|
1591
1614
|
secret_alternatives_sql: "\u6539\u7528 --password\u3001\u628A\u6191\u8B49\u653E\u9032 .env \u6216\u884C\u7A0B\u74B0\u5883\u8B8A\u6578\uFF0C\u6216\u4EE5 --use-env-refs \u5B58\u6210\u53C3\u7167",
|
|
1592
1615
|
secret_alternatives_mongo_password: "\u6539\u7528 --password\u3001\u628A\u6191\u8B49\u653E\u9032 .env \u6216\u884C\u7A0B\u74B0\u5883\u8B8A\u6578\uFF0C\u6216\u4EE5 --uri \u8CBC\u4E0A\u9023\u7DDA\u5B57\u4E32",
|
|
1593
1616
|
secret_alternatives_mongo_uri: "\u4EE5 --uri \u50B3\u5165\u9023\u7DDA\u5B57\u4E32",
|
|
1617
|
+
mongo_uri_conflicts_fields: "--uri \u4E0D\u80FD\u8207 {flags} \u4E26\u7528\uFF1A\u9023\u7DDA\u5B57\u4E32\u5DF2\u5305\u542B\u9019\u4E9B\u8A2D\u5B9A\u3002\u8ACB\u64C7\u4E00\u4F7F\u7528\uFF08--name \u53EF\u4E26\u7528\uFF0C\u7528\u4F86\u8986\u84CB\u8CC7\u6599\u5EAB\u540D\u7A31\uFF09\u3002",
|
|
1618
|
+
mongo_uri_with_env_refs: "--uri \u4E0D\u80FD\u8207 --use-env-refs \u4E26\u7528\uFF1A\u9023\u7DDA\u5B57\u4E32\u6703\u88AB\u62C6\u89E3\u6210\u6B04\u4F4D\u8A2D\u5B9A\u5BEB\u5165\uFF0C\u5E33\u5BC6\u4E0D\u6703\u88AB\u62BD\u6210\u74B0\u5883\u8B8A\u6578\u53C3\u7167\u3002\u8ACB\u6539\u8D70\u4E0B\u5217\u4EFB\u4E00\u505A\u6CD5\uFF1A\u62FF\u6389 --use-env-refs\uFF0C\u8B93 dbcli \u62C6\u89E3\u5B57\u4E32\u5BEB\u5165\u6B04\u4F4D\u8A2D\u5B9A\uFF1B\u6216\u6539\u7528 --env-* flag\uFF08--env-host\u3001--env-user\u3001--env-password \u7B49\uFF09\u9010\u6B04\u7D66\u8B8A\u6578\u540D\u7A31\u3002",
|
|
1619
|
+
mongo_uri_fallback_warning: "\u26A0\uFE0F \u6B64\u9023\u7DDA\u5B57\u4E32{reasons}\uFF0C\u7121\u6CD5\u62C6\u6210\u6B04\u4F4D\u8A2D\u5B9A\uFF0C\u5DF2\u539F\u6A23\u5B58\u5165 uri\uFF1B\u5E33\u5BC6\u5C07\u660E\u6587\u5B58\u653E\u65BC\u8A2D\u5B9A\u6A94\u3002",
|
|
1620
|
+
mongo_uri_reason_multi_host: "\u542B\u591A\u7D44 host\uFF08\u6B04\u4F4D\u8A2D\u5B9A\u53EA\u80FD\u8868\u9054\u4E00\u7D44\uFF09",
|
|
1621
|
+
mongo_uri_reason_secret_option: "\u542B\u6A5F\u5BC6 option\uFF08{keys}\uFF09\uFF0C\u62C6\u9032 options \u6703\u660E\u6587\u843D\u76E4",
|
|
1622
|
+
mongo_uri_reason_duplicate_key: "\u542B\u91CD\u8907\u7684 query \u9375\uFF08{keys}\uFF09\uFF08\u6B04\u4F4D\u8A2D\u5B9A\u6BCF\u500B\u9375\u53EA\u80FD\u5B58\u4E00\u500B\u503C\uFF09",
|
|
1623
|
+
mongo_uri_reason_non_scram: "\u4F7F\u7528\u975E SCRAM \u7684\u8A8D\u8B49\u6A5F\u5236 {mechanism}\uFF08\u6B04\u4F4D\u8A2D\u5B9A\u7121\u6CD5\u8868\u9054\uFF09",
|
|
1624
|
+
mongo_decomposed_header: "\u9023\u7DDA\u5B57\u4E32\u5DF2\u62C6\u89E3\u6210\u4E0B\u5217\u6B04\u4F4D\uFF08\u5BC6\u78BC\u5DF2\u906E\u853D\uFF09\uFF1A",
|
|
1625
|
+
mongo_paste_env_refs_warning: "\u26A0\uFE0F --use-env-refs \u4E0D\u9069\u7528\u65BC\u8CBC\u4E0A\u7684\u9023\u7DDA\u5B57\u4E32\uFF1A\u5E33\u5BC6\u6703\u4EE5\u5B57\u9762\u503C\u5BEB\u5165\u8A2D\u5B9A\u6A94\uFF0C\u4E0D\u6703\u8B8A\u6210\u74B0\u5883\u8B8A\u6578\u53C3\u7167\u3002",
|
|
1626
|
+
mongo_setup_mode_paste: "\u8CBC\u4E0A\u9023\u7DDA\u5B57\u4E32\uFF08Atlas / Compass \u8907\u88FD\u7684\uFF09",
|
|
1627
|
+
mongo_string_invalid: "\u4E0D\u662F\u5408\u6CD5\u7684 MongoDB \u9023\u7DDA\u5B57\u4E32\uFF08\u5B57\u4E32\u53EF\u80FD\u5E36\u6709\u5E33\u5BC6\uFF0C\u6240\u4EE5\u4E0D\u5370\u51FA\uFF09\u3002",
|
|
1628
|
+
mongo_string_bad_host: "\u9023\u7DDA\u5B57\u4E32\u7684 host \u6216\u57E0\u865F\u4E0D\u5408\u6CD5\uFF08\u57E0\u865F\u9808\u70BA 1 \u81F3 65535 \u7684\u6574\u6578\uFF09\u3002",
|
|
1629
|
+
mongo_string_bad_credentials: "\u9023\u7DDA\u5B57\u4E32\u7684\u5E33\u865F\u6216\u5BC6\u78BC\u542B\u6709\u672A\u8DF3\u812B\u7684\u4FDD\u7559\u5B57\u5143\uFF08\u5982 @\u3001:\u3001/\uFF09\u3002\u8ACB\u505A\u767E\u5206\u6BD4\u7DE8\u78BC\uFF08\u4F8B\u5982 @ \u5BEB\u6210 %40\uFF09\u3002",
|
|
1630
|
+
mongo_string_tls_conflict: "\u9023\u7DDA\u5B57\u4E32\u540C\u6642\u6307\u5B9A\u4E86 tls \u8207 ssl \u4E14\u503C\u4E0D\u540C\u3002",
|
|
1631
|
+
mongo_string_bad_tls: "\u9023\u7DDA\u5B57\u4E32\u7684 {key} \u53EA\u63A5\u53D7 true \u6216 false\u3002",
|
|
1632
|
+
mongo_string_empty_option: "\u9023\u7DDA\u5B57\u4E32\u6307\u5B9A\u4E86 {key} \u537B\u6C92\u6709\u503C\u3002\u8ACB\u7D66\u503C\u6216\u79FB\u9664\u3002",
|
|
1594
1633
|
prompt_name: "\u8CC7\u6599\u5EAB\u540D\u7A31\uFF1A",
|
|
1595
1634
|
prompt_permission: "\u6B0A\u9650\u7B49\u7D1A\uFF08query-only, read-write, data-admin, admin\uFF09\uFF1A",
|
|
1596
1635
|
env_parse_note: "\u63D0\u793A\uFF1A\u7121\u6CD5\u89E3\u6790 .env \u914D\u7F6E\uFF0C\u4F7F\u7528\u4E92\u52D5\u5F0F\u63D0\u793A",
|
|
@@ -1607,7 +1646,7 @@ var messages_default2 = {
|
|
|
1607
1646
|
config_exists_use_force: ".dbcli \u5DF2\u5B58\u5728\u3002\u4F7F\u7528 --force \u9078\u9805\u8986\u84CB\u3002",
|
|
1608
1647
|
connection_added: "\u5DF2\u65B0\u589E\u9023\u7DDA '{name}'",
|
|
1609
1648
|
connection_removed: "\u5DF2\u79FB\u9664\u9023\u7DDA '{name}'",
|
|
1610
|
-
|
|
1649
|
+
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",
|
|
1611
1650
|
connection_renamed: "\u5DF2\u5C07\u9023\u7DDA '{oldName}' \u91CD\u65B0\u547D\u540D\u70BA '{newName}'",
|
|
1612
1651
|
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",
|
|
1613
1652
|
config_saved_v2: "V2 \u8A2D\u5B9A\u5DF2\u5132\u5B58\u81F3 .dbcli",
|
|
@@ -1645,6 +1684,9 @@ var messages_default2 = {
|
|
|
1645
1684
|
description: "\u5207\u63DB\u6216\u986F\u793A\u9810\u8A2D\u8CC7\u6599\u5EAB\u9023\u7DDA",
|
|
1646
1685
|
switched: "\u5DF2\u5207\u63DB\u9810\u8A2D\u9023\u7DDA\u70BA {name}",
|
|
1647
1686
|
current: "\u76EE\u524D\u7684\u9810\u8A2D\u9023\u7DDA\uFF1A{name}",
|
|
1687
|
+
current_none: "\u76EE\u524D\u6C92\u6709\u9810\u8A2D\u9023\u7DDA\u3002\u8ACB\u4F7F\u7528 --use <name> \u6216\u8A2D\u5B9A DBCLI_CONNECTION\u3002",
|
|
1688
|
+
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",
|
|
1689
|
+
unset_conflict: "--unset \u4E0D\u53EF\u8207\u9023\u7DDA\u540D\u7A31\u3001--list\u3001--confirm-production \u6216 --format json \u540C\u6642\u4F7F\u7528",
|
|
1648
1690
|
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",
|
|
1649
1691
|
available: "\u53EF\u7528\u9023\u7DDA"
|
|
1650
1692
|
},
|
|
@@ -8486,6 +8528,24 @@ var TimeoutField = {
|
|
|
8486
8528
|
timeout: numberType().int().min(MIN_CONNECTION_TIMEOUT_MS).max(MAX_CONNECTION_TIMEOUT_MS).optional(),
|
|
8487
8529
|
statementTimeout: numberType().int().min(MIN_STATEMENT_TIMEOUT_MS).max(MAX_STATEMENT_TIMEOUT_MS).optional()
|
|
8488
8530
|
};
|
|
8531
|
+
var RESERVED_MONGODB_OPTION_KEYS = {
|
|
8532
|
+
authsource: "authSource",
|
|
8533
|
+
replicaset: "replicaSet",
|
|
8534
|
+
tls: "tls",
|
|
8535
|
+
ssl: "tls"
|
|
8536
|
+
};
|
|
8537
|
+
var MongoDBOptionsSchema = recordType(stringType(), stringType()).superRefine((options, ctx) => {
|
|
8538
|
+
for (const key of Object.keys(options)) {
|
|
8539
|
+
const field = RESERVED_MONGODB_OPTION_KEYS[key.toLowerCase()];
|
|
8540
|
+
if (field) {
|
|
8541
|
+
ctx.addIssue({
|
|
8542
|
+
code: ZodIssueCode.custom,
|
|
8543
|
+
path: [key],
|
|
8544
|
+
message: `options.${key} duplicates the dedicated '${field}' field; set '${field}' instead`
|
|
8545
|
+
});
|
|
8546
|
+
}
|
|
8547
|
+
}
|
|
8548
|
+
});
|
|
8489
8549
|
var MongoDBConnectionConfigSchema = objectType({
|
|
8490
8550
|
system: literalType("mongodb"),
|
|
8491
8551
|
uri: unionType([stringType(), EnvRefSchema]).optional(),
|
|
@@ -8497,6 +8557,7 @@ var MongoDBConnectionConfigSchema = objectType({
|
|
|
8497
8557
|
authSource: unionType([stringType(), EnvRefSchema]).optional(),
|
|
8498
8558
|
replicaSet: unionType([stringType(), EnvRefSchema]).optional(),
|
|
8499
8559
|
tls: booleanType().optional(),
|
|
8560
|
+
options: MongoDBOptionsSchema.optional(),
|
|
8500
8561
|
srv: booleanType().optional().default(false),
|
|
8501
8562
|
...TimeoutField
|
|
8502
8563
|
});
|
|
@@ -8676,7 +8737,7 @@ var NamedConnectionSchema = preprocessType((raw, ctx) => {
|
|
|
8676
8737
|
}, NamedConnectionUnion);
|
|
8677
8738
|
var DbcliConfigV2Schema = objectType({
|
|
8678
8739
|
version: literalType(2),
|
|
8679
|
-
default: stringType().min(1),
|
|
8740
|
+
default: stringType().min(1).optional(),
|
|
8680
8741
|
connections: recordType(NamedConnectionSchema).refine((conns) => Object.keys(conns).length > 0, {
|
|
8681
8742
|
message: "At least one connection is required"
|
|
8682
8743
|
}),
|
|
@@ -8686,7 +8747,7 @@ var DbcliConfigV2Schema = objectType({
|
|
|
8686
8747
|
blacklist: BlacklistConfigSchema,
|
|
8687
8748
|
audit: AuditConfigSchema,
|
|
8688
8749
|
redis: RedisConfigSchema
|
|
8689
|
-
}).refine((config) =>
|
|
8750
|
+
}).refine((config) => config.default === undefined || Object.hasOwn(config.connections, config.default), {
|
|
8690
8751
|
message: "Default connection must exist in connections",
|
|
8691
8752
|
path: ["default"]
|
|
8692
8753
|
});
|
|
@@ -9037,14 +9098,26 @@ function findSimilarConnectionNames(requestedName, availableNames) {
|
|
|
9037
9098
|
}).filter(({ isSimilar }) => isSimilar).sort((a, b) => a.distance - b.distance || a.name.localeCompare(b.name)).slice(0, 3).map(({ name }) => name);
|
|
9038
9099
|
}
|
|
9039
9100
|
function connectionNotFoundMessage(requestedName, availableNames) {
|
|
9101
|
+
if (requestedName === undefined) {
|
|
9102
|
+
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(", ")}`;
|
|
9103
|
+
}
|
|
9040
9104
|
const suggestions = findSimilarConnectionNames(requestedName, availableNames);
|
|
9041
9105
|
const suggestion = suggestions.length > 0 ? ` \u4F60\u662F\u5426\u8981\u4F7F\u7528\uFF1A${suggestions.join("\u3001")}\uFF1F` : "";
|
|
9042
9106
|
return `\u9023\u7DDA '${requestedName}' \u4E0D\u5B58\u5728\u3002${suggestion} \u53EF\u7528\u9023\u7DDA\uFF1A${availableNames.join(", ")}`;
|
|
9043
9107
|
}
|
|
9108
|
+
|
|
9109
|
+
class ConnectionSelectionRequiredError extends ConfigError {
|
|
9110
|
+
constructor(availableNames) {
|
|
9111
|
+
super(connectionNotFoundMessage(undefined, availableNames));
|
|
9112
|
+
}
|
|
9113
|
+
}
|
|
9044
9114
|
function resolveConnection(config, name) {
|
|
9045
9115
|
const connectionName = name ?? config.default;
|
|
9116
|
+
if (connectionName === undefined) {
|
|
9117
|
+
throw new ConnectionSelectionRequiredError(Object.keys(config.connections));
|
|
9118
|
+
}
|
|
9046
9119
|
const conn = config.connections[connectionName];
|
|
9047
|
-
if (!conn) {
|
|
9120
|
+
if (!Object.hasOwn(config.connections, connectionName) || !conn) {
|
|
9048
9121
|
throw new ConfigError(connectionNotFoundMessage(connectionName, Object.keys(config.connections)));
|
|
9049
9122
|
}
|
|
9050
9123
|
const { permission, envFile, environment, ...connectionFields } = conn;
|
|
@@ -9062,7 +9135,7 @@ async function loadConnectionEnv(resolved, basePath) {
|
|
|
9062
9135
|
await loadEnvFile(envPath);
|
|
9063
9136
|
}
|
|
9064
9137
|
}
|
|
9065
|
-
async function
|
|
9138
|
+
async function readV2ConfigDocument(path) {
|
|
9066
9139
|
const storagePath = await resolveConfigStoragePath(path);
|
|
9067
9140
|
const configPath = join7(storagePath, "config.json");
|
|
9068
9141
|
const file = Bun.file(configPath);
|
|
@@ -9072,8 +9145,10 @@ async function readV2Config(path) {
|
|
|
9072
9145
|
await assertAgentReadableFile(configPath);
|
|
9073
9146
|
const content = await file.text();
|
|
9074
9147
|
await assertConfigIntegrity(storagePath, content, { requireRecord: true });
|
|
9075
|
-
|
|
9076
|
-
|
|
9148
|
+
return JSON.parse(content);
|
|
9149
|
+
}
|
|
9150
|
+
async function readV2Config(path) {
|
|
9151
|
+
return DbcliConfigV2Schema.parse(await readV2ConfigDocument(path));
|
|
9077
9152
|
}
|
|
9078
9153
|
async function writeV2Config(path, config) {
|
|
9079
9154
|
assertConfigMutationApproved();
|
|
@@ -9104,18 +9179,20 @@ function envVarNameFor(connName, field) {
|
|
|
9104
9179
|
return `DBCLI_${slug}_${field.toUpperCase()}`;
|
|
9105
9180
|
}
|
|
9106
9181
|
function removeConnection(config, name) {
|
|
9107
|
-
if (!(
|
|
9182
|
+
if (!Object.hasOwn(config.connections, name))
|
|
9108
9183
|
throw new Error(`\u9023\u7DDA '${name}' \u4E0D\u5B58\u5728`);
|
|
9109
9184
|
const rest = { ...config.connections };
|
|
9110
9185
|
delete rest[name];
|
|
9111
9186
|
const remaining = Object.keys(rest);
|
|
9112
9187
|
if (remaining.length === 0)
|
|
9113
9188
|
throw new Error("\u7121\u6CD5\u522A\u9664\u6700\u5F8C\u4E00\u689D\u9023\u7DDA");
|
|
9114
|
-
const
|
|
9115
|
-
|
|
9189
|
+
const updated = { ...config, connections: rest };
|
|
9190
|
+
if (config.default === name)
|
|
9191
|
+
delete updated.default;
|
|
9192
|
+
return updated;
|
|
9116
9193
|
}
|
|
9117
9194
|
function setDefaultConnection(config, name) {
|
|
9118
|
-
if (!(
|
|
9195
|
+
if (!Object.hasOwn(config.connections, name))
|
|
9119
9196
|
throw new Error(`\u9023\u7DDA '${name}' \u4E0D\u5B58\u5728`);
|
|
9120
9197
|
return { ...config, default: name };
|
|
9121
9198
|
}
|
|
@@ -9240,15 +9317,11 @@ async function resolvePasswordTarget(projectPath, connectionName) {
|
|
|
9240
9317
|
};
|
|
9241
9318
|
}
|
|
9242
9319
|
const config = await readV2Config(projectPath);
|
|
9243
|
-
const targetName
|
|
9244
|
-
const connection = config.connections[targetName];
|
|
9245
|
-
if (!connection) {
|
|
9246
|
-
throw new ConfigError(connectionNotFoundMessage(targetName, Object.keys(config.connections)));
|
|
9247
|
-
}
|
|
9320
|
+
const { name: targetName, connection, envFile } = resolveConnection(config, connectionName);
|
|
9248
9321
|
const referencedVar = envRefName(connection.password);
|
|
9249
9322
|
return {
|
|
9250
9323
|
connection: targetName,
|
|
9251
|
-
envFile:
|
|
9324
|
+
envFile: envFile ?? DEFAULT_ENV_FILE,
|
|
9252
9325
|
varName: referencedVar ?? envVarNameFor(targetName, "password"),
|
|
9253
9326
|
convertedToEnvRef: referencedVar === undefined
|
|
9254
9327
|
};
|
package/gemini-extension.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carllee1983/dbcli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.0",
|
|
4
4
|
"description": "Database CLI for AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"blacklist"
|
|
42
42
|
],
|
|
43
43
|
"engines": {
|
|
44
|
-
"bun": ">=1.
|
|
44
|
+
"bun": ">=1.4.0"
|
|
45
45
|
},
|
|
46
46
|
"files": [
|
|
47
47
|
"dist/",
|
|
@@ -100,6 +100,7 @@
|
|
|
100
100
|
"lru-cache": "^11.4.0",
|
|
101
101
|
"lucide-react": "^1.16.0",
|
|
102
102
|
"mongodb": "^7.2.0",
|
|
103
|
+
"mongodb-connection-string-url": "^7.0.1",
|
|
103
104
|
"mysql2": "^3.24.3",
|
|
104
105
|
"node-sql-parser": "5",
|
|
105
106
|
"open": "^11.0.0",
|