dsh-dbhub-live 2.0.0 → 3.1.2
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/AGENTS.md +97 -0
- package/LICENSE +21 -21
- package/README.en.md +162 -0
- package/README.md +162 -110
- package/cordis.patch.yml +8 -8
- package/doc/REQUIREMENTS.md +65 -0
- package/lib/adhoc.mjs +97 -0
- package/lib/client.js +604 -0
- package/lib/collect.mjs +118 -0
- package/lib/config.mjs +492 -0
- package/lib/i18n.mjs +139 -0
- package/lib/index.mjs +345 -1417
- package/lib/mcp.mjs +462 -0
- package/lib/options.mjs +94 -0
- package/lib/runtime.mjs +255 -0
- package/lib/state.mjs +108 -0
- package/lib/tools.mjs +462 -0
- package/package.json +61 -39
- package/test/adhoc.test.mjs +29 -0
- package/test/client-format.test.mjs +88 -0
- package/test/i18n.test.mjs +27 -0
- package/test/init.test.mjs +163 -0
- package/test/options.test.mjs +41 -0
- package/test/state.test.mjs +85 -0
- package/test/util.test.mjs +96 -0
package/lib/i18n.mjs
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// dsh-dbhub-live: host-side locale support.
|
|
2
|
+
//
|
|
3
|
+
// The dsh UI language preference lives in the user settings document under
|
|
4
|
+
// the 'locale' namespace ('preference': 'zh' | 'en'; absence delegates to the
|
|
5
|
+
// browser and defaults to zh here). Every user/model-facing string the Host
|
|
6
|
+
// produces — tool results, error feedback, milestone logs, the status-card
|
|
7
|
+
// error source — runs through `currentT` so reports match the dsh UI
|
|
8
|
+
// language. Tool SCHEMA descriptions stay pinned Chinese (model-facing
|
|
9
|
+
// product copy; they are static per registration).
|
|
10
|
+
|
|
11
|
+
const ZH = {
|
|
12
|
+
'log.hostApply': 'host apply',
|
|
13
|
+
'log.nsRegistered': '状态命名空间已注册: dsh-dbhub-live',
|
|
14
|
+
'log.loaded': 'dbhub 服务已加载({n} 个工具)',
|
|
15
|
+
'log.readyNoSources': '插件就绪(暂无工作区数据源,可用 dbhub_configure 配置后自动启动服务)',
|
|
16
|
+
'log.initFailed': '初始化失败(状态卡片可见最近错误),下次调用自动重试',
|
|
17
|
+
'log.disabledBoot': '插件处于禁用状态,未自动初始化(可在 设置 → 插件 → dsh-dbhub-live 开启)',
|
|
18
|
+
'log.opSaved': '卡片配置:{title} 环境 {env} 已保存',
|
|
19
|
+
'log.opRemoved': '卡片配置:{title} 环境 {env} 已删除',
|
|
20
|
+
'log.opNothing': '卡片配置:{title} 无可删除的环境记录(自动发现项不会持久化)',
|
|
21
|
+
'log.opNoWs': '配置操作失败:找不到工作区 "{ws}"',
|
|
22
|
+
'log.opBad': '忽略非法的配置操作: {raw}',
|
|
23
|
+
'log.opUnknown': '忽略未知配置操作: {op}',
|
|
24
|
+
'log.syncApplied': '配置操作已生效:dbhub 工具已重新同步({n} 个)',
|
|
25
|
+
'log.syncLater': '配置操作后工具重同步失败(下次调用自动重试): {msg}',
|
|
26
|
+
'log.stateSyncFail': '状态同步失败: {msg}',
|
|
27
|
+
'log.updateCheckFailed': 'dbhub 自动更新检查失败: {msg}',
|
|
28
|
+
'result.disabled': 'dsh-dbhub-live 已禁用:所有 dbhub 工具暂不可用。请在 设置 → 插件 → dsh-dbhub-live 中重新开启。',
|
|
29
|
+
'result.dsnMissing': '缺少 dsn 参数(如 mysql://user:pass@host:3306/db)',
|
|
30
|
+
'result.masked': '检测到脱敏密码 `****`:dbhub_query / dbhub_query_objects 需要真实凭据,打码连接串不能直连。要查询已注册的环境,请改用对应的常驻工具(先用 dbhub_list_sources 查 source 值);若确需临时直连,请提供真实密码的完整 DSN。',
|
|
31
|
+
'result.noSource': '找不到数据源 "{src}":请先调用 dbhub_list_sources 查看可用 source 值(如 <工作区> 或 <工作区>_<环境>)。',
|
|
32
|
+
'result.sourcesIntro': '⚠️ 下面每个连接串都是脱敏显示(密码 ****),仅供识别,不要把它们拷进 dbhub_query 直连;查询某环境请用 dbhub_execute_sql / dbhub_search_objects,source 参数取该行的「source 值」。\n已注册连接源 {n} 个:',
|
|
33
|
+
'result.srcRow': '- {title}({badge})|环境 {env}|连接 {dsn}(打码,仅显示)|来源 {src}|source 值 {srcId}',
|
|
34
|
+
'result.sourcesEmpty': '暂无已注册的连接源(可用 dbhub_configure 或 设置 → 插件 → dsh-dbhub-live → 工作区连接 添加)。',
|
|
35
|
+
'result.badgeSaved': '已保存',
|
|
36
|
+
'result.badgeAuto': '自动',
|
|
37
|
+
'result.savedOk': '已持久化连接并注册工具({slug},环境 {env})。下次可直接使用 dbhub_execute_sql_{tool}。',
|
|
38
|
+
'result.sevSaveFail': '连接已持久化,但 dbhub 服务启动失败(下次调用会自动重试并注册工具)。见 dsh web 日志。',
|
|
39
|
+
'result.serverStartFail': 'dbhub 服务启动失败: {msg}',
|
|
40
|
+
'result.serverUnavailable': 'dbhub 服务不可用',
|
|
41
|
+
'result.noWslabel': '没有可用的工作区',
|
|
42
|
+
'result.modeCanceled': '已取消,未做任何修改',
|
|
43
|
+
'result.noDsn': '未提供 DSN,已取消',
|
|
44
|
+
'result.scanDenied': '未授权扫描,已取消(可改用“输入 DSN”或“填写分项”)',
|
|
45
|
+
'result.scanEmpty': '未找到可扫描的数据库配置文件(已跳过 node_modules/.git/target 等)。可改用“输入 DSN”或“填写分项”。',
|
|
46
|
+
'result.scanNone': '扫描了 {n} 个文件,但未提取到数据库连接。可改用“输入 DSN”或“填写分项”。',
|
|
47
|
+
'result.scanPicked': '已按你的确认持久化连接(来源: 项目文件扫描,环境 {env})并注册工具({slug})。',
|
|
48
|
+
'label.conn': '{连接: {src} → {dsn}}',
|
|
49
|
+
'label.adhocConn': '{临时连接: {dsn}}',
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const EN = {
|
|
53
|
+
'log.hostApply': 'host apply',
|
|
54
|
+
'log.nsRegistered': 'settings namespace registered: dsh-dbhub-live',
|
|
55
|
+
'log.loaded': 'dbhub server loaded ({n} tools)',
|
|
56
|
+
'log.readyNoSources': 'ready (no workspace sources yet — configure one with dbhub_configure)',
|
|
57
|
+
'log.initFailed': 'init failed (see the recent error on the status card); retried on next call',
|
|
58
|
+
'log.disabledBoot': 'plugin disabled — not initialized (enable it in Settings → Plugins → dsh-dbhub-live)',
|
|
59
|
+
'log.opSaved': 'card config: {title} environment {env} saved',
|
|
60
|
+
'log.opRemoved': 'card config: {title} environment {env} removed',
|
|
61
|
+
'log.opNothing': 'card config: {title} has no persisted environment to remove (auto-discovered rows are not persisted)',
|
|
62
|
+
'log.opNoWs': 'config operation failed: workspace "{ws}" not found',
|
|
63
|
+
'log.opBad': 'ignoring invalid config operation: {raw}',
|
|
64
|
+
'log.opUnknown': 'ignoring unknown config operation: {op}',
|
|
65
|
+
'log.syncApplied': 'config applied: dbhub tools re-synced ({n})',
|
|
66
|
+
'log.syncLater': 'tool re-sync failed after config (auto-retried on next call): {msg}',
|
|
67
|
+
'log.stateSyncFail': 'status sync failed: {msg}',
|
|
68
|
+
'log.updateCheckFailed': 'dbhub auto-update check failed: {msg}',
|
|
69
|
+
'result.disabled': 'dsh-dbhub-live is disabled: dbhub tools are unavailable. Re-enable it in Settings → Plugins → dsh-dbhub-live.',
|
|
70
|
+
'result.dsnMissing': 'missing dsn argument (e.g. mysql://user:pass@host:3306/db)',
|
|
71
|
+
'result.masked': 'masked password `****` detected: dbhub_query / dbhub_query_objects need real credentials. To query a registered environment use the persistent tools (run dbhub_list_sources for the source value); for a one-off connection pass a full DSN with the real password.',
|
|
72
|
+
'result.noSource': 'source "{src}" not found: run dbhub_list_sources first to see the available source values (e.g. <workspace> or <workspace>_<env>).',
|
|
73
|
+
'result.sourcesIntro': '⚠️ Every DSN below is masked (password ****) and only for identification — do not copy one into dbhub_query. To query an environment use dbhub_execute_sql / dbhub_search_objects with the row\u2019s source value.\n{n} registered source(s):',
|
|
74
|
+
'result.srcRow': '- {title} ({badge}) | env {env} | dsn {dsn} (masked) | source {src} | source value {srcId}',
|
|
75
|
+
'result.sourcesEmpty': 'no registered sources yet (add one with dbhub_configure or Settings → Plugins → dsh-dbhub-live → Workspace connections).',
|
|
76
|
+
'result.badgeSaved': 'saved',
|
|
77
|
+
'result.badgeAuto': 'auto',
|
|
78
|
+
'result.savedOk': 'connection persisted and tools registered ({slug}, env {env}). Next time use dbhub_execute_sql_{tool}.',
|
|
79
|
+
'result.sevSaveFail': 'connection persisted but the dbhub server failed to start (auto-retried and re-registered on next call). See the dsh web log.',
|
|
80
|
+
'result.serverStartFail': 'dbhub server failed to start: {msg}',
|
|
81
|
+
'result.serverUnavailable': 'dbhub server unavailable',
|
|
82
|
+
'result.noWslabel': 'no workspace available',
|
|
83
|
+
'result.modeCanceled': 'cancelled — nothing changed',
|
|
84
|
+
'result.noDsn': 'no DSN provided — cancelled',
|
|
85
|
+
'result.scanDenied': 'scan not authorized — cancelled (use "enter DSN" or "fill in fields" instead)',
|
|
86
|
+
'result.scanEmpty': 'no database config files found (node_modules/.git/target etc. are skipped). Use "enter DSN" or "fill in fields" instead.',
|
|
87
|
+
'result.scanNone': 'scanned {n} files but extracted no database connection. Use "enter DSN" or "fill in fields" instead.',
|
|
88
|
+
'result.scanPicked': 'connection persisted from your selection (source: project file scan, env {env}) and tools registered ({slug}).',
|
|
89
|
+
'label.conn': '{connection: {src} → {dsn}}',
|
|
90
|
+
'label.adhocConn': '{adhoc: {dsn}}',
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
let localeProvider = () => 'zh'
|
|
94
|
+
let cached = { at: 0, value: 'zh' }
|
|
95
|
+
|
|
96
|
+
/** Install the locale provider (set from apply with the settings service). */
|
|
97
|
+
export function setLocaleProvider(fn) {
|
|
98
|
+
localeProvider = fn
|
|
99
|
+
cached = { at: 0, value: 'zh' } // invalidate so the next read refreshes
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Current locale (cached up to 1s; provider errors fall back to zh). */
|
|
103
|
+
export function currentLocale() {
|
|
104
|
+
const now = Date.now()
|
|
105
|
+
if (now - cached.at >= 1000) {
|
|
106
|
+
let value = 'zh'
|
|
107
|
+
try {
|
|
108
|
+
value = localeProvider() === 'en' ? 'en' : 'zh'
|
|
109
|
+
} catch (e) {
|
|
110
|
+
value = 'zh'
|
|
111
|
+
}
|
|
112
|
+
cached = { at: now, value }
|
|
113
|
+
}
|
|
114
|
+
return cached.value
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Translate a key for the CURRENT locale; falls back to zh then the key. */
|
|
118
|
+
export function currentT(key, params) {
|
|
119
|
+
const dict = currentLocale() === 'en' ? EN : ZH
|
|
120
|
+
let s = dict[key] ?? ZH[key] ?? key
|
|
121
|
+
if (params) {
|
|
122
|
+
for (const [k, v] of Object.entries(params)) {
|
|
123
|
+
s = s.split('{' + k + '}').join(String(v))
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return s
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Translate for an explicit locale (pure — unit-testable). */
|
|
130
|
+
export function tFor(locale, key, params) {
|
|
131
|
+
const dict = locale === 'en' ? EN : ZH
|
|
132
|
+
let s = dict[key] ?? ZH[key] ?? key
|
|
133
|
+
if (params) {
|
|
134
|
+
for (const [k, v] of Object.entries(params)) {
|
|
135
|
+
s = s.split('{' + k + '}').join(String(v))
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return s
|
|
139
|
+
}
|