@carllee1983/dbcli 1.45.0 → 1.46.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 +20 -3
- package/.cursor/skills/dbcli/reference.md +13 -7
- package/.cursor-plugin/plugin.json +1 -1
- package/.github/skills/dbcli/SKILL.md +20 -3
- package/.github/skills/dbcli/reference.md +13 -7
- package/CHANGELOG.md +35 -0
- package/assets/SKILL.md +20 -3
- package/assets/reference.md +13 -7
- package/dist/cli.mjs +11977 -1066
- package/dist/core.d.ts +156 -0
- package/dist/core.mjs +80 -17
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/plugins/dbcli-agent/.codex-plugin/plugin.json +1 -1
- package/plugins/dbcli-agent/skills/dbcli/SKILL.md +20 -3
- package/plugins/dbcli-agent/skills/dbcli/reference.md +13 -7
- package/skills/dbcli/SKILL.md +20 -3
- package/skills/dbcli/reference.md +13 -7
package/dist/core.d.ts
CHANGED
|
@@ -29,6 +29,12 @@ export interface ConnectionOptions {
|
|
|
29
29
|
uri?: string;
|
|
30
30
|
/** MongoDB auth database — used when building URI from host/port/user/password (default: 'admin') */
|
|
31
31
|
authSource?: string;
|
|
32
|
+
/** MongoDB replica set name (optional, field-based config) */
|
|
33
|
+
replicaSet?: string;
|
|
34
|
+
/** MongoDB TLS switch (optional, field-based config; implied true when srv) */
|
|
35
|
+
tls?: boolean;
|
|
36
|
+
/** MongoDB SRV lookup — build a mongodb+srv:// URI from host (optional, field-based config) */
|
|
37
|
+
srv?: boolean;
|
|
32
38
|
/** Connection timeout in milliseconds (default: 5000) */
|
|
33
39
|
timeout?: number;
|
|
34
40
|
/** Elasticsearch protocol (http or https) */
|
|
@@ -430,6 +436,16 @@ interface MongoDBConnectionConfig {
|
|
|
430
436
|
database: string | {
|
|
431
437
|
$env: string;
|
|
432
438
|
};
|
|
439
|
+
/** Auth database; defaults to 'admin' when credentials are present */
|
|
440
|
+
authSource?: string | {
|
|
441
|
+
$env: string;
|
|
442
|
+
};
|
|
443
|
+
replicaSet?: string | {
|
|
444
|
+
$env: string;
|
|
445
|
+
};
|
|
446
|
+
tls?: boolean;
|
|
447
|
+
/** Build a mongodb+srv:// URI from host and expand it via DNS SRV lookup */
|
|
448
|
+
srv?: boolean;
|
|
433
449
|
}
|
|
434
450
|
interface RedisConnectionConfig {
|
|
435
451
|
system: "redis";
|
|
@@ -804,6 +820,28 @@ declare const DbcliConfigSchema: z.ZodObject<{
|
|
|
804
820
|
$env: string;
|
|
805
821
|
}>
|
|
806
822
|
]>>>;
|
|
823
|
+
authSource: z.ZodOptional<z.ZodUnion<[
|
|
824
|
+
z.ZodString,
|
|
825
|
+
z.ZodObject<{
|
|
826
|
+
$env: z.ZodString;
|
|
827
|
+
}, "strict", z.ZodTypeAny, {
|
|
828
|
+
$env: string;
|
|
829
|
+
}, {
|
|
830
|
+
$env: string;
|
|
831
|
+
}>
|
|
832
|
+
]>>;
|
|
833
|
+
replicaSet: z.ZodOptional<z.ZodUnion<[
|
|
834
|
+
z.ZodString,
|
|
835
|
+
z.ZodObject<{
|
|
836
|
+
$env: z.ZodString;
|
|
837
|
+
}, "strict", z.ZodTypeAny, {
|
|
838
|
+
$env: string;
|
|
839
|
+
}, {
|
|
840
|
+
$env: string;
|
|
841
|
+
}>
|
|
842
|
+
]>>;
|
|
843
|
+
tls: z.ZodOptional<z.ZodBoolean>;
|
|
844
|
+
srv: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
807
845
|
}, "strip", z.ZodTypeAny, {
|
|
808
846
|
password: string | {
|
|
809
847
|
$env: string;
|
|
@@ -821,6 +859,14 @@ declare const DbcliConfigSchema: z.ZodObject<{
|
|
|
821
859
|
database: string | {
|
|
822
860
|
$env: string;
|
|
823
861
|
};
|
|
862
|
+
srv: boolean;
|
|
863
|
+
authSource?: string | {
|
|
864
|
+
$env: string;
|
|
865
|
+
} | undefined;
|
|
866
|
+
replicaSet?: string | {
|
|
867
|
+
$env: string;
|
|
868
|
+
} | undefined;
|
|
869
|
+
tls?: boolean | undefined;
|
|
824
870
|
uri?: string | {
|
|
825
871
|
$env: string;
|
|
826
872
|
} | undefined;
|
|
@@ -841,6 +887,14 @@ declare const DbcliConfigSchema: z.ZodObject<{
|
|
|
841
887
|
database?: string | {
|
|
842
888
|
$env: string;
|
|
843
889
|
} | undefined;
|
|
890
|
+
authSource?: string | {
|
|
891
|
+
$env: string;
|
|
892
|
+
} | undefined;
|
|
893
|
+
replicaSet?: string | {
|
|
894
|
+
$env: string;
|
|
895
|
+
} | undefined;
|
|
896
|
+
tls?: boolean | undefined;
|
|
897
|
+
srv?: boolean | undefined;
|
|
844
898
|
uri?: string | {
|
|
845
899
|
$env: string;
|
|
846
900
|
} | undefined;
|
|
@@ -1183,6 +1237,14 @@ declare const DbcliConfigSchema: z.ZodObject<{
|
|
|
1183
1237
|
database: string | {
|
|
1184
1238
|
$env: string;
|
|
1185
1239
|
};
|
|
1240
|
+
srv: boolean;
|
|
1241
|
+
authSource?: string | {
|
|
1242
|
+
$env: string;
|
|
1243
|
+
} | undefined;
|
|
1244
|
+
replicaSet?: string | {
|
|
1245
|
+
$env: string;
|
|
1246
|
+
} | undefined;
|
|
1247
|
+
tls?: boolean | undefined;
|
|
1186
1248
|
uri?: string | {
|
|
1187
1249
|
$env: string;
|
|
1188
1250
|
} | undefined;
|
|
@@ -1273,6 +1335,14 @@ declare const DbcliConfigSchema: z.ZodObject<{
|
|
|
1273
1335
|
database?: string | {
|
|
1274
1336
|
$env: string;
|
|
1275
1337
|
} | undefined;
|
|
1338
|
+
authSource?: string | {
|
|
1339
|
+
$env: string;
|
|
1340
|
+
} | undefined;
|
|
1341
|
+
replicaSet?: string | {
|
|
1342
|
+
$env: string;
|
|
1343
|
+
} | undefined;
|
|
1344
|
+
tls?: boolean | undefined;
|
|
1345
|
+
srv?: boolean | undefined;
|
|
1276
1346
|
uri?: string | {
|
|
1277
1347
|
$env: string;
|
|
1278
1348
|
} | undefined;
|
|
@@ -1540,6 +1610,28 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
1540
1610
|
$env: string;
|
|
1541
1611
|
}>
|
|
1542
1612
|
]>>>;
|
|
1613
|
+
authSource: z.ZodOptional<z.ZodUnion<[
|
|
1614
|
+
z.ZodString,
|
|
1615
|
+
z.ZodObject<{
|
|
1616
|
+
$env: z.ZodString;
|
|
1617
|
+
}, "strict", z.ZodTypeAny, {
|
|
1618
|
+
$env: string;
|
|
1619
|
+
}, {
|
|
1620
|
+
$env: string;
|
|
1621
|
+
}>
|
|
1622
|
+
]>>;
|
|
1623
|
+
replicaSet: z.ZodOptional<z.ZodUnion<[
|
|
1624
|
+
z.ZodString,
|
|
1625
|
+
z.ZodObject<{
|
|
1626
|
+
$env: z.ZodString;
|
|
1627
|
+
}, "strict", z.ZodTypeAny, {
|
|
1628
|
+
$env: string;
|
|
1629
|
+
}, {
|
|
1630
|
+
$env: string;
|
|
1631
|
+
}>
|
|
1632
|
+
]>>;
|
|
1633
|
+
tls: z.ZodOptional<z.ZodBoolean>;
|
|
1634
|
+
srv: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
1543
1635
|
} & {
|
|
1544
1636
|
permission: z.ZodDefault<z.ZodEnum<[
|
|
1545
1637
|
"query-only",
|
|
@@ -1566,7 +1658,15 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
1566
1658
|
database: string | {
|
|
1567
1659
|
$env: string;
|
|
1568
1660
|
};
|
|
1661
|
+
srv: boolean;
|
|
1569
1662
|
permission: "admin" | "query-only" | "read-write" | "data-admin";
|
|
1663
|
+
authSource?: string | {
|
|
1664
|
+
$env: string;
|
|
1665
|
+
} | undefined;
|
|
1666
|
+
replicaSet?: string | {
|
|
1667
|
+
$env: string;
|
|
1668
|
+
} | undefined;
|
|
1669
|
+
tls?: boolean | undefined;
|
|
1570
1670
|
uri?: string | {
|
|
1571
1671
|
$env: string;
|
|
1572
1672
|
} | undefined;
|
|
@@ -1589,6 +1689,14 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
1589
1689
|
database?: string | {
|
|
1590
1690
|
$env: string;
|
|
1591
1691
|
} | undefined;
|
|
1692
|
+
authSource?: string | {
|
|
1693
|
+
$env: string;
|
|
1694
|
+
} | undefined;
|
|
1695
|
+
replicaSet?: string | {
|
|
1696
|
+
$env: string;
|
|
1697
|
+
} | undefined;
|
|
1698
|
+
tls?: boolean | undefined;
|
|
1699
|
+
srv?: boolean | undefined;
|
|
1592
1700
|
uri?: string | {
|
|
1593
1701
|
$env: string;
|
|
1594
1702
|
} | undefined;
|
|
@@ -1884,7 +1992,15 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
1884
1992
|
database: string | {
|
|
1885
1993
|
$env: string;
|
|
1886
1994
|
};
|
|
1995
|
+
srv: boolean;
|
|
1887
1996
|
permission: "admin" | "query-only" | "read-write" | "data-admin";
|
|
1997
|
+
authSource?: string | {
|
|
1998
|
+
$env: string;
|
|
1999
|
+
} | undefined;
|
|
2000
|
+
replicaSet?: string | {
|
|
2001
|
+
$env: string;
|
|
2002
|
+
} | undefined;
|
|
2003
|
+
tls?: boolean | undefined;
|
|
1888
2004
|
uri?: string | {
|
|
1889
2005
|
$env: string;
|
|
1890
2006
|
} | undefined;
|
|
@@ -1977,6 +2093,14 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
1977
2093
|
database?: string | {
|
|
1978
2094
|
$env: string;
|
|
1979
2095
|
} | undefined;
|
|
2096
|
+
authSource?: string | {
|
|
2097
|
+
$env: string;
|
|
2098
|
+
} | undefined;
|
|
2099
|
+
replicaSet?: string | {
|
|
2100
|
+
$env: string;
|
|
2101
|
+
} | undefined;
|
|
2102
|
+
tls?: boolean | undefined;
|
|
2103
|
+
srv?: boolean | undefined;
|
|
1980
2104
|
uri?: string | {
|
|
1981
2105
|
$env: string;
|
|
1982
2106
|
} | undefined;
|
|
@@ -2167,7 +2291,15 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
2167
2291
|
database: string | {
|
|
2168
2292
|
$env: string;
|
|
2169
2293
|
};
|
|
2294
|
+
srv: boolean;
|
|
2170
2295
|
permission: "admin" | "query-only" | "read-write" | "data-admin";
|
|
2296
|
+
authSource?: string | {
|
|
2297
|
+
$env: string;
|
|
2298
|
+
} | undefined;
|
|
2299
|
+
replicaSet?: string | {
|
|
2300
|
+
$env: string;
|
|
2301
|
+
} | undefined;
|
|
2302
|
+
tls?: boolean | undefined;
|
|
2171
2303
|
uri?: string | {
|
|
2172
2304
|
$env: string;
|
|
2173
2305
|
} | undefined;
|
|
@@ -2271,6 +2403,14 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
2271
2403
|
database?: string | {
|
|
2272
2404
|
$env: string;
|
|
2273
2405
|
} | undefined;
|
|
2406
|
+
authSource?: string | {
|
|
2407
|
+
$env: string;
|
|
2408
|
+
} | undefined;
|
|
2409
|
+
replicaSet?: string | {
|
|
2410
|
+
$env: string;
|
|
2411
|
+
} | undefined;
|
|
2412
|
+
tls?: boolean | undefined;
|
|
2413
|
+
srv?: boolean | undefined;
|
|
2274
2414
|
uri?: string | {
|
|
2275
2415
|
$env: string;
|
|
2276
2416
|
} | undefined;
|
|
@@ -2411,7 +2551,15 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
2411
2551
|
database: string | {
|
|
2412
2552
|
$env: string;
|
|
2413
2553
|
};
|
|
2554
|
+
srv: boolean;
|
|
2414
2555
|
permission: "admin" | "query-only" | "read-write" | "data-admin";
|
|
2556
|
+
authSource?: string | {
|
|
2557
|
+
$env: string;
|
|
2558
|
+
} | undefined;
|
|
2559
|
+
replicaSet?: string | {
|
|
2560
|
+
$env: string;
|
|
2561
|
+
} | undefined;
|
|
2562
|
+
tls?: boolean | undefined;
|
|
2415
2563
|
uri?: string | {
|
|
2416
2564
|
$env: string;
|
|
2417
2565
|
} | undefined;
|
|
@@ -2515,6 +2663,14 @@ declare const DbcliConfigV2Schema: z.ZodEffects<z.ZodObject<{
|
|
|
2515
2663
|
database?: string | {
|
|
2516
2664
|
$env: string;
|
|
2517
2665
|
} | undefined;
|
|
2666
|
+
authSource?: string | {
|
|
2667
|
+
$env: string;
|
|
2668
|
+
} | undefined;
|
|
2669
|
+
replicaSet?: string | {
|
|
2670
|
+
$env: string;
|
|
2671
|
+
} | undefined;
|
|
2672
|
+
tls?: boolean | undefined;
|
|
2673
|
+
srv?: boolean | undefined;
|
|
2518
2674
|
uri?: string | {
|
|
2519
2675
|
$env: string;
|
|
2520
2676
|
} | undefined;
|
package/dist/core.mjs
CHANGED
|
@@ -15022,12 +15022,40 @@ class MongoDBAdapter {
|
|
|
15022
15022
|
buildUri() {
|
|
15023
15023
|
if (this.options.uri)
|
|
15024
15024
|
return this.options.uri;
|
|
15025
|
-
const { user, password, host, port, database, authSource } = this.options;
|
|
15026
|
-
if (
|
|
15027
|
-
|
|
15028
|
-
|
|
15025
|
+
const { user, password, host, port, database, authSource, replicaSet, tls, srv } = this.options;
|
|
15026
|
+
if (!host) {
|
|
15027
|
+
throw new ConnectionError("UNKNOWN", "MongoDB host \u672A\u8A2D\u5B9A", [
|
|
15028
|
+
"\u8ACB\u586B\u5BEB host\uFF0C\u6216\u6539\u7528 uri \u6B04\u4F4D\u6307\u5B9A\u5B8C\u6574\u9023\u7DDA\u5B57\u4E32"
|
|
15029
|
+
]);
|
|
15030
|
+
}
|
|
15031
|
+
const isBracketedIpv6 = /^\[[0-9a-f:]+\]$/i.test(host);
|
|
15032
|
+
if (!isBracketedIpv6 && /[/@?#:\s\\]/.test(host)) {
|
|
15033
|
+
throw new ConnectionError("UNKNOWN", `MongoDB host \u542B\u6709\u975E\u6CD5\u5B57\u5143: ${host}`, [
|
|
15034
|
+
"host \u53EA\u61C9\u5305\u542B\u4E3B\u6A5F\u540D\u7A31\u6216 IP\uFF0C\u4E0D\u8981\u542B /\u3001@\u3001?\u3001#\u3001: \u6216\u7A7A\u767D",
|
|
15035
|
+
"\u57E0\u865F\u8ACB\u586B\u5728 port \u6B04\u4F4D\uFF0C\u4E0D\u8981\u4F75\u9032 host",
|
|
15036
|
+
"IPv6 \u4F4D\u5740\u8ACB\u52A0\u65B9\u62EC\u865F\uFF0C\u4F8B\u5982 [::1]",
|
|
15037
|
+
"\u82E5\u8981\u6307\u5B9A\u5B8C\u6574\u9023\u7DDA\u5B57\u4E32\uFF0C\u8ACB\u6539\u7528 uri \u6B04\u4F4D"
|
|
15038
|
+
]);
|
|
15039
|
+
}
|
|
15040
|
+
if (user && !password) {
|
|
15041
|
+
throw new ConnectionError("UNKNOWN", "\u5DF2\u6307\u5B9A user \u4F46\u672A\u63D0\u4F9B password", [
|
|
15042
|
+
'\u8ACB\u88DC\u4E0A password\uFF0C\u6216\u6539\u7528\u74B0\u5883\u8B8A\u6578\u53C3\u7167 {"$env": "..."}',
|
|
15043
|
+
"\u82E5\u78BA\u5B9A\u8981\u4EE5\u7121\u8A8D\u8B49\u65B9\u5F0F\u9023\u7DDA\uFF0C\u8ACB\u4E00\u4F75\u6E05\u7A7A user"
|
|
15044
|
+
]);
|
|
15029
15045
|
}
|
|
15030
|
-
|
|
15046
|
+
const userInfo = user ? `${encodeURIComponent(user)}:${encodeURIComponent(password)}@` : "";
|
|
15047
|
+
const scheme = srv ? "mongodb+srv://" : "mongodb://";
|
|
15048
|
+
const authority = srv ? host : `${host}:${port}`;
|
|
15049
|
+
const path = database ? `/${encodeURIComponent(database)}` : "/";
|
|
15050
|
+
const query = new URLSearchParams;
|
|
15051
|
+
if (user)
|
|
15052
|
+
query.set("authSource", authSource || "admin");
|
|
15053
|
+
if (replicaSet)
|
|
15054
|
+
query.set("replicaSet", replicaSet);
|
|
15055
|
+
if (tls !== undefined)
|
|
15056
|
+
query.set("tls", String(tls));
|
|
15057
|
+
const search = query.toString();
|
|
15058
|
+
return `${scheme}${userInfo}${authority}${path}${search ? `?${search}` : ""}`;
|
|
15031
15059
|
}
|
|
15032
15060
|
parseTxtRecords(records) {
|
|
15033
15061
|
const combined = records.flat().map((record) => record.replace(/^"|"$/g, "")).join("&");
|
|
@@ -15089,13 +15117,11 @@ class MongoDBAdapter {
|
|
|
15089
15117
|
return this.parseTxtRecords(payload.Answer.map((answer) => [answer.data]));
|
|
15090
15118
|
}
|
|
15091
15119
|
async buildResolvedUri() {
|
|
15092
|
-
|
|
15093
|
-
|
|
15094
|
-
|
|
15095
|
-
if (!this.options.uri.startsWith("mongodb+srv://")) {
|
|
15096
|
-
return this.options.uri;
|
|
15120
|
+
const canonical = this.buildUri();
|
|
15121
|
+
if (!canonical.startsWith("mongodb+srv://")) {
|
|
15122
|
+
return canonical;
|
|
15097
15123
|
}
|
|
15098
|
-
const url = new URL(
|
|
15124
|
+
const url = new URL(canonical);
|
|
15099
15125
|
const hosts = await this.resolveSrvHosts(url.hostname);
|
|
15100
15126
|
const txtOptions = await this.resolveTxtOptions(url.hostname);
|
|
15101
15127
|
const query = new URLSearchParams(url.searchParams);
|
|
@@ -15115,6 +15141,37 @@ class MongoDBAdapter {
|
|
|
15115
15141
|
const search = query.toString();
|
|
15116
15142
|
return `mongodb://${userInfo}${hosts.join(",")}${path}${search ? `?${search}` : ""}`;
|
|
15117
15143
|
}
|
|
15144
|
+
connectionHints(error, message) {
|
|
15145
|
+
const AUTH_HINTS = [
|
|
15146
|
+
"\u8A8D\u8B49\u5931\u6557\uFF1A\u8ACB\u78BA\u8A8D user / password \u6B63\u78BA",
|
|
15147
|
+
"\u8ACB\u78BA\u8A8D authSource \u6307\u5411\u5B58\u653E\u8A72\u5E33\u865F\u7684\u8CC7\u6599\u5EAB\uFF08Atlas \u8207\u591A\u6578\u81EA\u67B6\u74B0\u5883\u70BA admin\uFF09"
|
|
15148
|
+
];
|
|
15149
|
+
const DNS_HINTS = [
|
|
15150
|
+
"DNS/SRV \u89E3\u6790\u5931\u6557\uFF1A\u8ACB\u78BA\u8A8D host \u70BA SRV \u7DB2\u57DF\uFF0C\u4E14 srv \u8A2D\u5B9A\u8207\u5B83\u4E00\u81F4",
|
|
15151
|
+
"\u82E5\u8A72\u4E3B\u6A5F\u4E0D\u662F SRV \u7DB2\u57DF\uFF0C\u8ACB\u95DC\u9589 srv \u4E26\u6539\u586B host \u8207 port",
|
|
15152
|
+
"\u8ACB\u78BA\u8A8D\u672C\u6A5F DNS \u6216\u7DB2\u8DEF\uFF08VPN\u3001\u516C\u53F8\u7DB2\u8DEF\uFF09\u5141\u8A31 SRV \u67E5\u8A62"
|
|
15153
|
+
];
|
|
15154
|
+
const TLS_HINTS = [
|
|
15155
|
+
"TLS \u63E1\u624B\u5931\u6557\uFF1A\u8ACB\u78BA\u8A8D tls \u6B04\u4F4D\u8A2D\u5B9A\u8207\u4F3A\u670D\u5668\u4E00\u81F4",
|
|
15156
|
+
"\u81EA\u7C3D\u6191\u8B49\u74B0\u5883\u9700\u8981\u5728\u4F3A\u670D\u5668\u7AEF\u6216\u7CFB\u7D71\u4FE1\u4EFB\u93C8\u4E2D\u5B89\u88DD CA \u6191\u8B49"
|
|
15157
|
+
];
|
|
15158
|
+
const err = error;
|
|
15159
|
+
const causeCode = String(err?.cause?.code ?? err?.code ?? "");
|
|
15160
|
+
if (err?.code === 18 || err?.codeName === "AuthenticationFailed")
|
|
15161
|
+
return AUTH_HINTS;
|
|
15162
|
+
if (["ENOTFOUND", "EAI_AGAIN"].includes(causeCode))
|
|
15163
|
+
return DNS_HINTS;
|
|
15164
|
+
if (causeCode.startsWith("ERR_TLS") || causeCode.startsWith("SELF_SIGNED"))
|
|
15165
|
+
return TLS_HINTS;
|
|
15166
|
+
if (/authentication failed|not authorized|bad auth/i.test(message))
|
|
15167
|
+
return AUTH_HINTS;
|
|
15168
|
+
if (/querySrv|getaddrinfo (ENOTFOUND|EAI_AGAIN)/i.test(message))
|
|
15169
|
+
return DNS_HINTS;
|
|
15170
|
+
if (/unable to verify the first certificate|self.signed certificate|certificate has expired|ERR_TLS/i.test(message)) {
|
|
15171
|
+
return TLS_HINTS;
|
|
15172
|
+
}
|
|
15173
|
+
return ["\u8ACB\u78BA\u8A8D MongoDB \u670D\u52D9\u6B63\u5728\u57F7\u884C", "\u8ACB\u78BA\u8A8D\u9023\u7DDA\u8A2D\u5B9A\uFF08URI \u6216 host/port\uFF09\u6B63\u78BA"];
|
|
15174
|
+
}
|
|
15118
15175
|
getDatabase() {
|
|
15119
15176
|
if (!this.client) {
|
|
15120
15177
|
throw new ConnectionError("UNKNOWN", "\u5C1A\u672A\u9023\u7DDA\uFF0C\u8ACB\u5148\u547C\u53EB connect()", []);
|
|
@@ -15130,10 +15187,7 @@ class MongoDBAdapter {
|
|
|
15130
15187
|
} catch (err) {
|
|
15131
15188
|
const message = err.message ?? "Unknown error";
|
|
15132
15189
|
const code = message.includes("ECONNREFUSED") ? "ECONNREFUSED" : message.includes("ETIMEDOUT") ? "ETIMEDOUT" : "UNKNOWN";
|
|
15133
|
-
throw new ConnectionError(code, `MongoDB \u9023\u7DDA\u5931\u6557: ${message}`,
|
|
15134
|
-
"\u8ACB\u78BA\u8A8D MongoDB \u670D\u52D9\u6B63\u5728\u57F7\u884C",
|
|
15135
|
-
"\u8ACB\u78BA\u8A8D\u9023\u7DDA\u8A2D\u5B9A\uFF08URI \u6216 host/port\uFF09\u6B63\u78BA"
|
|
15136
|
-
]);
|
|
15190
|
+
throw new ConnectionError(code, `MongoDB \u9023\u7DDA\u5931\u6557: ${message}`, this.connectionHints(err, message));
|
|
15137
15191
|
}
|
|
15138
15192
|
}
|
|
15139
15193
|
async disconnect() {
|
|
@@ -17598,6 +17652,11 @@ async function bestEffortSecureMode(path, mode) {
|
|
|
17598
17652
|
await chmod(path, mode);
|
|
17599
17653
|
} catch {}
|
|
17600
17654
|
}
|
|
17655
|
+
function refusesGroupOrWorldWritable(mode, platform = process.platform) {
|
|
17656
|
+
if (platform === "win32")
|
|
17657
|
+
return false;
|
|
17658
|
+
return (mode & 18) !== 0;
|
|
17659
|
+
}
|
|
17601
17660
|
async function assertAgentReadableFile(path, description = "config") {
|
|
17602
17661
|
if (process.env.DBCLI_AGENT_MODE !== "1")
|
|
17603
17662
|
return;
|
|
@@ -17606,7 +17665,7 @@ async function assertAgentReadableFile(path, description = "config") {
|
|
|
17606
17665
|
if (fileStat.isSymbolicLink() || !fileStat.isFile()) {
|
|
17607
17666
|
throw new ConfigError(`Agent mode refuses a non-regular ${description} file: ${path}. Run the human/admin setup workflow to provision it.`);
|
|
17608
17667
|
}
|
|
17609
|
-
if ((fileStat.mode
|
|
17668
|
+
if (refusesGroupOrWorldWritable(fileStat.mode)) {
|
|
17610
17669
|
throw new ConfigError(`Agent mode refuses a group/world-writable config: ${path}. Run the human/admin setup workflow to secure it.`);
|
|
17611
17670
|
}
|
|
17612
17671
|
} catch (error) {
|
|
@@ -21799,7 +21858,11 @@ var MongoDBConnectionConfigSchema = exports_external.object({
|
|
|
21799
21858
|
port: OptNumberOrEnvRef,
|
|
21800
21859
|
user: OptStringOrEnvRef,
|
|
21801
21860
|
password: OptStringOrEnvRef,
|
|
21802
|
-
database: OptStringOrEnvRef
|
|
21861
|
+
database: OptStringOrEnvRef,
|
|
21862
|
+
authSource: exports_external.union([exports_external.string(), EnvRefSchema]).optional(),
|
|
21863
|
+
replicaSet: exports_external.union([exports_external.string(), EnvRefSchema]).optional(),
|
|
21864
|
+
tls: exports_external.boolean().optional(),
|
|
21865
|
+
srv: exports_external.boolean().optional().default(false)
|
|
21803
21866
|
});
|
|
21804
21867
|
var SqlConnectionConfigSchema = exports_external.object({
|
|
21805
21868
|
system: exports_external.enum(["postgresql", "mysql", "mariadb"]),
|
package/gemini-extension.json
CHANGED
package/package.json
CHANGED
|
@@ -229,11 +229,13 @@ dbcli init --system postgresql --host localhost --port 5432 \
|
|
|
229
229
|
# Reuse an existing .env (DATABASE_URL=postgresql://user:pw@host:5432/db)
|
|
230
230
|
dbcli init # parses .env in cwd
|
|
231
231
|
|
|
232
|
-
# MongoDB —
|
|
232
|
+
# MongoDB — field-by-field (no auth = omit --user/--password)
|
|
233
|
+
dbcli init --system mongodb --host localhost --port 27017 --name mydb
|
|
234
|
+
dbcli init --system mongodb --host localhost --port 27017 \
|
|
235
|
+
--user admin --password '<secret>' --auth-source admin --name mydb
|
|
236
|
+
# MongoDB — full URI (advanced escape hatch: multi-host, non-standard driver options)
|
|
233
237
|
dbcli init --system mongodb \
|
|
234
238
|
--uri "mongodb+srv://user:pw@cluster.example.mongodb.net/mydb?authSource=admin"
|
|
235
|
-
# MongoDB — discrete params (no auth = omit --user/--password)
|
|
236
|
-
dbcli init --system mongodb --host localhost --port 27017 --name mydb
|
|
237
239
|
|
|
238
240
|
# Redis — `--name` is the LOGICAL DB INDEX ("0".."15"), not a database name
|
|
239
241
|
dbcli init --system redis --host localhost --port 6379 --password '<secret>' --name 0
|
|
@@ -301,10 +303,25 @@ as a `$env` ref. In a **non-interactive / CI** run you **must** pass all five `-
|
|
|
301
303
|
flags; otherwise `init` exits with an error — it never silently falls back to plaintext.
|
|
302
304
|
`--env-file <path>` is the path to the env file, independent of the `$env` key names.
|
|
303
305
|
|
|
306
|
+
**MongoDB is the exception**: only `--env-host` is required non-interactively.
|
|
307
|
+
`--env-port` / `--env-user` / `--env-password` / `--env-database` are optional — an
|
|
308
|
+
omitted one is written as a literal value (empty string for `user` / `password`, the
|
|
309
|
+
resolved value for `port` / `database`) instead of an `$env` ref, so a field the
|
|
310
|
+
connection never needed doesn't later fail closed on an undefined variable. `init`
|
|
311
|
+
also skips the connection test in this mode regardless of `--skip-test` — the `$env`
|
|
312
|
+
refs have no value to connect with yet.
|
|
313
|
+
|
|
304
314
|
### Common gotchas
|
|
305
315
|
|
|
306
316
|
- **MongoDB `mongodb+srv://`** — `dbcli doctor` reports whether SRV resolves
|
|
307
317
|
natively or via the DoH fallback; useful when the runtime restricts DNS.
|
|
318
|
+
- **MongoDB `authSource` / `replicaSet` / `tls` / `srv`** — `init` asks for
|
|
319
|
+
these interactively (`authSource` only when a user is set; `replicaSet` /
|
|
320
|
+
`tls` behind an "advanced options?" prompt); `--auth-source <db>` is the
|
|
321
|
+
only one with a dedicated non-interactive flag, so set `replicaSet` / `tls`
|
|
322
|
+
interactively or edit `.dbcli` afterward. If a config has both `uri` and
|
|
323
|
+
per-field values, `uri` wins silently — `dbcli doctor` flags this and also
|
|
324
|
+
warns when `srv: true` is combined with a non-default `port`.
|
|
308
325
|
- **MySQL/Postgres password with `@` `:` `/`** — when using `DATABASE_URL`,
|
|
309
326
|
percent-encode (`@` → `%40`); discrete `--password` flags do not need encoding.
|
|
310
327
|
- **Redis `--name`** — accepts only the logical DB index string; non-numeric
|
|
@@ -32,10 +32,11 @@ dbcli init --system mysql --host localhost --port 3306 --user root --name mydb
|
|
|
32
32
|
dbcli init --use-env-refs # Store env var references
|
|
33
33
|
dbcli init --no-interactive --force # Non-interactive mode
|
|
34
34
|
|
|
35
|
-
# MongoDB
|
|
36
|
-
dbcli init --system mongodb --
|
|
37
|
-
dbcli init --system mongodb --host localhost --port 27017 --user admin --password secret --name mydb
|
|
35
|
+
# MongoDB — field-by-field (primary path, same shape as SQL)
|
|
36
|
+
dbcli init --system mongodb --host localhost --port 27017 --user admin --password secret --auth-source admin --name mydb
|
|
38
37
|
dbcli init --system mongodb --host localhost --port 27017 --name mydb # No auth
|
|
38
|
+
# MongoDB — full URI (advanced fallback: multi-host, non-standard driver options)
|
|
39
|
+
dbcli init --system mongodb --uri "mongodb://user:pass@host:27017/mydb?authSource=admin"
|
|
39
40
|
|
|
40
41
|
# Redis (database = logical DB index)
|
|
41
42
|
dbcli init --system redis --host localhost --port 6379
|
|
@@ -62,7 +63,7 @@ dbcli --global use --list
|
|
|
62
63
|
|
|
63
64
|
**Environment-reference options:** `--env-host <var>`, `--env-port <var>`, `--env-user <var>`, `--env-password <var>`, `--env-database <var>`
|
|
64
65
|
|
|
65
|
-
**MongoDB-specific options:** `--uri <uri>` (full connection URI), `--auth-source <db>` (auth database, default: `admin` when user/password set)
|
|
66
|
+
**MongoDB-specific options:** `--uri <uri>` (full connection URI — advanced fallback), `--auth-source <db>` (auth database, default: `admin` when user/password set). Interactive `init` also asks for `replicaSet` and `tls` under an "advanced options?" prompt; there is no dedicated non-interactive flag for either yet — set them interactively or edit `.dbcli` afterward. `srv` (boolean, builds `mongodb+srv://` and resolves hosts via DNS SRV, ignoring `port`) is asked right after `host`, before `port`, since it decides whether `port` is even relevant.
|
|
66
67
|
|
|
67
68
|
**Elasticsearch-specific options:** `--cloud-id <id>` (Elastic Cloud), `--api-key <key>` (ApiKey auth). Other ES fields (`nodes[]`, `protocol`, `caPath`, `rejectUnauthorized`) can be edited directly in `.dbcli`.
|
|
68
69
|
|
|
@@ -2025,7 +2026,9 @@ dbcli doctor --format json # JSON output for AI agents
|
|
|
2025
2026
|
- Configuration: config file exists/valid, permission level, blacklist completeness (detects unprotected sensitive columns)
|
|
2026
2027
|
- Connection & Data: database connectivity, schema cache freshness (warns if > 7 days), large table warnings (> 1M rows)
|
|
2027
2028
|
|
|
2028
|
-
> **MongoDB SRV diagnostics:** When the active connection uses `mongodb+srv
|
|
2029
|
+
> **MongoDB SRV diagnostics:** When the active connection uses `mongodb+srv://` (via a full `uri` or the per-field `srv: true`), `doctor` reports whether the current runtime can resolve SRV records directly or only through the DNS-over-HTTPS fallback used by dbcli. This helps spot execution-environment DNS restrictions even when Compass can connect.
|
|
2030
|
+
|
|
2031
|
+
> **MongoDB connection-field warnings:** `doctor` also warns when a config has both `uri` and per-field values (`host` / `user`) present — `uri` silently wins and the per-field values are ignored — and when `srv: true` is combined with a non-default `port`, since SRV records carry their own ports.
|
|
2029
2032
|
|
|
2030
2033
|
**Exit code:** 0 if all pass or warnings only, 1 if any error
|
|
2031
2034
|
**Options:** `--format <text|json>`, `--remediation`
|
|
@@ -2600,7 +2603,7 @@ Parser behaviour (`src/core/saved-queries/parser.ts::normaliseVisual`):
|
|
|
2600
2603
|
|
|
2601
2604
|
MongoDB connections use a JSON-based query model instead of SQL. Treat MongoDB support as a narrower document-database path, not as a full SQL feature equivalent.
|
|
2602
2605
|
|
|
2603
|
-
Atlas-style `mongodb+srv://` URIs are supported. `list` and `query` run against the database configured for the connection, and `query` always requires `--collection <name>`.
|
|
2606
|
+
`init --system mongodb` defaults to a field-by-field wizard (`host`, `srv`, `port`, `user`, `password` + `authSource`, then optional `replicaSet` / `tls`); a full `uri` is an explicit advanced choice in the interactive flow and the unchanged non-interactive path via `--uri`. Optional fields `authSource`, `replicaSet`, `tls`, and `srv` express what previously required embedding options in the `uri` query string. Atlas-style `mongodb+srv://` URIs are supported both as a full `uri` and via the per-field `srv: true` option. `list` and `query` run against the database configured for the connection, and `query` always requires `--collection <name>`.
|
|
2604
2607
|
|
|
2605
2608
|
**Supported commands:** `init`, `use`, `list`, `schema`, `query`, `q`, `insert`, `update`, `delete`, `export`, `status`, `shell`, `doctor`, `upgrade`, `completion`
|
|
2606
2609
|
|
|
@@ -2623,7 +2626,10 @@ Atlas-style `mongodb+srv://` URIs are supported. `list` and `query` run against
|
|
|
2623
2626
|
### MongoDB-specific workflow
|
|
2624
2627
|
|
|
2625
2628
|
```bash
|
|
2626
|
-
# 1. Initialize
|
|
2629
|
+
# 1. Initialize — field-by-field (primary path)
|
|
2630
|
+
dbcli init --system mongodb --host localhost --port 27017 \
|
|
2631
|
+
--user admin --password '<secret>' --auth-source admin --name mydb
|
|
2632
|
+
# ...or a full URI (advanced fallback, e.g. Atlas SRV clusters)
|
|
2627
2633
|
dbcli init --system mongodb --uri "mongodb+srv://user:pass@cluster.example.mongodb.net/mydb"
|
|
2628
2634
|
|
|
2629
2635
|
# 2. List collections
|
package/skills/dbcli/SKILL.md
CHANGED
|
@@ -229,11 +229,13 @@ dbcli init --system postgresql --host localhost --port 5432 \
|
|
|
229
229
|
# Reuse an existing .env (DATABASE_URL=postgresql://user:pw@host:5432/db)
|
|
230
230
|
dbcli init # parses .env in cwd
|
|
231
231
|
|
|
232
|
-
# MongoDB —
|
|
232
|
+
# MongoDB — field-by-field (no auth = omit --user/--password)
|
|
233
|
+
dbcli init --system mongodb --host localhost --port 27017 --name mydb
|
|
234
|
+
dbcli init --system mongodb --host localhost --port 27017 \
|
|
235
|
+
--user admin --password '<secret>' --auth-source admin --name mydb
|
|
236
|
+
# MongoDB — full URI (advanced escape hatch: multi-host, non-standard driver options)
|
|
233
237
|
dbcli init --system mongodb \
|
|
234
238
|
--uri "mongodb+srv://user:pw@cluster.example.mongodb.net/mydb?authSource=admin"
|
|
235
|
-
# MongoDB — discrete params (no auth = omit --user/--password)
|
|
236
|
-
dbcli init --system mongodb --host localhost --port 27017 --name mydb
|
|
237
239
|
|
|
238
240
|
# Redis — `--name` is the LOGICAL DB INDEX ("0".."15"), not a database name
|
|
239
241
|
dbcli init --system redis --host localhost --port 6379 --password '<secret>' --name 0
|
|
@@ -301,10 +303,25 @@ as a `$env` ref. In a **non-interactive / CI** run you **must** pass all five `-
|
|
|
301
303
|
flags; otherwise `init` exits with an error — it never silently falls back to plaintext.
|
|
302
304
|
`--env-file <path>` is the path to the env file, independent of the `$env` key names.
|
|
303
305
|
|
|
306
|
+
**MongoDB is the exception**: only `--env-host` is required non-interactively.
|
|
307
|
+
`--env-port` / `--env-user` / `--env-password` / `--env-database` are optional — an
|
|
308
|
+
omitted one is written as a literal value (empty string for `user` / `password`, the
|
|
309
|
+
resolved value for `port` / `database`) instead of an `$env` ref, so a field the
|
|
310
|
+
connection never needed doesn't later fail closed on an undefined variable. `init`
|
|
311
|
+
also skips the connection test in this mode regardless of `--skip-test` — the `$env`
|
|
312
|
+
refs have no value to connect with yet.
|
|
313
|
+
|
|
304
314
|
### Common gotchas
|
|
305
315
|
|
|
306
316
|
- **MongoDB `mongodb+srv://`** — `dbcli doctor` reports whether SRV resolves
|
|
307
317
|
natively or via the DoH fallback; useful when the runtime restricts DNS.
|
|
318
|
+
- **MongoDB `authSource` / `replicaSet` / `tls` / `srv`** — `init` asks for
|
|
319
|
+
these interactively (`authSource` only when a user is set; `replicaSet` /
|
|
320
|
+
`tls` behind an "advanced options?" prompt); `--auth-source <db>` is the
|
|
321
|
+
only one with a dedicated non-interactive flag, so set `replicaSet` / `tls`
|
|
322
|
+
interactively or edit `.dbcli` afterward. If a config has both `uri` and
|
|
323
|
+
per-field values, `uri` wins silently — `dbcli doctor` flags this and also
|
|
324
|
+
warns when `srv: true` is combined with a non-default `port`.
|
|
308
325
|
- **MySQL/Postgres password with `@` `:` `/`** — when using `DATABASE_URL`,
|
|
309
326
|
percent-encode (`@` → `%40`); discrete `--password` flags do not need encoding.
|
|
310
327
|
- **Redis `--name`** — accepts only the logical DB index string; non-numeric
|
|
@@ -32,10 +32,11 @@ dbcli init --system mysql --host localhost --port 3306 --user root --name mydb
|
|
|
32
32
|
dbcli init --use-env-refs # Store env var references
|
|
33
33
|
dbcli init --no-interactive --force # Non-interactive mode
|
|
34
34
|
|
|
35
|
-
# MongoDB
|
|
36
|
-
dbcli init --system mongodb --
|
|
37
|
-
dbcli init --system mongodb --host localhost --port 27017 --user admin --password secret --name mydb
|
|
35
|
+
# MongoDB — field-by-field (primary path, same shape as SQL)
|
|
36
|
+
dbcli init --system mongodb --host localhost --port 27017 --user admin --password secret --auth-source admin --name mydb
|
|
38
37
|
dbcli init --system mongodb --host localhost --port 27017 --name mydb # No auth
|
|
38
|
+
# MongoDB — full URI (advanced fallback: multi-host, non-standard driver options)
|
|
39
|
+
dbcli init --system mongodb --uri "mongodb://user:pass@host:27017/mydb?authSource=admin"
|
|
39
40
|
|
|
40
41
|
# Redis (database = logical DB index)
|
|
41
42
|
dbcli init --system redis --host localhost --port 6379
|
|
@@ -62,7 +63,7 @@ dbcli --global use --list
|
|
|
62
63
|
|
|
63
64
|
**Environment-reference options:** `--env-host <var>`, `--env-port <var>`, `--env-user <var>`, `--env-password <var>`, `--env-database <var>`
|
|
64
65
|
|
|
65
|
-
**MongoDB-specific options:** `--uri <uri>` (full connection URI), `--auth-source <db>` (auth database, default: `admin` when user/password set)
|
|
66
|
+
**MongoDB-specific options:** `--uri <uri>` (full connection URI — advanced fallback), `--auth-source <db>` (auth database, default: `admin` when user/password set). Interactive `init` also asks for `replicaSet` and `tls` under an "advanced options?" prompt; there is no dedicated non-interactive flag for either yet — set them interactively or edit `.dbcli` afterward. `srv` (boolean, builds `mongodb+srv://` and resolves hosts via DNS SRV, ignoring `port`) is asked right after `host`, before `port`, since it decides whether `port` is even relevant.
|
|
66
67
|
|
|
67
68
|
**Elasticsearch-specific options:** `--cloud-id <id>` (Elastic Cloud), `--api-key <key>` (ApiKey auth). Other ES fields (`nodes[]`, `protocol`, `caPath`, `rejectUnauthorized`) can be edited directly in `.dbcli`.
|
|
68
69
|
|
|
@@ -2025,7 +2026,9 @@ dbcli doctor --format json # JSON output for AI agents
|
|
|
2025
2026
|
- Configuration: config file exists/valid, permission level, blacklist completeness (detects unprotected sensitive columns)
|
|
2026
2027
|
- Connection & Data: database connectivity, schema cache freshness (warns if > 7 days), large table warnings (> 1M rows)
|
|
2027
2028
|
|
|
2028
|
-
> **MongoDB SRV diagnostics:** When the active connection uses `mongodb+srv
|
|
2029
|
+
> **MongoDB SRV diagnostics:** When the active connection uses `mongodb+srv://` (via a full `uri` or the per-field `srv: true`), `doctor` reports whether the current runtime can resolve SRV records directly or only through the DNS-over-HTTPS fallback used by dbcli. This helps spot execution-environment DNS restrictions even when Compass can connect.
|
|
2030
|
+
|
|
2031
|
+
> **MongoDB connection-field warnings:** `doctor` also warns when a config has both `uri` and per-field values (`host` / `user`) present — `uri` silently wins and the per-field values are ignored — and when `srv: true` is combined with a non-default `port`, since SRV records carry their own ports.
|
|
2029
2032
|
|
|
2030
2033
|
**Exit code:** 0 if all pass or warnings only, 1 if any error
|
|
2031
2034
|
**Options:** `--format <text|json>`, `--remediation`
|
|
@@ -2600,7 +2603,7 @@ Parser behaviour (`src/core/saved-queries/parser.ts::normaliseVisual`):
|
|
|
2600
2603
|
|
|
2601
2604
|
MongoDB connections use a JSON-based query model instead of SQL. Treat MongoDB support as a narrower document-database path, not as a full SQL feature equivalent.
|
|
2602
2605
|
|
|
2603
|
-
Atlas-style `mongodb+srv://` URIs are supported. `list` and `query` run against the database configured for the connection, and `query` always requires `--collection <name>`.
|
|
2606
|
+
`init --system mongodb` defaults to a field-by-field wizard (`host`, `srv`, `port`, `user`, `password` + `authSource`, then optional `replicaSet` / `tls`); a full `uri` is an explicit advanced choice in the interactive flow and the unchanged non-interactive path via `--uri`. Optional fields `authSource`, `replicaSet`, `tls`, and `srv` express what previously required embedding options in the `uri` query string. Atlas-style `mongodb+srv://` URIs are supported both as a full `uri` and via the per-field `srv: true` option. `list` and `query` run against the database configured for the connection, and `query` always requires `--collection <name>`.
|
|
2604
2607
|
|
|
2605
2608
|
**Supported commands:** `init`, `use`, `list`, `schema`, `query`, `q`, `insert`, `update`, `delete`, `export`, `status`, `shell`, `doctor`, `upgrade`, `completion`
|
|
2606
2609
|
|
|
@@ -2623,7 +2626,10 @@ Atlas-style `mongodb+srv://` URIs are supported. `list` and `query` run against
|
|
|
2623
2626
|
### MongoDB-specific workflow
|
|
2624
2627
|
|
|
2625
2628
|
```bash
|
|
2626
|
-
# 1. Initialize
|
|
2629
|
+
# 1. Initialize — field-by-field (primary path)
|
|
2630
|
+
dbcli init --system mongodb --host localhost --port 27017 \
|
|
2631
|
+
--user admin --password '<secret>' --auth-source admin --name mydb
|
|
2632
|
+
# ...or a full URI (advanced fallback, e.g. Atlas SRV clusters)
|
|
2627
2633
|
dbcli init --system mongodb --uri "mongodb+srv://user:pass@cluster.example.mongodb.net/mydb"
|
|
2628
2634
|
|
|
2629
2635
|
# 2. List collections
|