@yejiming/dsh-data-agent 0.0.11 → 0.0.13
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/README.en.md +70 -15
- package/README.md +70 -15
- package/conformance/dsh-ecosystem/baseline.json +59 -0
- package/conformance/dsh-ecosystem/dependencies.json +41 -0
- package/conformance/dsh-ecosystem/fixtures/host-degraded.fixture.json +12 -0
- package/conformance/dsh-ecosystem/fixtures/host-eligible.fixture.json +13 -0
- package/conformance/dsh-ecosystem/fixtures/host-rejected.fixture.json +12 -0
- package/conformance/dsh-ecosystem/fixtures/profiles/native-only/package.json +8 -0
- package/conformance/dsh-ecosystem/fixtures/profiles/native-plus-adapter/package.json +9 -0
- package/conformance/dsh-ecosystem/inventory.json +77 -0
- package/conformance/dsh-ecosystem/restrictions.json +20 -0
- package/dsh-plugin.json +67 -0
- package/lib/client.js +1352 -130
- package/lib/client.js.map +1 -1
- package/lib/{command-DuCpwVbl.js → command-utC5MHd9.js} +101 -60
- package/lib/command.js +1 -1
- package/lib/{connections-5sfdEDsG.js → connections-CHY4uB6z.js} +747 -65
- package/lib/defaults-Cngd8Tf8.js +131 -0
- package/lib/ecosystem.js +19 -0
- package/lib/index.js +40 -33
- package/lib/routes.js +5 -6
- package/lib/{tool-DVh61An-.js → tool-ZTOS4B33.js} +161 -177
- package/lib/tool.js +1 -1
- package/lib/types/analysis-html.d.ts +27 -0
- package/lib/types/analysis.d.ts +13 -1
- package/lib/types/client/DataAgentWorkbench.d.ts +1 -2
- package/lib/types/client/QueryResultTable.d.ts +13 -0
- package/lib/types/client/locales.d.ts +48 -0
- package/lib/types/client/persistence.d.ts +3 -1
- package/lib/types/client/query-export.d.ts +11 -0
- package/lib/types/client-discovery.d.ts +3 -4
- package/lib/types/clients.d.ts +14 -8
- package/lib/types/command.d.ts +2 -2
- package/lib/types/connections.d.ts +33 -4
- package/lib/types/database-types.d.ts +23 -0
- package/lib/types/defaults.d.ts +4 -0
- package/lib/types/ecosystem.d.ts +13 -0
- package/lib/types/index.d.ts +21 -16
- package/lib/types/presentation-text.d.ts +3 -0
- package/lib/types/query.d.ts +13 -11
- package/lib/types/sql.d.ts +9 -1
- package/lib/types/storage.d.ts +11 -1
- package/lib/types/structured-read.d.ts +2 -2
- package/lib/types/structured.d.ts +1 -1
- package/lib/types/tool.d.ts +5 -5
- package/lib/types/tui-connection-form.d.ts +10 -7
- package/package.json +66 -42
- package/preset/data-agent/agent.cordis.yml +9 -4
- package/lib/defaults-DP4RyRh1.js +0 -21
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { d as defaultDatabasePort$1, l as DATABASE_TYPES, p as isDatabaseType, u as databaseTypeLabel$1 } from "./defaults-Cngd8Tf8.js";
|
|
2
|
+
import { i as validatePasswordRef, r as redactSecretText } from "./connections-CHY4uB6z.js";
|
|
2
3
|
import { RUN_CODE_NAME } from "@deepseek-ai/dsh-tools";
|
|
3
4
|
//#region src/tui-connection-form.ts
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Short-lived ANSI connection form used by `/database connect` in dsh-tui.
|
|
7
|
+
*
|
|
8
|
+
* dsh-tui 0.6.x exposes commands but no public custom-form/sensitive-input
|
|
9
|
+
* slot. This adapter therefore owns a small terminal form and only activates
|
|
10
|
+
* for an interactive `dsh-tui` profile. It snapshots the host's `readable`
|
|
11
|
+
* listeners, consumes input for the lifetime of the form, then restores the
|
|
12
|
+
* listeners exactly. It never imports dsh-tui, React, or Ink.
|
|
13
|
+
* @module @yejiming/dsh-data-agent/tui-connection-form
|
|
14
|
+
*/
|
|
15
|
+
const TUI_DATABASE_TYPES = DATABASE_TYPES;
|
|
12
16
|
/** Initial form intentionally leaves host/port empty so placeholders are real defaults. */
|
|
13
17
|
function createTuiConnectionFormState(initialDraft) {
|
|
14
18
|
return {
|
|
@@ -18,6 +22,8 @@ function createTuiConnectionFormState(initialDraft) {
|
|
|
18
22
|
user: initialDraft?.user ?? "",
|
|
19
23
|
database: initialDraft?.database ?? "",
|
|
20
24
|
password: "",
|
|
25
|
+
passwordRef: initialDraft?.passwordRef ?? "",
|
|
26
|
+
secure: initialDraft?.secure ?? false,
|
|
21
27
|
readonly: initialDraft?.readonly ?? false,
|
|
22
28
|
focus: "type",
|
|
23
29
|
cursor: 0
|
|
@@ -31,38 +37,39 @@ function connectionFormDraft(state) {
|
|
|
31
37
|
port: state.port,
|
|
32
38
|
user: state.user,
|
|
33
39
|
database: state.database,
|
|
34
|
-
readonly: state.readonly
|
|
40
|
+
readonly: state.readonly,
|
|
41
|
+
...state.type === "clickhouse" ? { secure: state.secure } : {}
|
|
35
42
|
};
|
|
36
43
|
}
|
|
37
44
|
/** Relevant focus order for the selected database kind. */
|
|
38
45
|
function tuiConnectionFields(type) {
|
|
39
|
-
|
|
46
|
+
if (type === "sqlite") return [
|
|
40
47
|
"type",
|
|
41
48
|
"database",
|
|
42
49
|
"readonly",
|
|
43
50
|
"confirm",
|
|
44
51
|
"cancel"
|
|
45
|
-
]
|
|
52
|
+
];
|
|
53
|
+
const fields = [
|
|
46
54
|
"type",
|
|
47
55
|
"host",
|
|
48
56
|
"port",
|
|
49
57
|
"user",
|
|
50
58
|
"database",
|
|
51
59
|
"password",
|
|
60
|
+
"passwordRef"
|
|
61
|
+
];
|
|
62
|
+
if (type === "clickhouse") fields.push("secure");
|
|
63
|
+
return [
|
|
64
|
+
...fields,
|
|
52
65
|
"readonly",
|
|
53
66
|
"confirm",
|
|
54
67
|
"cancel"
|
|
55
68
|
];
|
|
56
69
|
}
|
|
57
70
|
/** Default network port shown as a placeholder and applied only at submit time. */
|
|
58
|
-
function defaultDatabasePort(type) {
|
|
59
|
-
|
|
60
|
-
case "mysql": return 3306;
|
|
61
|
-
case "postgres": return 5432;
|
|
62
|
-
case "oracle": return 1521;
|
|
63
|
-
case "hive": return 1e4;
|
|
64
|
-
case "impala": return 21050;
|
|
65
|
-
}
|
|
71
|
+
function defaultDatabasePort(type, secure = false) {
|
|
72
|
+
return defaultDatabasePort$1(type, secure);
|
|
66
73
|
}
|
|
67
74
|
/** Detect the supported host without coupling to dsh-tui modules. */
|
|
68
75
|
function isDshTuiTerminal(argv = process.argv, input = process.stdin, output = process.stdout) {
|
|
@@ -130,12 +137,12 @@ function updateTuiConnectionForm(current, key) {
|
|
|
130
137
|
state
|
|
131
138
|
};
|
|
132
139
|
}
|
|
133
|
-
if (state.focus === "readonly") {
|
|
140
|
+
if (state.focus === "readonly" || state.focus === "secure") {
|
|
134
141
|
if (key.name === "enter" || key.name === "space") state = {
|
|
135
142
|
...state,
|
|
136
143
|
selector: {
|
|
137
|
-
field:
|
|
138
|
-
index: state.
|
|
144
|
+
field: state.focus,
|
|
145
|
+
index: state[state.focus] ? 1 : 0
|
|
139
146
|
}
|
|
140
147
|
};
|
|
141
148
|
return {
|
|
@@ -163,7 +170,7 @@ function renderTuiConnectionForm(state, columns = 80) {
|
|
|
163
170
|
];
|
|
164
171
|
for (const field of tuiConnectionFields(state.type)) lines.push(...renderField(state, field, width));
|
|
165
172
|
if (state.error !== void 0) lines.push("", red(`! ${state.error}`));
|
|
166
|
-
lines.push("", dim("
|
|
173
|
+
lines.push("", dim(state.type === "sqlite" ? "SQLite 连接不收集数据库凭据。" : "临时密码不持久化;凭据引用可随非敏感连接 profile 恢复。"));
|
|
167
174
|
return lines.join("\n");
|
|
168
175
|
}
|
|
169
176
|
/**
|
|
@@ -322,7 +329,7 @@ function validateTuiConnectionForm(state) {
|
|
|
322
329
|
readonly: state.readonly
|
|
323
330
|
} };
|
|
324
331
|
const portText = state.port.trim();
|
|
325
|
-
const port = portText === "" ? defaultDatabasePort(state.type) : Number(portText);
|
|
332
|
+
const port = portText === "" ? defaultDatabasePort(state.type, state.secure) : Number(portText);
|
|
326
333
|
if (!Number.isInteger(port) || port < 1 || port > 65535) return { error: "端口必须是 1–65535 的整数,或留空使用默认值" };
|
|
327
334
|
const input = {
|
|
328
335
|
type: state.type,
|
|
@@ -331,9 +338,19 @@ function validateTuiConnectionForm(state) {
|
|
|
331
338
|
database,
|
|
332
339
|
readonly: state.readonly
|
|
333
340
|
};
|
|
341
|
+
if (state.type === "clickhouse") input.secure = state.secure;
|
|
334
342
|
const user = state.user.trim();
|
|
335
343
|
if (user !== "") input.user = user;
|
|
336
|
-
|
|
344
|
+
const passwordRef = state.passwordRef.trim();
|
|
345
|
+
if (state.password !== "" && passwordRef !== "") return { error: "临时密码与凭据引用不能同时填写" };
|
|
346
|
+
if (passwordRef !== "") {
|
|
347
|
+
try {
|
|
348
|
+
validatePasswordRef(passwordRef);
|
|
349
|
+
} catch (error) {
|
|
350
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
351
|
+
}
|
|
352
|
+
input.passwordRef = passwordRef;
|
|
353
|
+
} else if (state.password !== "") input.password = state.password;
|
|
337
354
|
return { input };
|
|
338
355
|
}
|
|
339
356
|
function editTextField(state, key) {
|
|
@@ -370,7 +387,7 @@ function replaceField(state, value, cursor) {
|
|
|
370
387
|
};
|
|
371
388
|
}
|
|
372
389
|
function isTextField(field) {
|
|
373
|
-
return field === "host" || field === "port" || field === "user" || field === "database" || field === "password";
|
|
390
|
+
return field === "host" || field === "port" || field === "user" || field === "database" || field === "password" || field === "passwordRef";
|
|
374
391
|
}
|
|
375
392
|
function moveFocus(state, delta) {
|
|
376
393
|
const fields = tuiConnectionFields(state.type);
|
|
@@ -395,16 +412,37 @@ function updateOpenSelector(state, key) {
|
|
|
395
412
|
kind: "editing",
|
|
396
413
|
state: closeSelector(state)
|
|
397
414
|
};
|
|
398
|
-
if (key.name === "enter")
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
type:
|
|
403
|
-
|
|
415
|
+
if (key.name === "enter") {
|
|
416
|
+
let selected;
|
|
417
|
+
if (selector.field === "type") {
|
|
418
|
+
const type = TUI_DATABASE_TYPES[selector.index];
|
|
419
|
+
const previousDefault = state.type === "sqlite" ? "" : String(defaultDatabasePort(state.type, state.secure));
|
|
420
|
+
const secure = type === "clickhouse" && state.secure;
|
|
421
|
+
const port = state.port === "" || state.port === previousDefault ? type === "sqlite" ? "" : String(defaultDatabasePort(type, secure)) : state.port;
|
|
422
|
+
selected = {
|
|
423
|
+
...state,
|
|
424
|
+
type,
|
|
425
|
+
secure,
|
|
426
|
+
port
|
|
427
|
+
};
|
|
428
|
+
} else if (selector.field === "secure") {
|
|
429
|
+
const secure = selector.index === 1;
|
|
430
|
+
const previousDefault = String(defaultDatabasePort("clickhouse", state.secure));
|
|
431
|
+
const port = state.port === "" || state.port === previousDefault ? String(defaultDatabasePort("clickhouse", secure)) : state.port;
|
|
432
|
+
selected = {
|
|
433
|
+
...state,
|
|
434
|
+
secure,
|
|
435
|
+
port
|
|
436
|
+
};
|
|
437
|
+
} else selected = {
|
|
404
438
|
...state,
|
|
405
439
|
readonly: selector.index === 1
|
|
406
|
-
}
|
|
407
|
-
|
|
440
|
+
};
|
|
441
|
+
return {
|
|
442
|
+
kind: "editing",
|
|
443
|
+
state: closeSelector(selected)
|
|
444
|
+
};
|
|
445
|
+
}
|
|
408
446
|
let delta = 0;
|
|
409
447
|
if (key.name === "up" || key.name === "left") delta = -1;
|
|
410
448
|
if (key.name === "down" || key.name === "right") delta = 1;
|
|
@@ -440,19 +478,20 @@ function renderField(state, field, width) {
|
|
|
440
478
|
let placeholder = false;
|
|
441
479
|
if (field === "type") value = databaseTypeLabel(state.type);
|
|
442
480
|
else if (field === "readonly") value = state.readonly ? "是" : "否";
|
|
481
|
+
else if (field === "secure") value = state.secure ? "是" : "否";
|
|
443
482
|
else {
|
|
444
483
|
const raw = state[field];
|
|
445
484
|
if (field === "password") value = "*".repeat([...raw].length);
|
|
446
485
|
else value = raw;
|
|
447
486
|
if (value === "") {
|
|
448
487
|
placeholder = true;
|
|
449
|
-
value = field === "host" ? "127.0.0.1(默认)" : field === "port" ? `${defaultDatabasePort(state.type)}(默认)` : field === "password" ? "可留空" : field === "user" ? "可留空" : "请输入";
|
|
488
|
+
value = field === "host" ? "127.0.0.1(默认)" : field === "port" ? `${defaultDatabasePort(state.type, state.secure)}(默认)` : field === "password" ? "可留空" : field === "passwordRef" ? "例如 DB_PASSWORD,可留空" : field === "user" ? "可留空" : "请输入";
|
|
450
489
|
}
|
|
451
490
|
}
|
|
452
491
|
const maxValue = Math.max(8, width - 20);
|
|
453
492
|
const shown = truncate(value.replace(/[\r\n\u001B]/g, " "), maxValue);
|
|
454
493
|
const content = placeholder ? dim(shown) : shown;
|
|
455
|
-
const expandable = field === "type" || field === "readonly";
|
|
494
|
+
const expandable = field === "type" || field === "readonly" || field === "secure";
|
|
456
495
|
const line = `${pointer} ${label.padEnd(8, " ")} [ ${focused ? cyan(content) : content}${expandable ? " ▾" : ""} ]`;
|
|
457
496
|
if (state.selector?.field !== field) return [line];
|
|
458
497
|
return [line, ...renderSelectorOptions(state)];
|
|
@@ -460,20 +499,13 @@ function renderField(state, field, width) {
|
|
|
460
499
|
function renderSelectorOptions(state) {
|
|
461
500
|
const selector = state.selector;
|
|
462
501
|
const labels = selector.field === "type" ? TUI_DATABASE_TYPES.map(databaseTypeLabel) : ["否", "是"];
|
|
463
|
-
const selectedIndex = selector.field === "type" ? TUI_DATABASE_TYPES.indexOf(state.type) : state.
|
|
502
|
+
const selectedIndex = selector.field === "type" ? TUI_DATABASE_TYPES.indexOf(state.type) : state[selector.field] ? 1 : 0;
|
|
464
503
|
return labels.map((label, index) => {
|
|
465
504
|
return ` ${index === selector.index ? cyan("›") : " "} ${index === selectedIndex ? cyan("●") : dim("○")} ${index === selector.index ? cyan(bold(label)) : label}`;
|
|
466
505
|
});
|
|
467
506
|
}
|
|
468
507
|
function databaseTypeLabel(type) {
|
|
469
|
-
|
|
470
|
-
case "mysql": return "MySQL";
|
|
471
|
-
case "postgres": return "PostgreSQL";
|
|
472
|
-
case "sqlite": return "SQLite";
|
|
473
|
-
case "oracle": return "Oracle";
|
|
474
|
-
case "hive": return "Hive";
|
|
475
|
-
case "impala": return "Impala";
|
|
476
|
-
}
|
|
508
|
+
return databaseTypeLabel$1(type);
|
|
477
509
|
}
|
|
478
510
|
function fieldLabel(field, type) {
|
|
479
511
|
switch (field) {
|
|
@@ -483,6 +515,8 @@ function fieldLabel(field, type) {
|
|
|
483
515
|
case "user": return "数据库用户";
|
|
484
516
|
case "database": return type === "sqlite" ? "文件路径" : "数据库名";
|
|
485
517
|
case "password": return "密码";
|
|
518
|
+
case "passwordRef": return "凭据引用";
|
|
519
|
+
case "secure": return "HTTPS";
|
|
486
520
|
case "readonly": return "只读模式";
|
|
487
521
|
}
|
|
488
522
|
}
|
|
@@ -513,7 +547,7 @@ const inject = [
|
|
|
513
547
|
const DATABASE_COMMAND_USAGE = [
|
|
514
548
|
"用法:",
|
|
515
549
|
" /database status",
|
|
516
|
-
|
|
550
|
+
` /database connect --type <${DATABASE_TYPES.join("|")}> --database <name|path> [--host <host>] [--port <port>] [--user <user>] [--password-ref <REF>] [--readonly] [--secure]`,
|
|
517
551
|
" /database test",
|
|
518
552
|
" /database disconnect",
|
|
519
553
|
"安全提示:TUI 无参数 connect 可输入掩码临时密码;命令参数不接受 --password,请使用 --password-ref。"
|
|
@@ -625,6 +659,7 @@ function parseDatabaseAction(rawInput) {
|
|
|
625
659
|
function parseConnectArguments(tokens) {
|
|
626
660
|
const values = /* @__PURE__ */ new Map();
|
|
627
661
|
let readonly;
|
|
662
|
+
let secure;
|
|
628
663
|
for (let index = 0; index < tokens.length; index += 1) {
|
|
629
664
|
const token = tokens[index];
|
|
630
665
|
if (token === "--password" || token.startsWith("--password=") || token.startsWith("password=")) throw new Error("安全限制:/database 不接受明文密码参数;请改用 --password-ref <REF>。");
|
|
@@ -636,6 +671,14 @@ function parseConnectArguments(tokens) {
|
|
|
636
671
|
readonly = false;
|
|
637
672
|
continue;
|
|
638
673
|
}
|
|
674
|
+
if (token === "--secure") {
|
|
675
|
+
secure = true;
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
if (token === "--insecure") {
|
|
679
|
+
secure = false;
|
|
680
|
+
continue;
|
|
681
|
+
}
|
|
639
682
|
const assignment = token.startsWith("--") ? token.slice(2).split("=", 2) : token.split("=", 2);
|
|
640
683
|
let key;
|
|
641
684
|
let value;
|
|
@@ -684,6 +727,7 @@ function parseConnectArguments(tokens) {
|
|
|
684
727
|
input.port = number;
|
|
685
728
|
}
|
|
686
729
|
if (readonly !== void 0) input.readonly = readonly;
|
|
730
|
+
if (type === "clickhouse" && secure !== void 0) input.secure = secure;
|
|
687
731
|
return input;
|
|
688
732
|
}
|
|
689
733
|
/** Render a public summary; no password-bearing field exists in the type. */
|
|
@@ -697,6 +741,7 @@ function formatConnectionStatus(summary) {
|
|
|
697
741
|
`数据库:${summary.database}`,
|
|
698
742
|
`只读:${summary.readonly === true ? "是" : "否"}`
|
|
699
743
|
];
|
|
744
|
+
if (summary.type === "clickhouse") lines.push(`HTTPS:${summary.secure === true ? "是" : "否"}`);
|
|
700
745
|
if (summary.user !== void 0) lines.push(`用户:${summary.user}`);
|
|
701
746
|
if (summary.profileId !== void 0) lines.push(`Profile:${summary.name ?? summary.profileId}`);
|
|
702
747
|
if (summary.passwordRef !== void 0) lines.push(`凭据引用:${summary.passwordRef}`);
|
|
@@ -749,7 +794,7 @@ async function askForConnection(ctx, invocation, interaction) {
|
|
|
749
794
|
{
|
|
750
795
|
id: "port",
|
|
751
796
|
header: "端口",
|
|
752
|
-
question: `数据库端口(留空使用 ${defaultDatabasePort(typeValue)})`
|
|
797
|
+
question: typeValue === "clickhouse" ? `数据库端口(留空使用HTTP ${defaultDatabasePort$1("clickhouse")};HTTPS ${defaultDatabasePort$1("clickhouse", true)})` : `数据库端口(留空使用 ${defaultDatabasePort$1(typeValue)})`
|
|
753
798
|
},
|
|
754
799
|
{
|
|
755
800
|
id: "user",
|
|
@@ -766,6 +811,12 @@ async function askForConnection(ctx, invocation, interaction) {
|
|
|
766
811
|
header: "凭据引用",
|
|
767
812
|
question: "DSH credential reference(可留空)"
|
|
768
813
|
},
|
|
814
|
+
...typeValue === "clickhouse" ? [{
|
|
815
|
+
id: "secure",
|
|
816
|
+
header: "HTTPS",
|
|
817
|
+
question: "是否使用HTTPS并验证服务器证书?",
|
|
818
|
+
options: [{ label: "是" }, { label: "否" }]
|
|
819
|
+
}] : [],
|
|
769
820
|
{
|
|
770
821
|
id: "readonly",
|
|
771
822
|
header: "只读",
|
|
@@ -787,8 +838,9 @@ async function askForConnection(ctx, invocation, interaction) {
|
|
|
787
838
|
};
|
|
788
839
|
if (typeValue !== "sqlite") {
|
|
789
840
|
input.host = answerValue(details, "host")?.trim() || "127.0.0.1";
|
|
841
|
+
if (typeValue === "clickhouse") input.secure = answerValue(details, "secure") === "是";
|
|
790
842
|
const portText = answerValue(details, "port")?.trim();
|
|
791
|
-
input.port = portText === void 0 || portText === "" ? defaultDatabasePort(typeValue) : Number(portText);
|
|
843
|
+
input.port = portText === void 0 || portText === "" ? defaultDatabasePort$1(typeValue, input.secure === true) : Number(portText);
|
|
792
844
|
const user = answerValue(details, "user")?.trim();
|
|
793
845
|
if (user !== void 0 && user !== "") input.user = user;
|
|
794
846
|
const passwordRef = answerValue(details, "passwordRef")?.trim();
|
|
@@ -800,14 +852,6 @@ async function askForConnection(ctx, invocation, interaction) {
|
|
|
800
852
|
throw error;
|
|
801
853
|
}
|
|
802
854
|
}
|
|
803
|
-
const DATABASE_TYPES = [
|
|
804
|
-
"mysql",
|
|
805
|
-
"postgres",
|
|
806
|
-
"sqlite",
|
|
807
|
-
"oracle",
|
|
808
|
-
"hive",
|
|
809
|
-
"impala"
|
|
810
|
-
];
|
|
811
855
|
const CONNECT_ARGUMENTS = /* @__PURE__ */ new Set([
|
|
812
856
|
"type",
|
|
813
857
|
"host",
|
|
@@ -818,9 +862,6 @@ const CONNECT_ARGUMENTS = /* @__PURE__ */ new Set([
|
|
|
818
862
|
"profileId",
|
|
819
863
|
"name"
|
|
820
864
|
]);
|
|
821
|
-
function isDatabaseType(value) {
|
|
822
|
-
return typeof value === "string" && DATABASE_TYPES.includes(value);
|
|
823
|
-
}
|
|
824
865
|
function normalizeArgumentName(value) {
|
|
825
866
|
return value.replace(/-([a-z])/g, (_match, letter) => letter.toUpperCase());
|
|
826
867
|
}
|
package/lib/command.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as formatConnectionStatus, c as parseConnectArguments, i as executeDatabaseCommand, l as parseDatabaseAction, n as DATA_AGENT_TOOL_NAMES, o as inject, r as apply, s as name, t as DATABASE_COMMAND_USAGE } from "./command-
|
|
1
|
+
import { a as formatConnectionStatus, c as parseConnectArguments, i as executeDatabaseCommand, l as parseDatabaseAction, n as DATA_AGENT_TOOL_NAMES, o as inject, r as apply, s as name, t as DATABASE_COMMAND_USAGE } from "./command-utC5MHd9.js";
|
|
2
2
|
export { DATABASE_COMMAND_USAGE, DATA_AGENT_TOOL_NAMES, apply, executeDatabaseCommand, formatConnectionStatus, inject, name, parseConnectArguments, parseDatabaseAction };
|