dsh-dbhub-live 5.0.1 → 5.2.0-dev.3

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.
Files changed (50) hide show
  1. package/AGENTS.md +95 -209
  2. package/README.en.md +251 -169
  3. package/README.md +251 -169
  4. package/doc/ARCHITECTURE.md +108 -0
  5. package/doc/CLIENT.md +124 -0
  6. package/doc/DESENSITIZE.md +56 -0
  7. package/doc/DEVELOPMENT.md +139 -0
  8. package/doc/IMPACT-MATRIX.md +36 -0
  9. package/doc/RELEASE.md +93 -0
  10. package/doc/REQUIREMENTS.md +177 -105
  11. package/doc/images/chat-query.png +0 -0
  12. package/doc/images/row-editor.png +0 -0
  13. package/doc/images/settings-page.png +0 -0
  14. package/lib/adhoc.mjs +412 -34
  15. package/lib/capability.mjs +157 -0
  16. package/lib/client.js +1243 -80
  17. package/lib/config.mjs +370 -21
  18. package/lib/i18n.mjs +119 -4
  19. package/lib/index.mjs +401 -43
  20. package/lib/mcp.mjs +496 -391
  21. package/lib/meta.mjs +267 -0
  22. package/lib/options.mjs +25 -5
  23. package/lib/policy.mjs +92 -0
  24. package/lib/toml.mjs +188 -0
  25. package/lib/tools.mjs +1093 -827
  26. package/lib/update.mjs +244 -0
  27. package/package.json +34 -10
  28. package/scripts/desensitize-check.mjs +10 -3
  29. package/scripts/desensitize.config.mjs +255 -237
  30. package/scripts/docs-check.mjs +214 -0
  31. package/scripts/release-preflight.mjs +180 -0
  32. package/scripts/render-check.mjs +1366 -843
  33. package/test/adhoc-toml.test.mjs +365 -0
  34. package/test/bridge.test.mjs +227 -185
  35. package/test/capability.test.mjs +231 -0
  36. package/test/client-format.test.mjs +515 -352
  37. package/test/configure-options.test.mjs +244 -0
  38. package/test/configure-ssh.test.mjs +232 -0
  39. package/test/copy-from.test.mjs +155 -0
  40. package/test/env-options.test.mjs +456 -0
  41. package/test/meta.test.mjs +234 -0
  42. package/test/options.test.mjs +160 -123
  43. package/test/policy.test.mjs +132 -0
  44. package/test/row-cache.test.mjs +237 -138
  45. package/test/ssh-probe.test.mjs +834 -0
  46. package/test/test-op-fastpath.test.mjs +208 -0
  47. package/test/toml.test.mjs +352 -0
  48. package/test/update.test.mjs +270 -0
  49. package/test/util.test.mjs +17 -0
  50. package/test/zero-knowledge.test.mjs +120 -78
@@ -0,0 +1,157 @@
1
+ // dsh-dbhub-live: dbhub version / capability guard.
2
+ //
3
+ // The read-only and SSH-tunnel features are translated into dbhub's TOML
4
+ // dialect (`[[tools]] readonly = true`, `ssh_*` per-source fields). That
5
+ // dialect exists only from dbhub 1.x on: the 0.x spelling (`read_only` on a
6
+ // source, or the `--readonly` flag) is either REJECTED by 1.4+ or — far worse —
7
+ // silently IGNORED, which would look like "read-only is configured" while every
8
+ // write still goes through. Generating an unverified old spelling is therefore
9
+ // forbidden; when the installed dbhub is too old we refuse the two features
10
+ // with an upgrade hint instead of degrading silently.
11
+ //
12
+ // Detection is deliberately file-based (no extra process spawn): the executable
13
+ // we resolved lives inside a package directory (`…/node_modules/.bin/dbhub.cmd`
14
+ // next to `…/node_modules/@bytebase/dbhub/package.json`) or under mise's
15
+ // `npm-bytebase-dbhub/<version>/` layout, and both carry the version.
16
+ // Pure module: `node:fs` + `node:path` only, no Cordis service.
17
+
18
+ import { existsSync, readFileSync, statSync } from 'node:fs'
19
+ import { dirname, join, resolve } from 'node:path'
20
+
21
+ /** Minimum dbhub version whose TOML dialect this plugin generates. */
22
+ export const DBHUB_MIN_VERSION = '1.4.0'
23
+ /** Versions below this predate the TOML tool model entirely. */
24
+ export const DBHUB_TOML_SINCE = '1.0.0'
25
+
26
+ /**
27
+ * Parse a semver-ish string into `{ major, minor, patch }`.
28
+ * Accepts a leading `v`, prerelease/build suffixes, and returns `null` when
29
+ * there is no leading numeric triplet.
30
+ */
31
+ export function parseVersion(text) {
32
+ const m = /^\s*v?(\d+)\.(\d+)(?:\.(\d+))?/.exec(String(text || ''))
33
+ if (!m) return null
34
+ return { major: Number(m[1]), minor: Number(m[2]), patch: Number(m[3] || 0) }
35
+ }
36
+
37
+ /** Compare two parsed versions: <0, 0, >0. */
38
+ export function compareVersions(a, b) {
39
+ for (const k of ['major', 'minor', 'patch']) {
40
+ const x = (a && a[k]) || 0
41
+ const y = (b && b[k]) || 0
42
+ if (x !== y) return x - y
43
+ }
44
+ return 0
45
+ }
46
+
47
+ /** True when `version` (parsed) is at or above `min` (string). */
48
+ export function atLeast(version, min) {
49
+ const floor = parseVersion(min)
50
+ if (!version || !floor) return false
51
+ return compareVersions(version, floor) >= 0
52
+ }
53
+
54
+ /**
55
+ * Read the version out of a mise-style layout path:
56
+ * `…/npm-bytebase-dbhub/1.4.0/node_modules/.bin/dbhub.cmd`.
57
+ * @returns a version string, or `''`.
58
+ */
59
+ export function versionFromMisePath(exe) {
60
+ const m = /npm-bytebase-dbhub[\\/]([^\\/]+)[\\/]/i.exec(String(exe || ''))
61
+ if (!m) return ''
62
+ return parseVersion(m[1]) ? m[1] : ''
63
+ }
64
+
65
+ /**
66
+ * Walk up from the executable (bounded) looking for the owning package.json and
67
+ * read its version. Works for the auto-managed install
68
+ * (`<RUNTIME_DIR>/node_modules/@bytebase/dbhub/package.json`) and for any npm /
69
+ * pnpm / mise layout that keeps the manifest above the shim.
70
+ * @returns a version string, or `''`.
71
+ */
72
+ export function versionFromPackageJson(exe) {
73
+ const raw = String(exe || '').trim()
74
+ if (!raw) return ''
75
+ let dir
76
+ try {
77
+ dir = dirname(resolve(raw))
78
+ } catch (e) {
79
+ return ''
80
+ }
81
+ for (let i = 0; i < 6 && dir; i++) {
82
+ // Three layouts matter, and all of them must be probed at EVERY level:
83
+ // · `<pkg>/package.json` — the mise shim package that pins dbhub;
84
+ // · `<dir>/node_modules/@bytebase/dbhub/package.json` — what
85
+ // `npm install @bytebase/dbhub --prefix <dir>` produces, i.e. the
86
+ // DEFAULT auto-managed install (and `npm -g` too);
87
+ // · `<dir>/node_modules/dbhub/package.json` — an unscoped install.
88
+ for (const candidate of [
89
+ join(dir, 'package.json'),
90
+ join(dir, 'node_modules', '@bytebase', 'dbhub', 'package.json'),
91
+ join(dir, 'node_modules', 'dbhub', 'package.json'),
92
+ ]) {
93
+ try {
94
+ if (!existsSync(candidate) || !statSync(candidate).isFile()) continue
95
+ const doc = JSON.parse(readFileSync(candidate, 'utf8'))
96
+ const version = parseVersion(doc && doc.version) ? String(doc.version) : ''
97
+ if (!version) continue
98
+ // Only trust a manifest that IS dbhub: an unrelated package.json above
99
+ // us (this plugin's own, say) must never lend it its version number.
100
+ const name = String((doc && doc.name) || '')
101
+ if (name === '@bytebase/dbhub' || name === 'dbhub') return version
102
+ } catch (e) {
103
+ /* keep walking */
104
+ }
105
+ }
106
+ const parent = dirname(dir)
107
+ if (!parent || parent === dir) break
108
+ dir = parent
109
+ }
110
+ return ''
111
+ }
112
+
113
+ /** Resolve the installed dbhub version from an executable path ('' when unknown). */
114
+ export function detectVersion(exe) {
115
+ return versionFromMisePath(exe) || versionFromPackageJson(exe)
116
+ }
117
+
118
+ /**
119
+ * Map a version onto the two generated features.
120
+ * - `< 1.0.0` → neither feature is supported (upgrade hint);
121
+ * - `1.0.0–1.3.x` → allowed, but flagged "untested" so the UI can warn;
122
+ * - `>= 1.4.0` → supported (the dialect this plugin was measured against);
123
+ * - unknown → allowed with a warning (we cannot prove the version; the
124
+ * real failure, if any, surfaces as a dbhub fatal error).
125
+ * @returns `{ version, readonlyTools, ssh, warning }`.
126
+ */
127
+ export function capabilitiesOf(rawVersion) {
128
+ const version = String(rawVersion || '')
129
+ const parsed = parseVersion(version)
130
+ if (!parsed) {
131
+ return { version, readonlyTools: true, ssh: true, warning: 'unknown' }
132
+ }
133
+ if (!atLeast(parsed, DBHUB_TOML_SINCE)) {
134
+ return { version, readonlyTools: false, ssh: false, warning: 'tooOld' }
135
+ }
136
+ if (!atLeast(parsed, DBHUB_MIN_VERSION)) {
137
+ return { version, readonlyTools: true, ssh: true, warning: 'untested' }
138
+ }
139
+ return { version, readonlyTools: true, ssh: true, warning: '' }
140
+ }
141
+
142
+ /**
143
+ * Detect the capabilities of one resolved dbhub executable.
144
+ * Never throws and never blocks: an unresolvable version is reported as
145
+ * `unknown` and the features stay enabled (the caller only *uses* this on
146
+ * read-only / SSH environments, and an genuine incompatibility surfaces as a
147
+ * clear dbhub error).
148
+ * @param exe - resolved dbhub executable path (may be undefined at boot).
149
+ * @returns `{ version, readonlyTools, ssh, warning }`.
150
+ */
151
+ export function detectDbhubCapabilities(exe) {
152
+ try {
153
+ return capabilitiesOf(detectVersion(exe))
154
+ } catch (e) {
155
+ return { version: '', readonlyTools: true, ssh: true, warning: 'unknown' }
156
+ }
157
+ }