spindb 0.37.2 → 0.38.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.
Files changed (811) hide show
  1. package/dist/cli/bin.js +9 -0
  2. package/dist/cli/bin.js.map +1 -0
  3. package/dist/cli/commands/attach.js +102 -0
  4. package/dist/cli/commands/attach.js.map +1 -0
  5. package/dist/cli/commands/backup.js +197 -0
  6. package/dist/cli/commands/backup.js.map +1 -0
  7. package/dist/cli/commands/backups.js +190 -0
  8. package/dist/cli/commands/backups.js.map +1 -0
  9. package/dist/cli/commands/clone.js +119 -0
  10. package/dist/cli/commands/clone.js.map +1 -0
  11. package/dist/cli/commands/config.js +276 -0
  12. package/dist/cli/commands/config.js.map +1 -0
  13. package/dist/cli/commands/connect.js +559 -0
  14. package/dist/cli/commands/connect.js.map +1 -0
  15. package/dist/cli/commands/create.js +952 -0
  16. package/dist/cli/commands/create.js.map +1 -0
  17. package/dist/cli/commands/databases.js +485 -0
  18. package/dist/cli/commands/databases.js.map +1 -0
  19. package/dist/cli/commands/delete.js +106 -0
  20. package/dist/cli/commands/delete.js.map +1 -0
  21. package/dist/cli/commands/deps.js +238 -0
  22. package/dist/cli/commands/deps.js.map +1 -0
  23. package/dist/cli/commands/detach.js +81 -0
  24. package/dist/cli/commands/detach.js.map +1 -0
  25. package/dist/cli/commands/doctor.js +567 -0
  26. package/dist/cli/commands/doctor.js.map +1 -0
  27. package/dist/cli/commands/duckdb.js +207 -0
  28. package/dist/cli/commands/duckdb.js.map +1 -0
  29. package/dist/cli/commands/edit.js +524 -0
  30. package/dist/cli/commands/edit.js.map +1 -0
  31. package/dist/cli/commands/engines.js +1414 -0
  32. package/dist/cli/commands/engines.js.map +1 -0
  33. package/dist/cli/commands/export.js +383 -0
  34. package/dist/cli/commands/export.js.map +1 -0
  35. package/dist/cli/commands/info.js +270 -0
  36. package/dist/cli/commands/info.js.map +1 -0
  37. package/dist/cli/commands/list.js +215 -0
  38. package/dist/cli/commands/list.js.map +1 -0
  39. package/dist/cli/commands/logs.js +81 -0
  40. package/dist/cli/commands/logs.js.map +1 -0
  41. package/dist/cli/commands/menu/backup-handlers.js +1202 -0
  42. package/dist/cli/commands/menu/backup-handlers.js.map +1 -0
  43. package/dist/cli/commands/menu/container-handlers.js +1788 -0
  44. package/dist/cli/commands/menu/container-handlers.js.map +1 -0
  45. package/dist/cli/commands/menu/engine-handlers.js +235 -0
  46. package/dist/cli/commands/menu/engine-handlers.js.map +1 -0
  47. package/dist/cli/commands/menu/index.js +266 -0
  48. package/dist/cli/commands/menu/index.js.map +1 -0
  49. package/dist/cli/commands/menu/settings-handlers.js +320 -0
  50. package/dist/cli/commands/menu/settings-handlers.js.map +1 -0
  51. package/dist/cli/commands/menu/shared.js +13 -0
  52. package/dist/cli/commands/menu/shared.js.map +1 -0
  53. package/dist/cli/commands/menu/shell-handlers.js +1573 -0
  54. package/dist/cli/commands/menu/shell-handlers.js.map +1 -0
  55. package/dist/cli/commands/menu/sql-handlers.js +185 -0
  56. package/dist/cli/commands/menu/sql-handlers.js.map +1 -0
  57. package/dist/cli/commands/menu/update-handlers.js +322 -0
  58. package/dist/cli/commands/menu/update-handlers.js.map +1 -0
  59. package/dist/cli/commands/menu/validators.js +9 -0
  60. package/dist/cli/commands/menu/validators.js.map +1 -0
  61. package/dist/cli/commands/ports.js +166 -0
  62. package/dist/cli/commands/ports.js.map +1 -0
  63. package/dist/cli/commands/pull.js +166 -0
  64. package/dist/cli/commands/pull.js.map +1 -0
  65. package/dist/cli/commands/query.js +180 -0
  66. package/dist/cli/commands/query.js.map +1 -0
  67. package/dist/cli/commands/restore.js +428 -0
  68. package/dist/cli/commands/restore.js.map +1 -0
  69. package/dist/cli/commands/run.js +115 -0
  70. package/dist/cli/commands/run.js.map +1 -0
  71. package/dist/cli/commands/self-update.js +99 -0
  72. package/dist/cli/commands/self-update.js.map +1 -0
  73. package/dist/cli/commands/sqlite.js +207 -0
  74. package/dist/cli/commands/sqlite.js.map +1 -0
  75. package/dist/cli/commands/start.js +196 -0
  76. package/dist/cli/commands/start.js.map +1 -0
  77. package/dist/cli/commands/stop.js +182 -0
  78. package/dist/cli/commands/stop.js.map +1 -0
  79. package/dist/cli/commands/url.js +88 -0
  80. package/dist/cli/commands/url.js.map +1 -0
  81. package/dist/cli/commands/users.js +189 -0
  82. package/dist/cli/commands/users.js.map +1 -0
  83. package/dist/cli/commands/version.js +52 -0
  84. package/dist/cli/commands/version.js.map +1 -0
  85. package/dist/cli/commands/which.js +258 -0
  86. package/dist/cli/commands/which.js.map +1 -0
  87. package/dist/cli/constants.js +212 -0
  88. package/dist/cli/constants.js.map +1 -0
  89. package/dist/cli/helpers.js +1120 -0
  90. package/dist/cli/helpers.js.map +1 -0
  91. package/dist/cli/index.js +146 -0
  92. package/dist/cli/index.js.map +1 -0
  93. package/dist/cli/ui/prompts.js +1002 -0
  94. package/dist/cli/ui/prompts.js.map +1 -0
  95. package/dist/cli/ui/spinner.js +74 -0
  96. package/dist/cli/ui/spinner.js.map +1 -0
  97. package/dist/cli/ui/theme.js +99 -0
  98. package/dist/cli/ui/theme.js.map +1 -0
  99. package/dist/cli/utils/file-follower.js +79 -0
  100. package/dist/cli/utils/file-follower.js.map +1 -0
  101. package/dist/config/backup-formats.js +363 -0
  102. package/dist/config/backup-formats.js.map +1 -0
  103. package/dist/config/defaults.js +25 -0
  104. package/dist/config/defaults.js.map +1 -0
  105. package/dist/config/engine-defaults.js +303 -0
  106. package/dist/config/engine-defaults.js.map +1 -0
  107. package/dist/config/engines-registry.js +103 -0
  108. package/dist/config/engines-registry.js.map +1 -0
  109. package/dist/config/os-dependencies.js +767 -0
  110. package/dist/config/os-dependencies.js.map +1 -0
  111. package/dist/config/paths.js +156 -0
  112. package/dist/config/paths.js.map +1 -0
  113. package/dist/config/version.js +3 -0
  114. package/dist/config/version.js.map +1 -0
  115. package/dist/core/backup-restore.js +219 -0
  116. package/dist/core/backup-restore.js.map +1 -0
  117. package/dist/core/base-binary-manager.js +403 -0
  118. package/dist/core/base-binary-manager.js.map +1 -0
  119. package/dist/core/base-document-binary-manager.js +364 -0
  120. package/dist/core/base-document-binary-manager.js.map +1 -0
  121. package/dist/core/base-embedded-binary-manager.js +364 -0
  122. package/dist/core/base-embedded-binary-manager.js.map +1 -0
  123. package/dist/core/base-server-binary-manager.js +368 -0
  124. package/dist/core/base-server-binary-manager.js.map +1 -0
  125. package/dist/core/config-manager.js +495 -0
  126. package/dist/core/config-manager.js.map +1 -0
  127. package/dist/core/container-manager.js +609 -0
  128. package/dist/core/container-manager.js.map +1 -0
  129. package/dist/core/credential-generator.js +67 -0
  130. package/dist/core/credential-generator.js.map +1 -0
  131. package/dist/core/credential-manager.js +211 -0
  132. package/dist/core/credential-manager.js.map +1 -0
  133. package/dist/core/dblab-utils.js +105 -0
  134. package/dist/core/dblab-utils.js.map +1 -0
  135. package/dist/core/dependency-manager.js +359 -0
  136. package/dist/core/dependency-manager.js.map +1 -0
  137. package/dist/core/docker-exporter.js +1077 -0
  138. package/dist/core/docker-exporter.js.map +1 -0
  139. package/dist/core/error-handler.js +295 -0
  140. package/dist/core/error-handler.js.map +1 -0
  141. package/dist/core/fs-error-utils.js +74 -0
  142. package/dist/core/fs-error-utils.js.map +1 -0
  143. package/dist/core/homebrew-version-manager.js +280 -0
  144. package/dist/core/homebrew-version-manager.js.map +1 -0
  145. package/dist/core/hostdb-client.js +252 -0
  146. package/dist/core/hostdb-client.js.map +1 -0
  147. package/dist/core/hostdb-metadata.js +243 -0
  148. package/dist/core/hostdb-metadata.js.map +1 -0
  149. package/dist/core/hostdb-releases-factory.js +161 -0
  150. package/dist/core/hostdb-releases-factory.js.map +1 -0
  151. package/dist/core/library-env.js +88 -0
  152. package/dist/core/library-env.js.map +1 -0
  153. package/dist/core/pgweb-utils.js +53 -0
  154. package/dist/core/pgweb-utils.js.map +1 -0
  155. package/dist/core/platform-service.js +632 -0
  156. package/dist/core/platform-service.js.map +1 -0
  157. package/dist/core/port-manager.js +136 -0
  158. package/dist/core/port-manager.js.map +1 -0
  159. package/dist/core/process-manager.js +445 -0
  160. package/dist/core/process-manager.js.map +1 -0
  161. package/dist/core/pull-manager.js +418 -0
  162. package/dist/core/pull-manager.js.map +1 -0
  163. package/dist/core/query-parser.js +449 -0
  164. package/dist/core/query-parser.js.map +1 -0
  165. package/dist/core/spawn-utils.js +90 -0
  166. package/dist/core/spawn-utils.js.map +1 -0
  167. package/dist/core/start-with-retry.js +90 -0
  168. package/dist/core/start-with-retry.js.map +1 -0
  169. package/dist/core/test-cleanup.js +85 -0
  170. package/dist/core/test-cleanup.js.map +1 -0
  171. package/dist/core/tls-generator.js +84 -0
  172. package/dist/core/tls-generator.js.map +1 -0
  173. package/dist/core/transaction-manager.js +139 -0
  174. package/dist/core/transaction-manager.js.map +1 -0
  175. package/dist/core/update-manager.js +241 -0
  176. package/dist/core/update-manager.js.map +1 -0
  177. package/dist/core/version-migration.js +260 -0
  178. package/dist/core/version-migration.js.map +1 -0
  179. package/dist/core/version-utils.js +91 -0
  180. package/dist/core/version-utils.js.map +1 -0
  181. package/dist/engines/base-engine.js +179 -0
  182. package/dist/engines/base-engine.js.map +1 -0
  183. package/dist/engines/clickhouse/backup.js +289 -0
  184. package/dist/engines/clickhouse/backup.js.map +1 -0
  185. package/dist/engines/clickhouse/binary-manager.js +145 -0
  186. package/dist/engines/clickhouse/binary-manager.js.map +1 -0
  187. package/dist/engines/clickhouse/binary-urls.js +100 -0
  188. package/dist/engines/clickhouse/binary-urls.js.map +1 -0
  189. package/dist/engines/clickhouse/cli-utils.js +143 -0
  190. package/dist/engines/clickhouse/cli-utils.js.map +1 -0
  191. package/dist/engines/clickhouse/hostdb-releases.js +24 -0
  192. package/dist/engines/clickhouse/hostdb-releases.js.map +1 -0
  193. package/dist/engines/clickhouse/index.js +1077 -0
  194. package/dist/engines/clickhouse/index.js.map +1 -0
  195. package/dist/engines/clickhouse/restore.js +335 -0
  196. package/dist/engines/clickhouse/restore.js.map +1 -0
  197. package/dist/engines/clickhouse/version-maps.js +83 -0
  198. package/dist/engines/clickhouse/version-maps.js.map +1 -0
  199. package/dist/engines/clickhouse/version-validator.js +133 -0
  200. package/dist/engines/clickhouse/version-validator.js.map +1 -0
  201. package/dist/engines/cockroachdb/backup.js +261 -0
  202. package/dist/engines/cockroachdb/backup.js.map +1 -0
  203. package/dist/engines/cockroachdb/binary-manager.js +33 -0
  204. package/dist/engines/cockroachdb/binary-manager.js.map +1 -0
  205. package/dist/engines/cockroachdb/binary-urls.js +33 -0
  206. package/dist/engines/cockroachdb/binary-urls.js.map +1 -0
  207. package/dist/engines/cockroachdb/cli-utils.js +338 -0
  208. package/dist/engines/cockroachdb/cli-utils.js.map +1 -0
  209. package/dist/engines/cockroachdb/hostdb-releases.js +21 -0
  210. package/dist/engines/cockroachdb/hostdb-releases.js.map +1 -0
  211. package/dist/engines/cockroachdb/index.js +1016 -0
  212. package/dist/engines/cockroachdb/index.js.map +1 -0
  213. package/dist/engines/cockroachdb/restore.js +323 -0
  214. package/dist/engines/cockroachdb/restore.js.map +1 -0
  215. package/dist/engines/cockroachdb/version-maps.js +37 -0
  216. package/dist/engines/cockroachdb/version-maps.js.map +1 -0
  217. package/dist/engines/couchdb/api-client.js +64 -0
  218. package/dist/engines/couchdb/api-client.js.map +1 -0
  219. package/dist/engines/couchdb/backup.js +90 -0
  220. package/dist/engines/couchdb/backup.js.map +1 -0
  221. package/dist/engines/couchdb/binary-manager.js +62 -0
  222. package/dist/engines/couchdb/binary-manager.js.map +1 -0
  223. package/dist/engines/couchdb/binary-urls.js +92 -0
  224. package/dist/engines/couchdb/binary-urls.js.map +1 -0
  225. package/dist/engines/couchdb/hostdb-releases.js +21 -0
  226. package/dist/engines/couchdb/hostdb-releases.js.map +1 -0
  227. package/dist/engines/couchdb/index.js +1043 -0
  228. package/dist/engines/couchdb/index.js.map +1 -0
  229. package/dist/engines/couchdb/restore.js +198 -0
  230. package/dist/engines/couchdb/restore.js.map +1 -0
  231. package/dist/engines/couchdb/version-maps.js +67 -0
  232. package/dist/engines/couchdb/version-maps.js.map +1 -0
  233. package/dist/engines/couchdb/version-validator.js +88 -0
  234. package/dist/engines/couchdb/version-validator.js.map +1 -0
  235. package/dist/engines/duckdb/binary-manager.js +33 -0
  236. package/dist/engines/duckdb/binary-manager.js.map +1 -0
  237. package/{engines/duckdb/binary-urls.ts → dist/engines/duckdb/binary-urls.js} +11 -16
  238. package/dist/engines/duckdb/binary-urls.js.map +1 -0
  239. package/dist/engines/duckdb/hostdb-releases.js +21 -0
  240. package/dist/engines/duckdb/hostdb-releases.js.map +1 -0
  241. package/dist/engines/duckdb/index.js +594 -0
  242. package/dist/engines/duckdb/index.js.map +1 -0
  243. package/dist/engines/duckdb/registry.js +265 -0
  244. package/dist/engines/duckdb/registry.js.map +1 -0
  245. package/dist/engines/duckdb/scanner.js +12 -0
  246. package/dist/engines/duckdb/scanner.js.map +1 -0
  247. package/dist/engines/duckdb/version-maps.js +67 -0
  248. package/dist/engines/duckdb/version-maps.js.map +1 -0
  249. package/dist/engines/duckdb/version-validator.js +62 -0
  250. package/dist/engines/duckdb/version-validator.js.map +1 -0
  251. package/dist/engines/ferretdb/backup.js +170 -0
  252. package/dist/engines/ferretdb/backup.js.map +1 -0
  253. package/dist/engines/ferretdb/binary-manager.js +765 -0
  254. package/dist/engines/ferretdb/binary-manager.js.map +1 -0
  255. package/dist/engines/ferretdb/binary-urls.js +135 -0
  256. package/dist/engines/ferretdb/binary-urls.js.map +1 -0
  257. package/dist/engines/ferretdb/index.js +1517 -0
  258. package/dist/engines/ferretdb/index.js.map +1 -0
  259. package/dist/engines/ferretdb/restore.js +310 -0
  260. package/dist/engines/ferretdb/restore.js.map +1 -0
  261. package/{engines/ferretdb/version-maps.ts → dist/engines/ferretdb/version-maps.js} +62 -79
  262. package/dist/engines/ferretdb/version-maps.js.map +1 -0
  263. package/dist/engines/file-based-utils.js +184 -0
  264. package/dist/engines/file-based-utils.js.map +1 -0
  265. package/dist/engines/index.js +124 -0
  266. package/dist/engines/index.js.map +1 -0
  267. package/dist/engines/influxdb/api-client.js +54 -0
  268. package/dist/engines/influxdb/api-client.js.map +1 -0
  269. package/dist/engines/influxdb/backup.js +119 -0
  270. package/dist/engines/influxdb/backup.js.map +1 -0
  271. package/dist/engines/influxdb/binary-manager.js +87 -0
  272. package/dist/engines/influxdb/binary-manager.js.map +1 -0
  273. package/dist/engines/influxdb/binary-urls.js +56 -0
  274. package/dist/engines/influxdb/binary-urls.js.map +1 -0
  275. package/dist/engines/influxdb/hostdb-releases.js +21 -0
  276. package/dist/engines/influxdb/hostdb-releases.js.map +1 -0
  277. package/dist/engines/influxdb/index.js +962 -0
  278. package/dist/engines/influxdb/index.js.map +1 -0
  279. package/dist/engines/influxdb/restore.js +329 -0
  280. package/dist/engines/influxdb/restore.js.map +1 -0
  281. package/dist/engines/influxdb/version-maps.js +64 -0
  282. package/dist/engines/influxdb/version-maps.js.map +1 -0
  283. package/dist/engines/influxdb/version-validator.js +109 -0
  284. package/dist/engines/influxdb/version-validator.js.map +1 -0
  285. package/dist/engines/mariadb/backup.js +178 -0
  286. package/dist/engines/mariadb/backup.js.map +1 -0
  287. package/dist/engines/mariadb/binary-manager.js +33 -0
  288. package/dist/engines/mariadb/binary-manager.js.map +1 -0
  289. package/{engines/mariadb/binary-urls.ts → dist/engines/mariadb/binary-urls.js} +38 -55
  290. package/dist/engines/mariadb/binary-urls.js.map +1 -0
  291. package/dist/engines/mariadb/hostdb-releases.js +21 -0
  292. package/dist/engines/mariadb/hostdb-releases.js.map +1 -0
  293. package/dist/engines/mariadb/index.js +1011 -0
  294. package/dist/engines/mariadb/index.js.map +1 -0
  295. package/dist/engines/mariadb/restore.js +322 -0
  296. package/dist/engines/mariadb/restore.js.map +1 -0
  297. package/dist/engines/mariadb/version-maps.js +63 -0
  298. package/dist/engines/mariadb/version-maps.js.map +1 -0
  299. package/dist/engines/mariadb/version-validator.js +143 -0
  300. package/dist/engines/mariadb/version-validator.js.map +1 -0
  301. package/dist/engines/meilisearch/api-client.js +50 -0
  302. package/dist/engines/meilisearch/api-client.js.map +1 -0
  303. package/dist/engines/meilisearch/backup.js +167 -0
  304. package/dist/engines/meilisearch/backup.js.map +1 -0
  305. package/dist/engines/meilisearch/binary-manager.js +31 -0
  306. package/dist/engines/meilisearch/binary-manager.js.map +1 -0
  307. package/dist/engines/meilisearch/binary-urls.js +56 -0
  308. package/dist/engines/meilisearch/binary-urls.js.map +1 -0
  309. package/dist/engines/meilisearch/hostdb-releases.js +21 -0
  310. package/dist/engines/meilisearch/hostdb-releases.js.map +1 -0
  311. package/dist/engines/meilisearch/index.js +992 -0
  312. package/dist/engines/meilisearch/index.js.map +1 -0
  313. package/dist/engines/meilisearch/restore.js +167 -0
  314. package/dist/engines/meilisearch/restore.js.map +1 -0
  315. package/dist/engines/meilisearch/version-maps.js +67 -0
  316. package/dist/engines/meilisearch/version-maps.js.map +1 -0
  317. package/dist/engines/meilisearch/version-validator.js +109 -0
  318. package/dist/engines/meilisearch/version-validator.js.map +1 -0
  319. package/dist/engines/mongodb/backup.js +109 -0
  320. package/dist/engines/mongodb/backup.js.map +1 -0
  321. package/dist/engines/mongodb/binary-manager.js +36 -0
  322. package/dist/engines/mongodb/binary-manager.js.map +1 -0
  323. package/dist/engines/mongodb/binary-urls.js +46 -0
  324. package/dist/engines/mongodb/binary-urls.js.map +1 -0
  325. package/dist/engines/mongodb/cli-utils.js +131 -0
  326. package/dist/engines/mongodb/cli-utils.js.map +1 -0
  327. package/dist/engines/mongodb/hostdb-releases.js +77 -0
  328. package/dist/engines/mongodb/hostdb-releases.js.map +1 -0
  329. package/dist/engines/mongodb/index.js +873 -0
  330. package/dist/engines/mongodb/index.js.map +1 -0
  331. package/dist/engines/mongodb/restore.js +276 -0
  332. package/dist/engines/mongodb/restore.js.map +1 -0
  333. package/dist/engines/mongodb/version-maps.js +79 -0
  334. package/dist/engines/mongodb/version-maps.js.map +1 -0
  335. package/dist/engines/mongodb/version-validator.js +133 -0
  336. package/dist/engines/mongodb/version-validator.js.map +1 -0
  337. package/dist/engines/mysql/backup.js +210 -0
  338. package/dist/engines/mysql/backup.js.map +1 -0
  339. package/dist/engines/mysql/binary-detection.js +325 -0
  340. package/dist/engines/mysql/binary-detection.js.map +1 -0
  341. package/dist/engines/mysql/binary-manager.js +30 -0
  342. package/dist/engines/mysql/binary-manager.js.map +1 -0
  343. package/dist/engines/mysql/binary-urls.js +87 -0
  344. package/dist/engines/mysql/binary-urls.js.map +1 -0
  345. package/{engines/mysql/hostdb-releases.ts → dist/engines/mysql/hostdb-releases.js} +20 -23
  346. package/dist/engines/mysql/hostdb-releases.js.map +1 -0
  347. package/dist/engines/mysql/index.js +1066 -0
  348. package/dist/engines/mysql/index.js.map +1 -0
  349. package/dist/engines/mysql/restore.js +361 -0
  350. package/dist/engines/mysql/restore.js.map +1 -0
  351. package/dist/engines/mysql/version-maps.js +79 -0
  352. package/dist/engines/mysql/version-maps.js.map +1 -0
  353. package/dist/engines/mysql/version-validator.js +266 -0
  354. package/dist/engines/mysql/version-validator.js.map +1 -0
  355. package/dist/engines/postgresql/backup.js +118 -0
  356. package/dist/engines/postgresql/backup.js.map +1 -0
  357. package/dist/engines/postgresql/binary-manager.js +85 -0
  358. package/dist/engines/postgresql/binary-manager.js.map +1 -0
  359. package/dist/engines/postgresql/binary-urls.js +80 -0
  360. package/dist/engines/postgresql/binary-urls.js.map +1 -0
  361. package/dist/engines/postgresql/hostdb-releases.js +21 -0
  362. package/dist/engines/postgresql/hostdb-releases.js.map +1 -0
  363. package/dist/engines/postgresql/index.js +852 -0
  364. package/dist/engines/postgresql/index.js.map +1 -0
  365. package/dist/engines/postgresql/remote-version.js +109 -0
  366. package/dist/engines/postgresql/remote-version.js.map +1 -0
  367. package/dist/engines/postgresql/restore.js +254 -0
  368. package/dist/engines/postgresql/restore.js.map +1 -0
  369. package/dist/engines/postgresql/version-maps.js +73 -0
  370. package/dist/engines/postgresql/version-maps.js.map +1 -0
  371. package/dist/engines/postgresql/version-validator.js +286 -0
  372. package/dist/engines/postgresql/version-validator.js.map +1 -0
  373. package/dist/engines/qdrant/api-client.js +50 -0
  374. package/dist/engines/qdrant/api-client.js.map +1 -0
  375. package/dist/engines/qdrant/backup.js +115 -0
  376. package/dist/engines/qdrant/backup.js.map +1 -0
  377. package/dist/engines/qdrant/binary-manager.js +31 -0
  378. package/dist/engines/qdrant/binary-manager.js.map +1 -0
  379. package/dist/engines/qdrant/binary-urls.js +92 -0
  380. package/dist/engines/qdrant/binary-urls.js.map +1 -0
  381. package/dist/engines/qdrant/cli-utils.js +39 -0
  382. package/dist/engines/qdrant/cli-utils.js.map +1 -0
  383. package/dist/engines/qdrant/hostdb-releases.js +21 -0
  384. package/dist/engines/qdrant/hostdb-releases.js.map +1 -0
  385. package/dist/engines/qdrant/index.js +1002 -0
  386. package/dist/engines/qdrant/index.js.map +1 -0
  387. package/dist/engines/qdrant/restore.js +154 -0
  388. package/dist/engines/qdrant/restore.js.map +1 -0
  389. package/dist/engines/qdrant/version-maps.js +67 -0
  390. package/dist/engines/qdrant/version-maps.js.map +1 -0
  391. package/dist/engines/qdrant/version-validator.js +109 -0
  392. package/dist/engines/qdrant/version-validator.js.map +1 -0
  393. package/dist/engines/questdb/backup.js +191 -0
  394. package/dist/engines/questdb/backup.js.map +1 -0
  395. package/dist/engines/questdb/binary-manager.js +247 -0
  396. package/dist/engines/questdb/binary-manager.js.map +1 -0
  397. package/dist/engines/questdb/binary-urls.js +27 -0
  398. package/dist/engines/questdb/binary-urls.js.map +1 -0
  399. package/dist/engines/questdb/hostdb-releases.js +21 -0
  400. package/dist/engines/questdb/hostdb-releases.js.map +1 -0
  401. package/dist/engines/questdb/index.js +814 -0
  402. package/dist/engines/questdb/index.js.map +1 -0
  403. package/dist/engines/questdb/restore.js +202 -0
  404. package/dist/engines/questdb/restore.js.map +1 -0
  405. package/dist/engines/questdb/version-maps.js +33 -0
  406. package/dist/engines/questdb/version-maps.js.map +1 -0
  407. package/dist/engines/questdb/version-validator.js +99 -0
  408. package/dist/engines/questdb/version-validator.js.map +1 -0
  409. package/dist/engines/redis/backup.js +292 -0
  410. package/dist/engines/redis/backup.js.map +1 -0
  411. package/dist/engines/redis/binary-manager.js +32 -0
  412. package/dist/engines/redis/binary-manager.js.map +1 -0
  413. package/dist/engines/redis/binary-urls.js +96 -0
  414. package/dist/engines/redis/binary-urls.js.map +1 -0
  415. package/dist/engines/redis/cli-utils.js +38 -0
  416. package/dist/engines/redis/cli-utils.js.map +1 -0
  417. package/dist/engines/redis/hostdb-releases.js +21 -0
  418. package/dist/engines/redis/hostdb-releases.js.map +1 -0
  419. package/dist/engines/redis/index.js +1263 -0
  420. package/dist/engines/redis/index.js.map +1 -0
  421. package/dist/engines/redis/restore.js +338 -0
  422. package/dist/engines/redis/restore.js.map +1 -0
  423. package/dist/engines/redis/version-maps.js +70 -0
  424. package/dist/engines/redis/version-maps.js.map +1 -0
  425. package/dist/engines/redis/version-validator.js +109 -0
  426. package/dist/engines/redis/version-validator.js.map +1 -0
  427. package/dist/engines/sqlite/binary-manager.js +39 -0
  428. package/dist/engines/sqlite/binary-manager.js.map +1 -0
  429. package/{engines/sqlite/binary-urls.ts → dist/engines/sqlite/binary-urls.js} +11 -16
  430. package/dist/engines/sqlite/binary-urls.js.map +1 -0
  431. package/dist/engines/sqlite/hostdb-releases.js +21 -0
  432. package/dist/engines/sqlite/hostdb-releases.js.map +1 -0
  433. package/dist/engines/sqlite/index.js +493 -0
  434. package/dist/engines/sqlite/index.js.map +1 -0
  435. package/dist/engines/sqlite/registry.js +163 -0
  436. package/dist/engines/sqlite/registry.js.map +1 -0
  437. package/dist/engines/sqlite/scanner.js +12 -0
  438. package/dist/engines/sqlite/scanner.js.map +1 -0
  439. package/dist/engines/sqlite/version-maps.js +57 -0
  440. package/dist/engines/sqlite/version-maps.js.map +1 -0
  441. package/dist/engines/surrealdb/backup.js +97 -0
  442. package/dist/engines/surrealdb/backup.js.map +1 -0
  443. package/dist/engines/surrealdb/binary-manager.js +33 -0
  444. package/dist/engines/surrealdb/binary-manager.js.map +1 -0
  445. package/dist/engines/surrealdb/binary-urls.js +33 -0
  446. package/dist/engines/surrealdb/binary-urls.js.map +1 -0
  447. package/dist/engines/surrealdb/cli-utils.js +147 -0
  448. package/dist/engines/surrealdb/cli-utils.js.map +1 -0
  449. package/dist/engines/surrealdb/hostdb-releases.js +21 -0
  450. package/dist/engines/surrealdb/hostdb-releases.js.map +1 -0
  451. package/dist/engines/surrealdb/index.js +1022 -0
  452. package/dist/engines/surrealdb/index.js.map +1 -0
  453. package/dist/engines/surrealdb/restore.js +224 -0
  454. package/dist/engines/surrealdb/restore.js.map +1 -0
  455. package/dist/engines/surrealdb/version-maps.js +36 -0
  456. package/dist/engines/surrealdb/version-maps.js.map +1 -0
  457. package/dist/engines/tigerbeetle/backup.js +36 -0
  458. package/dist/engines/tigerbeetle/backup.js.map +1 -0
  459. package/dist/engines/tigerbeetle/binary-manager.js +72 -0
  460. package/dist/engines/tigerbeetle/binary-manager.js.map +1 -0
  461. package/dist/engines/tigerbeetle/binary-urls.js +49 -0
  462. package/dist/engines/tigerbeetle/binary-urls.js.map +1 -0
  463. package/dist/engines/tigerbeetle/hostdb-releases.js +21 -0
  464. package/dist/engines/tigerbeetle/hostdb-releases.js.map +1 -0
  465. package/dist/engines/tigerbeetle/index.js +559 -0
  466. package/dist/engines/tigerbeetle/index.js.map +1 -0
  467. package/dist/engines/tigerbeetle/restore.js +91 -0
  468. package/dist/engines/tigerbeetle/restore.js.map +1 -0
  469. package/{engines/tigerbeetle/version-maps.ts → dist/engines/tigerbeetle/version-maps.js} +22 -31
  470. package/dist/engines/tigerbeetle/version-maps.js.map +1 -0
  471. package/dist/engines/tigerbeetle/version-validator.js +108 -0
  472. package/dist/engines/tigerbeetle/version-validator.js.map +1 -0
  473. package/dist/engines/typedb/backup.js +129 -0
  474. package/dist/engines/typedb/backup.js.map +1 -0
  475. package/dist/engines/typedb/binary-manager.js +151 -0
  476. package/dist/engines/typedb/binary-manager.js.map +1 -0
  477. package/dist/engines/typedb/binary-urls.js +33 -0
  478. package/dist/engines/typedb/binary-urls.js.map +1 -0
  479. package/dist/engines/typedb/cli-utils.js +163 -0
  480. package/dist/engines/typedb/cli-utils.js.map +1 -0
  481. package/dist/engines/typedb/hostdb-releases.js +21 -0
  482. package/dist/engines/typedb/hostdb-releases.js.map +1 -0
  483. package/dist/engines/typedb/index.js +1003 -0
  484. package/dist/engines/typedb/index.js.map +1 -0
  485. package/dist/engines/typedb/restore.js +279 -0
  486. package/dist/engines/typedb/restore.js.map +1 -0
  487. package/dist/engines/typedb/version-maps.js +40 -0
  488. package/dist/engines/typedb/version-maps.js.map +1 -0
  489. package/dist/engines/typedb/version-validator.js +103 -0
  490. package/dist/engines/typedb/version-validator.js.map +1 -0
  491. package/dist/engines/valkey/backup.js +292 -0
  492. package/dist/engines/valkey/backup.js.map +1 -0
  493. package/dist/engines/valkey/binary-manager.js +33 -0
  494. package/dist/engines/valkey/binary-manager.js.map +1 -0
  495. package/dist/engines/valkey/binary-urls.js +98 -0
  496. package/dist/engines/valkey/binary-urls.js.map +1 -0
  497. package/dist/engines/valkey/cli-utils.js +38 -0
  498. package/dist/engines/valkey/cli-utils.js.map +1 -0
  499. package/dist/engines/valkey/hostdb-releases.js +21 -0
  500. package/dist/engines/valkey/hostdb-releases.js.map +1 -0
  501. package/dist/engines/valkey/index.js +1257 -0
  502. package/dist/engines/valkey/index.js.map +1 -0
  503. package/dist/engines/valkey/restore.js +340 -0
  504. package/dist/engines/valkey/restore.js.map +1 -0
  505. package/dist/engines/valkey/version-maps.js +70 -0
  506. package/dist/engines/valkey/version-maps.js.map +1 -0
  507. package/dist/engines/valkey/version-validator.js +112 -0
  508. package/dist/engines/valkey/version-validator.js.map +1 -0
  509. package/dist/engines/weaviate/api-client.js +50 -0
  510. package/dist/engines/weaviate/api-client.js.map +1 -0
  511. package/dist/engines/weaviate/backup.js +95 -0
  512. package/dist/engines/weaviate/backup.js.map +1 -0
  513. package/dist/engines/weaviate/binary-manager.js +58 -0
  514. package/dist/engines/weaviate/binary-manager.js.map +1 -0
  515. package/dist/engines/weaviate/binary-urls.js +92 -0
  516. package/dist/engines/weaviate/binary-urls.js.map +1 -0
  517. package/dist/engines/weaviate/cli-utils.js +39 -0
  518. package/dist/engines/weaviate/cli-utils.js.map +1 -0
  519. package/dist/engines/weaviate/hostdb-releases.js +21 -0
  520. package/dist/engines/weaviate/hostdb-releases.js.map +1 -0
  521. package/dist/engines/weaviate/index.js +871 -0
  522. package/dist/engines/weaviate/index.js.map +1 -0
  523. package/dist/engines/weaviate/restore.js +185 -0
  524. package/dist/engines/weaviate/restore.js.map +1 -0
  525. package/dist/engines/weaviate/version-maps.js +67 -0
  526. package/dist/engines/weaviate/version-maps.js.map +1 -0
  527. package/dist/engines/weaviate/version-validator.js +109 -0
  528. package/dist/engines/weaviate/version-validator.js.map +1 -0
  529. package/dist/types/index.js +102 -0
  530. package/dist/types/index.js.map +1 -0
  531. package/package.json +12 -9
  532. package/bin/cli.js +0 -68
  533. package/cli/bin.ts +0 -10
  534. package/cli/commands/attach.ts +0 -139
  535. package/cli/commands/backup.ts +0 -290
  536. package/cli/commands/backups.ts +0 -247
  537. package/cli/commands/clone.ts +0 -159
  538. package/cli/commands/config.ts +0 -367
  539. package/cli/commands/connect.ts +0 -684
  540. package/cli/commands/create.ts +0 -1201
  541. package/cli/commands/databases.ts +0 -630
  542. package/cli/commands/delete.ts +0 -133
  543. package/cli/commands/deps.ts +0 -342
  544. package/cli/commands/detach.ts +0 -107
  545. package/cli/commands/doctor.ts +0 -689
  546. package/cli/commands/duckdb.ts +0 -273
  547. package/cli/commands/edit.ts +0 -683
  548. package/cli/commands/engines.ts +0 -1914
  549. package/cli/commands/export.ts +0 -544
  550. package/cli/commands/info.ts +0 -340
  551. package/cli/commands/list.ts +0 -284
  552. package/cli/commands/logs.ts +0 -102
  553. package/cli/commands/menu/backup-handlers.ts +0 -1571
  554. package/cli/commands/menu/container-handlers.ts +0 -2288
  555. package/cli/commands/menu/engine-handlers.ts +0 -355
  556. package/cli/commands/menu/index.ts +0 -342
  557. package/cli/commands/menu/settings-handlers.ts +0 -365
  558. package/cli/commands/menu/shared.ts +0 -23
  559. package/cli/commands/menu/shell-handlers.ts +0 -1811
  560. package/cli/commands/menu/sql-handlers.ts +0 -231
  561. package/cli/commands/menu/update-handlers.ts +0 -378
  562. package/cli/commands/menu/validators.ts +0 -8
  563. package/cli/commands/ports.ts +0 -211
  564. package/cli/commands/pull.ts +0 -223
  565. package/cli/commands/query.ts +0 -241
  566. package/cli/commands/restore.ts +0 -587
  567. package/cli/commands/run.ts +0 -178
  568. package/cli/commands/self-update.ts +0 -121
  569. package/cli/commands/sqlite.ts +0 -273
  570. package/cli/commands/start.ts +0 -218
  571. package/cli/commands/stop.ts +0 -241
  572. package/cli/commands/url.ts +0 -104
  573. package/cli/commands/users.ts +0 -264
  574. package/cli/commands/version.ts +0 -55
  575. package/cli/commands/which.ts +0 -290
  576. package/cli/constants.ts +0 -233
  577. package/cli/helpers.ts +0 -1593
  578. package/cli/index.ts +0 -162
  579. package/cli/ui/prompts.ts +0 -1525
  580. package/cli/ui/spinner.ts +0 -88
  581. package/cli/ui/theme.ts +0 -128
  582. package/cli/utils/file-follower.ts +0 -93
  583. package/config/backup-formats.ts +0 -446
  584. package/config/defaults.ts +0 -56
  585. package/config/engine-defaults.ts +0 -336
  586. package/config/engines-registry.ts +0 -150
  587. package/config/engines.schema.json +0 -135
  588. package/config/os-dependencies.ts +0 -888
  589. package/config/paths.ts +0 -200
  590. package/core/backup-restore.ts +0 -330
  591. package/core/base-binary-manager.ts +0 -562
  592. package/core/base-document-binary-manager.ts +0 -523
  593. package/core/base-embedded-binary-manager.ts +0 -547
  594. package/core/base-server-binary-manager.ts +0 -523
  595. package/core/config-manager.ts +0 -652
  596. package/core/container-manager.ts +0 -787
  597. package/core/credential-generator.ts +0 -93
  598. package/core/credential-manager.ts +0 -259
  599. package/core/dblab-utils.ts +0 -113
  600. package/core/dependency-manager.ts +0 -512
  601. package/core/docker-exporter.ts +0 -1345
  602. package/core/error-handler.ts +0 -419
  603. package/core/fs-error-utils.ts +0 -82
  604. package/core/homebrew-version-manager.ts +0 -352
  605. package/core/hostdb-client.ts +0 -344
  606. package/core/hostdb-metadata.ts +0 -350
  607. package/core/hostdb-releases-factory.ts +0 -237
  608. package/core/library-env.ts +0 -118
  609. package/core/pgweb-utils.ts +0 -62
  610. package/core/platform-service.ts +0 -829
  611. package/core/port-manager.ts +0 -165
  612. package/core/process-manager.ts +0 -576
  613. package/core/pull-manager.ts +0 -511
  614. package/core/query-parser.ts +0 -514
  615. package/core/spawn-utils.ts +0 -122
  616. package/core/start-with-retry.ts +0 -130
  617. package/core/test-cleanup.ts +0 -108
  618. package/core/tls-generator.ts +0 -116
  619. package/core/transaction-manager.ts +0 -158
  620. package/core/update-manager.ts +0 -308
  621. package/core/version-migration.ts +0 -346
  622. package/core/version-utils.ts +0 -104
  623. package/engines/base-engine.ts +0 -340
  624. package/engines/clickhouse/README.md +0 -231
  625. package/engines/clickhouse/backup.ts +0 -398
  626. package/engines/clickhouse/binary-manager.ts +0 -201
  627. package/engines/clickhouse/binary-urls.ts +0 -125
  628. package/engines/clickhouse/cli-utils.ts +0 -176
  629. package/engines/clickhouse/hostdb-releases.ts +0 -30
  630. package/engines/clickhouse/index.ts +0 -1345
  631. package/engines/clickhouse/restore.ts +0 -466
  632. package/engines/clickhouse/version-maps.ts +0 -95
  633. package/engines/clickhouse/version-validator.ts +0 -154
  634. package/engines/cockroachdb/README.md +0 -170
  635. package/engines/cockroachdb/backup.ts +0 -376
  636. package/engines/cockroachdb/binary-manager.ts +0 -45
  637. package/engines/cockroachdb/binary-urls.ts +0 -40
  638. package/engines/cockroachdb/cli-utils.ts +0 -384
  639. package/engines/cockroachdb/hostdb-releases.ts +0 -26
  640. package/engines/cockroachdb/index.ts +0 -1276
  641. package/engines/cockroachdb/restore.ts +0 -455
  642. package/engines/cockroachdb/version-maps.ts +0 -42
  643. package/engines/couchdb/README.md +0 -257
  644. package/engines/couchdb/api-client.ts +0 -81
  645. package/engines/couchdb/backup.ts +0 -137
  646. package/engines/couchdb/binary-manager.ts +0 -86
  647. package/engines/couchdb/binary-urls.ts +0 -115
  648. package/engines/couchdb/hostdb-releases.ts +0 -23
  649. package/engines/couchdb/index.ts +0 -1429
  650. package/engines/couchdb/restore.ts +0 -290
  651. package/engines/couchdb/version-maps.ts +0 -78
  652. package/engines/couchdb/version-validator.ts +0 -111
  653. package/engines/duckdb/README.md +0 -154
  654. package/engines/duckdb/binary-manager.ts +0 -45
  655. package/engines/duckdb/hostdb-releases.ts +0 -23
  656. package/engines/duckdb/index.ts +0 -749
  657. package/engines/duckdb/registry.ts +0 -303
  658. package/engines/duckdb/scanner.ts +0 -22
  659. package/engines/duckdb/version-maps.ts +0 -78
  660. package/engines/duckdb/version-validator.ts +0 -78
  661. package/engines/ferretdb/README.md +0 -262
  662. package/engines/ferretdb/backup.ts +0 -173
  663. package/engines/ferretdb/binary-manager.ts +0 -1095
  664. package/engines/ferretdb/binary-urls.ts +0 -183
  665. package/engines/ferretdb/index.ts +0 -1907
  666. package/engines/ferretdb/restore.ts +0 -357
  667. package/engines/file-based-utils.ts +0 -262
  668. package/engines/index.ts +0 -131
  669. package/engines/influxdb/README.md +0 -180
  670. package/engines/influxdb/api-client.ts +0 -64
  671. package/engines/influxdb/backup.ts +0 -160
  672. package/engines/influxdb/binary-manager.ts +0 -110
  673. package/engines/influxdb/binary-urls.ts +0 -69
  674. package/engines/influxdb/hostdb-releases.ts +0 -23
  675. package/engines/influxdb/index.ts +0 -1272
  676. package/engines/influxdb/restore.ts +0 -417
  677. package/engines/influxdb/version-maps.ts +0 -75
  678. package/engines/influxdb/version-validator.ts +0 -128
  679. package/engines/mariadb/README.md +0 -141
  680. package/engines/mariadb/backup.ts +0 -233
  681. package/engines/mariadb/binary-manager.ts +0 -45
  682. package/engines/mariadb/hostdb-releases.ts +0 -23
  683. package/engines/mariadb/index.ts +0 -1300
  684. package/engines/mariadb/restore.ts +0 -447
  685. package/engines/mariadb/version-maps.ts +0 -72
  686. package/engines/mariadb/version-validator.ts +0 -181
  687. package/engines/meilisearch/README.md +0 -255
  688. package/engines/meilisearch/api-client.ts +0 -61
  689. package/engines/meilisearch/backup.ts +0 -233
  690. package/engines/meilisearch/binary-manager.ts +0 -43
  691. package/engines/meilisearch/binary-urls.ts +0 -69
  692. package/engines/meilisearch/hostdb-releases.ts +0 -26
  693. package/engines/meilisearch/index.ts +0 -1292
  694. package/engines/meilisearch/restore.ts +0 -219
  695. package/engines/meilisearch/version-maps.ts +0 -78
  696. package/engines/meilisearch/version-validator.ts +0 -128
  697. package/engines/mongodb/README.md +0 -162
  698. package/engines/mongodb/backup.ts +0 -127
  699. package/engines/mongodb/binary-manager.ts +0 -48
  700. package/engines/mongodb/binary-urls.ts +0 -63
  701. package/engines/mongodb/cli-utils.ts +0 -171
  702. package/engines/mongodb/hostdb-releases.ts +0 -91
  703. package/engines/mongodb/index.ts +0 -1118
  704. package/engines/mongodb/restore.ts +0 -361
  705. package/engines/mongodb/version-maps.ts +0 -91
  706. package/engines/mongodb/version-validator.ts +0 -160
  707. package/engines/mysql/README.md +0 -142
  708. package/engines/mysql/backup.ts +0 -270
  709. package/engines/mysql/binary-detection.ts +0 -408
  710. package/engines/mysql/binary-manager.ts +0 -42
  711. package/engines/mysql/binary-urls.ts +0 -104
  712. package/engines/mysql/index.ts +0 -1361
  713. package/engines/mysql/restore.ts +0 -500
  714. package/engines/mysql/version-maps.ts +0 -91
  715. package/engines/mysql/version-validator.ts +0 -369
  716. package/engines/postgresql/README.md +0 -158
  717. package/engines/postgresql/backup.ts +0 -151
  718. package/engines/postgresql/binary-manager.ts +0 -114
  719. package/engines/postgresql/binary-urls.ts +0 -99
  720. package/engines/postgresql/hostdb-releases.ts +0 -26
  721. package/engines/postgresql/index.ts +0 -1143
  722. package/engines/postgresql/remote-version.ts +0 -161
  723. package/engines/postgresql/restore.ts +0 -342
  724. package/engines/postgresql/version-maps.ts +0 -83
  725. package/engines/postgresql/version-validator.ts +0 -413
  726. package/engines/qdrant/README.md +0 -222
  727. package/engines/qdrant/api-client.ts +0 -61
  728. package/engines/qdrant/backup.ts +0 -165
  729. package/engines/qdrant/binary-manager.ts +0 -43
  730. package/engines/qdrant/binary-urls.ts +0 -115
  731. package/engines/qdrant/cli-utils.ts +0 -43
  732. package/engines/qdrant/hostdb-releases.ts +0 -23
  733. package/engines/qdrant/index.ts +0 -1312
  734. package/engines/qdrant/restore.ts +0 -203
  735. package/engines/qdrant/version-maps.ts +0 -78
  736. package/engines/qdrant/version-validator.ts +0 -128
  737. package/engines/questdb/README.md +0 -334
  738. package/engines/questdb/backup.ts +0 -220
  739. package/engines/questdb/binary-manager.ts +0 -310
  740. package/engines/questdb/binary-urls.ts +0 -34
  741. package/engines/questdb/hostdb-releases.ts +0 -23
  742. package/engines/questdb/index.ts +0 -1023
  743. package/engines/questdb/restore.ts +0 -260
  744. package/engines/questdb/version-maps.ts +0 -37
  745. package/engines/questdb/version-validator.ts +0 -121
  746. package/engines/redis/README.md +0 -173
  747. package/engines/redis/backup.ts +0 -389
  748. package/engines/redis/binary-manager.ts +0 -44
  749. package/engines/redis/binary-urls.ts +0 -117
  750. package/engines/redis/cli-utils.ts +0 -42
  751. package/engines/redis/hostdb-releases.ts +0 -23
  752. package/engines/redis/index.ts +0 -1583
  753. package/engines/redis/restore.ts +0 -443
  754. package/engines/redis/version-maps.ts +0 -81
  755. package/engines/redis/version-validator.ts +0 -131
  756. package/engines/sqlite/README.md +0 -162
  757. package/engines/sqlite/binary-manager.ts +0 -52
  758. package/engines/sqlite/hostdb-releases.ts +0 -23
  759. package/engines/sqlite/index.ts +0 -641
  760. package/engines/sqlite/registry.ts +0 -198
  761. package/engines/sqlite/scanner.ts +0 -22
  762. package/engines/sqlite/version-maps.ts +0 -64
  763. package/engines/surrealdb/README.md +0 -218
  764. package/engines/surrealdb/backup.ts +0 -131
  765. package/engines/surrealdb/binary-manager.ts +0 -45
  766. package/engines/surrealdb/binary-urls.ts +0 -40
  767. package/engines/surrealdb/cli-utils.ts +0 -173
  768. package/engines/surrealdb/hostdb-releases.ts +0 -23
  769. package/engines/surrealdb/index.ts +0 -1246
  770. package/engines/surrealdb/restore.ts +0 -302
  771. package/engines/surrealdb/version-maps.ts +0 -41
  772. package/engines/tigerbeetle/README.md +0 -61
  773. package/engines/tigerbeetle/backup.ts +0 -49
  774. package/engines/tigerbeetle/binary-manager.ts +0 -95
  775. package/engines/tigerbeetle/binary-urls.ts +0 -62
  776. package/engines/tigerbeetle/hostdb-releases.ts +0 -26
  777. package/engines/tigerbeetle/index.ts +0 -746
  778. package/engines/tigerbeetle/restore.ts +0 -130
  779. package/engines/tigerbeetle/version-validator.ts +0 -126
  780. package/engines/typedb/backup.ts +0 -167
  781. package/engines/typedb/binary-manager.ts +0 -200
  782. package/engines/typedb/binary-urls.ts +0 -40
  783. package/engines/typedb/cli-utils.ts +0 -210
  784. package/engines/typedb/hostdb-releases.ts +0 -23
  785. package/engines/typedb/index.ts +0 -1275
  786. package/engines/typedb/restore.ts +0 -377
  787. package/engines/typedb/version-maps.ts +0 -48
  788. package/engines/typedb/version-validator.ts +0 -127
  789. package/engines/valkey/README.md +0 -219
  790. package/engines/valkey/backup.ts +0 -389
  791. package/engines/valkey/binary-manager.ts +0 -45
  792. package/engines/valkey/binary-urls.ts +0 -122
  793. package/engines/valkey/cli-utils.ts +0 -42
  794. package/engines/valkey/hostdb-releases.ts +0 -23
  795. package/engines/valkey/index.ts +0 -1585
  796. package/engines/valkey/restore.ts +0 -446
  797. package/engines/valkey/version-maps.ts +0 -81
  798. package/engines/valkey/version-validator.ts +0 -131
  799. package/engines/weaviate/README.md +0 -302
  800. package/engines/weaviate/api-client.ts +0 -61
  801. package/engines/weaviate/backup.ts +0 -145
  802. package/engines/weaviate/binary-manager.ts +0 -80
  803. package/engines/weaviate/binary-urls.ts +0 -115
  804. package/engines/weaviate/cli-utils.ts +0 -43
  805. package/engines/weaviate/hostdb-releases.ts +0 -23
  806. package/engines/weaviate/index.ts +0 -1139
  807. package/engines/weaviate/restore.ts +0 -235
  808. package/engines/weaviate/version-maps.ts +0 -78
  809. package/engines/weaviate/version-validator.ts +0 -128
  810. package/types/index.ts +0 -624
  811. /package/{config → dist/config}/engines.json +0 -0
package/cli/ui/prompts.ts DELETED
@@ -1,1525 +0,0 @@
1
- import inquirer from 'inquirer'
2
- import inquirerAutocomplete from 'inquirer-autocomplete-prompt'
3
- import chalk from 'chalk'
4
-
5
- // Register the autocomplete prompt type
6
- inquirer.registerPrompt('autocomplete', inquirerAutocomplete)
7
- import ora from 'ora'
8
- import { existsSync, statSync } from 'fs'
9
- import { resolve, join } from 'path'
10
- import { homedir } from 'os'
11
- import { listEngines, getEngine } from '../../engines'
12
- import { defaults, getEngineDefaults } from '../../config/defaults'
13
- import { portManager } from '../../core/port-manager'
14
- import { containerManager } from '../../core/container-manager'
15
- import {
16
- detectPackageManager,
17
- getManualInstallInstructions,
18
- getCurrentPlatform,
19
- installEngineDependencies,
20
- } from '../../core/dependency-manager'
21
- import { getEngineDependencies } from '../../config/os-dependencies'
22
- import { getEngineIcon, getPageSize } from '../constants'
23
- import {
24
- BACKUP_FORMATS,
25
- supportsFormatChoice,
26
- getDefaultFormat,
27
- } from '../../config/backup-formats'
28
- import {
29
- type ContainerConfig,
30
- type Engine,
31
- type BackupFormatType,
32
- } from '../../types'
33
-
34
- // Navigation sentinel values for menu navigation
35
- export const BACK_VALUE = '__back__'
36
- export const MAIN_MENU_VALUE = '__main__'
37
- export const ESCAPE_VALUE = '__escape__'
38
- export const TOGGLE_PREFIX = '__toggle__:'
39
-
40
- // Global escape handler state
41
- let globalEscapeEnabled = false
42
- let escapeTriggered = false
43
- let escapeReject: ((error: Error) => void) | null = null
44
- // Store the raw UI object so we can access activePrompt dynamically
45
- // (activePrompt may not be set at capture time due to async initialization)
46
- let currentPromptUi: Record<string, unknown> | null = null
47
-
48
- // Toggle handler state (Shift+Tab to toggle container start/stop)
49
- let toggleEnabled = false
50
- // Set of values that are valid toggle targets (container names)
51
- let toggleValidTargets: Set<string> = new Set()
52
-
53
- // Custom error class for escape
54
- export class EscapeError extends Error {
55
- constructor() {
56
- super('Escape pressed')
57
- this.name = 'EscapeError'
58
- }
59
- }
60
-
61
- // Custom error class for toggle (Shift+Tab)
62
- export class ToggleError extends Error {
63
- targetValue: string
64
- constructor(targetValue: string) {
65
- super('Toggle pressed')
66
- this.name = 'ToggleError'
67
- this.targetValue = targetValue
68
- }
69
- }
70
-
71
- // Module-scoped stdin data handler for escape key and special key detection
72
- // Defined at module scope so disableGlobalEscape() can remove it
73
- function onEscapeData(data: Buffer): void {
74
- // Ctrl+C is byte 3 - handle graceful exit
75
- if (data.length === 1 && data[0] === 3) {
76
- console.log(chalk.gray('\n Goodbye!\n'))
77
- process.exit(0)
78
- }
79
-
80
- // Handle multi-byte escape sequences (arrow keys, Shift+Tab)
81
- // These start with ESC (27) followed by '[' (91) and a letter
82
- if (data.length === 3 && data[0] === 27 && data[1] === 91) {
83
- const keyCode = data[2]
84
-
85
- // Shift+Tab: \x1b[Z (27, 91, 90)
86
- // Access inquirer's internal state to get the currently highlighted value
87
- if (keyCode === 90 && toggleEnabled && currentPromptUi) {
88
- try {
89
- // Access activePrompt dynamically (it may not be set at capture time)
90
- // inquirer-autocomplete-prompt uses 'selected' for cursor index
91
- // and currentChoices.getChoice(index) to get the choice object
92
- const activePrompt = currentPromptUi.activePrompt as
93
- | {
94
- selected?: number
95
- currentChoices?: {
96
- getChoice?: (
97
- index: number,
98
- ) => { value?: string; type?: string } | undefined
99
- }
100
- }
101
- | undefined
102
-
103
- if (
104
- activePrompt?.currentChoices?.getChoice &&
105
- activePrompt.selected !== undefined
106
- ) {
107
- const currentChoice = activePrompt.currentChoices.getChoice(
108
- activePrompt.selected,
109
- )
110
-
111
- // Check if the highlighted item is a valid toggle target (a container)
112
- // Skip separators (type === 'separator') and non-container items
113
- if (
114
- currentChoice &&
115
- currentChoice.value &&
116
- currentChoice.type !== 'separator' &&
117
- toggleValidTargets.has(currentChoice.value)
118
- ) {
119
- // Reject the prompt with the container value to toggle
120
- if (escapeReject) {
121
- const reject = escapeReject
122
- escapeReject = null
123
- reject(new ToggleError(currentChoice.value))
124
- }
125
-
126
- // Close the prompt UI
127
- if (typeof currentPromptUi.close === 'function') {
128
- try {
129
- currentPromptUi.close()
130
- } catch {
131
- // Swallow errors from inquirer internals
132
- }
133
- currentPromptUi = null
134
- }
135
- }
136
- }
137
- } catch {
138
- // Ignore errors accessing inquirer internals - the prompt state
139
- // may be inconsistent during filtering or other operations
140
- }
141
- return
142
- }
143
-
144
- return // Don't process other escape sequences as standalone escape
145
- }
146
-
147
- // Escape key is byte 27 (0x1b) by itself
148
- // Arrow keys and other sequences start with 27 but have more bytes
149
- if (data.length === 1 && data[0] === 27) {
150
- escapeTriggered = true
151
- // First reject the escape promise to interrupt the prompt
152
- if (escapeReject) {
153
- const reject = escapeReject
154
- escapeReject = null
155
- reject(new EscapeError())
156
- }
157
- // Then close the prompt UI to stop it from rendering
158
- // Do this after rejecting so the error propagates first
159
- // Wrap in try/catch as inquirer internals may change between versions
160
- if (currentPromptUi && typeof currentPromptUi.close === 'function') {
161
- try {
162
- currentPromptUi.close()
163
- } catch {
164
- // Swallow errors from inquirer internals - close() behavior may vary
165
- }
166
- currentPromptUi = null
167
- }
168
- // Clear the screen
169
- console.clear()
170
- }
171
- }
172
-
173
- /**
174
- * Enable global escape key handling for the interactive menu.
175
- * When escape is pressed, the current prompt is closed and escapeTriggered flag is set.
176
- * Call this once at the start of the interactive menu session.
177
- */
178
- export function enableGlobalEscape(): void {
179
- if (globalEscapeEnabled) return
180
- globalEscapeEnabled = true
181
- process.stdin.on('data', onEscapeData)
182
- }
183
-
184
- /**
185
- * Disable global escape key handling and clean up state.
186
- * Call this when exiting interactive mode or in tests to remove the stdin listener.
187
- */
188
- export function disableGlobalEscape(): void {
189
- if (!globalEscapeEnabled) return
190
- process.stdin.off('data', onEscapeData)
191
- globalEscapeEnabled = false
192
- escapeTriggered = false
193
- escapeReject = null
194
- currentPromptUi = null
195
- }
196
-
197
- /**
198
- * Check if escape was triggered and reset the flag.
199
- * Call this at the start of main menu to handle escape from anywhere.
200
- */
201
- export function checkAndResetEscape(): boolean {
202
- const wasTriggered = escapeTriggered
203
- escapeTriggered = false
204
- return wasTriggered
205
- }
206
-
207
- /**
208
- * Enable toggle tracking for the container list.
209
- * @param validTargets - Set of values that are valid toggle targets (container names)
210
- */
211
- export function enableToggleTracking(validTargets: Set<string>): void {
212
- toggleEnabled = true
213
- toggleValidTargets = validTargets
214
- }
215
-
216
- /**
217
- * Disable toggle tracking and clean up state.
218
- */
219
- export function disableToggleTracking(): void {
220
- toggleEnabled = false
221
- toggleValidTargets = new Set()
222
- }
223
-
224
- /**
225
- * Wrapper around inquirer.prompt that registers/unregisters with global escape handler.
226
- * Use this instead of inquirer.prompt() directly for escape key support.
227
- *
228
- * Automatically detects non-interactive mode (piped input, scripts, CI) and throws
229
- * a clear error instead of hanging on user input that can never come.
230
- */
231
- export async function escapeablePrompt<T extends Record<string, unknown>>(
232
- questions: Parameters<typeof inquirer.prompt>[0],
233
- ): Promise<T> {
234
- // Detect non-interactive mode (piped input, scripts, CI environments)
235
- if (!process.stdin.isTTY) {
236
- throw new Error(
237
- 'Cannot prompt in non-interactive mode. Use appropriate flags (--force, --yes, --json) or provide required arguments.',
238
- )
239
- }
240
-
241
- // Create a promise that rejects when escape is pressed
242
- const escapePromise = new Promise<never>((_, reject) => {
243
- escapeReject = reject
244
- })
245
-
246
- try {
247
- const p = inquirer.prompt(questions)
248
- // Register the prompt UI so we can close it on escape
249
- // Use runtime guard to safely access inquirer's internal ui property
250
- // which may change between versions.
251
- // Validated against inquirer@9.3.7 - the prompt object exposes a .ui
252
- // property with a .close() method for programmatic prompt termination.
253
- const promptWithUi = p as unknown as Record<string, unknown>
254
- if (
255
- promptWithUi.ui &&
256
- typeof promptWithUi.ui === 'object' &&
257
- promptWithUi.ui !== null &&
258
- typeof (promptWithUi.ui as Record<string, unknown>).close === 'function'
259
- ) {
260
- currentPromptUi = promptWithUi.ui as Record<string, unknown>
261
- } else {
262
- currentPromptUi = null
263
- }
264
-
265
- // Race the prompt against the escape promise
266
- const result = (await Promise.race([p, escapePromise])) as T
267
- return result
268
- } finally {
269
- escapeReject = null
270
- currentPromptUi = null
271
- }
272
- }
273
-
274
- /**
275
- * Type for autocomplete choices - must have name and value
276
- */
277
- export type FilterableChoice = {
278
- name: string
279
- value: string
280
- short?: string
281
- }
282
-
283
- /**
284
- * Filterable list prompt using inquirer-autocomplete-prompt.
285
- * Allows typing to filter items while still using arrow keys to navigate.
286
- *
287
- * @param choices - Array of choices (items to filter + navigation items)
288
- * @param message - Prompt message
289
- * @param options.filterableCount - Number of items at the start that should be filterable
290
- * (remaining items like Back/separators are always shown)
291
- * @param options.pageSize - Number of items to show at once
292
- * @param options.emptyText - Text to show when filter matches nothing
293
- * @param options.enableToggle - Enable Shift+Tab to toggle items (returns TOGGLE_PREFIX + value)
294
- */
295
- export async function filterableListPrompt(
296
- choices: (FilterableChoice | inquirer.Separator)[],
297
- message: string,
298
- options: {
299
- filterableCount: number
300
- pageSize?: number
301
- emptyText?: string
302
- enableToggle?: boolean
303
- defaultValue?: string // Pre-select this value (cursor starts here)
304
- headerItems?: (FilterableChoice | inquirer.Separator)[] // Shown above filterable items
305
- },
306
- ): Promise<string> {
307
- // Split choices into filterable items and static footer (separators, back buttons, etc.)
308
- const filterableItems = choices.slice(
309
- 0,
310
- options.filterableCount,
311
- ) as FilterableChoice[]
312
- const footerItems = choices.slice(options.filterableCount)
313
-
314
- // Enable toggle tracking if requested
315
- // Build a set of valid toggle targets (the container values from filterable items)
316
- if (options.enableToggle) {
317
- const validTargets = new Set(filterableItems.map((item) => item.value))
318
- enableToggleTracking(validTargets)
319
- }
320
-
321
- // Source function for autocomplete - filters items based on input
322
- const header = options.headerItems || []
323
- async function source(
324
- _answers: Record<string, unknown>,
325
- input: string | undefined,
326
- ): Promise<(FilterableChoice | inquirer.Separator)[]> {
327
- const searchTerm = (input || '').toLowerCase().trim()
328
-
329
- let result: (FilterableChoice | inquirer.Separator)[]
330
-
331
- if (!searchTerm) {
332
- // No filter - show all items
333
- result = [...header, ...filterableItems, ...footerItems]
334
- } else {
335
- // Filter items by matching search term against the display name
336
- // Strip ANSI codes for matching but keep them for display
337
- // eslint-disable-next-line no-control-regex
338
- const ansiPattern = /\x1b\[[0-9;]*m/g
339
- const filtered = filterableItems.filter((item) => {
340
- // Strip ANSI escape codes for matching
341
- const plainName = item.name.replace(ansiPattern, '')
342
- return plainName.toLowerCase().includes(searchTerm)
343
- })
344
-
345
- if (filtered.length === 0) {
346
- // No matches - show empty message and footer
347
- result = [
348
- new inquirer.Separator(
349
- chalk.gray(options.emptyText || `No matches for "${input}"`),
350
- ),
351
- ...footerItems,
352
- ]
353
- } else {
354
- result = [...header, ...filtered, ...footerItems]
355
- }
356
- }
357
-
358
- return result
359
- }
360
-
361
- // Create escape promise for escape key handling
362
- const escapePromise = new Promise<never>((_, reject) => {
363
- escapeReject = reject
364
- })
365
-
366
- try {
367
- const p = inquirer.prompt([
368
- {
369
- type: 'autocomplete',
370
- name: 'selection',
371
- message,
372
- source,
373
- pageSize: options.pageSize || getPageSize(),
374
- emptyText: options.emptyText || 'No matches',
375
- suggestOnly: false,
376
- // Suppress the default "(Use arrow keys or type to search)" suffix
377
- // since we include custom instructions in the message
378
- suffix: '',
379
- // Pre-select a value (cursor starts on this item)
380
- default: options.defaultValue,
381
- },
382
- ])
383
-
384
- // Register the prompt UI for escape and toggle handling
385
- // Store the raw UI object so we can access activePrompt dynamically
386
- // (activePrompt contains selected and currentChoices for the highlighted item)
387
- const promptWithUi = p as unknown as Record<string, unknown>
388
- if (
389
- promptWithUi.ui &&
390
- typeof promptWithUi.ui === 'object' &&
391
- promptWithUi.ui !== null &&
392
- typeof (promptWithUi.ui as Record<string, unknown>).close === 'function'
393
- ) {
394
- currentPromptUi = promptWithUi.ui as Record<string, unknown>
395
- } else {
396
- currentPromptUi = null
397
- }
398
-
399
- const result = (await Promise.race([p, escapePromise])) as {
400
- selection: string
401
- }
402
- return result.selection
403
- } catch (error) {
404
- // Handle toggle (Shift+Tab) - return special value so caller can handle it
405
- if (error instanceof ToggleError) {
406
- return TOGGLE_PREFIX + error.targetValue
407
- }
408
- throw error
409
- } finally {
410
- escapeReject = null
411
- currentPromptUi = null
412
- if (options.enableToggle) {
413
- disableToggleTracking()
414
- }
415
- }
416
- }
417
-
418
- /**
419
- * Check if a prompt result indicates escape was pressed
420
- */
421
- export function wasEscapePressed(result: unknown): boolean {
422
- if (typeof result === 'string') return result === ESCAPE_VALUE
423
- if (typeof result === 'object' && result !== null) {
424
- return Object.values(result).some((v) => v === ESCAPE_VALUE)
425
- }
426
- return false
427
- }
428
-
429
- /**
430
- * Prompt for container name
431
- * @param defaultName - Default value for the container name
432
- * @param options.allowBack - Allow empty input to go back (returns null)
433
- */
434
- export function promptContainerName(
435
- defaultName?: string,
436
- options?: { allowBack?: false },
437
- ): Promise<string>
438
- export function promptContainerName(
439
- defaultName: string | undefined,
440
- options: { allowBack: true },
441
- ): Promise<string | null>
442
- export async function promptContainerName(
443
- defaultName?: string,
444
- options?: { allowBack?: boolean },
445
- ): Promise<string | null> {
446
- const { name } = await escapeablePrompt<{ name: string }>([
447
- {
448
- type: 'input',
449
- name: 'name',
450
- message: 'Container name:',
451
- default: options?.allowBack ? undefined : defaultName,
452
- validate: (input: string) => {
453
- if (options?.allowBack && !input) return true // Allow empty for back
454
- if (!input) return 'Name is required'
455
- if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(input)) {
456
- return 'Name must start with a letter and contain only letters, numbers, hyphens, and underscores'
457
- }
458
- return true
459
- },
460
- },
461
- ])
462
-
463
- if (options?.allowBack && !name) return null
464
- return name
465
- }
466
-
467
- /**
468
- * Prompt for database engine selection
469
- * @param options.includeBack - Include back/main menu navigation options
470
- * @returns Engine name, or BACK_VALUE/MAIN_MENU_VALUE for navigation
471
- */
472
- export async function promptEngine(options?: {
473
- includeBack?: boolean
474
- }): Promise<string> {
475
- const engines = listEngines()
476
-
477
- const engineChoices: FilterableChoice[] = engines.map((e) => ({
478
- name: `${getEngineIcon(e.name)} ${e.displayName} ${chalk.gray(`(versions: ${e.supportedVersions.join(', ')})`)}`,
479
- value: e.name,
480
- short: e.displayName,
481
- }))
482
-
483
- const footerChoices: (FilterableChoice | inquirer.Separator)[] = [
484
- new inquirer.Separator(),
485
- new inquirer.Separator(
486
- chalk.gray(` ${engines.length} engines — type to filter`),
487
- ),
488
- ]
489
-
490
- if (options?.includeBack) {
491
- footerChoices.push(new inquirer.Separator())
492
- footerChoices.push({
493
- name: `${chalk.blue('←')} Back`,
494
- value: BACK_VALUE,
495
- })
496
- footerChoices.push({
497
- name: `${chalk.blue('⌂')} Back to main menu ${chalk.gray('(esc)')}`,
498
- value: MAIN_MENU_VALUE,
499
- })
500
- }
501
-
502
- footerChoices.push(new inquirer.Separator())
503
-
504
- const allChoices = [...engineChoices, ...footerChoices]
505
-
506
- const engine = await filterableListPrompt(
507
- allChoices,
508
- 'Select database engine:',
509
- {
510
- filterableCount: engineChoices.length,
511
- pageSize: getPageSize(),
512
- emptyText: 'No engines match filter',
513
- },
514
- )
515
-
516
- return engine
517
- }
518
-
519
- /**
520
- * Prompt for database version
521
- * Two-step selection: first major version, then specific minor version (if available)
522
- * @param options.includeBack - Include back/main menu navigation options
523
- * @returns Version string, or BACK_VALUE/MAIN_MENU_VALUE for navigation
524
- */
525
- export async function promptVersion(
526
- engineName: string,
527
- options?: { includeBack?: boolean },
528
- ): Promise<string> {
529
- const engine = getEngine(engineName)
530
- const majorVersions = engine.supportedVersions
531
-
532
- // Fetch available versions with a loading indicator
533
- const spinner = ora({
534
- text: 'Fetching available versions...',
535
- color: 'cyan',
536
- }).start()
537
-
538
- let availableVersions: Record<string, string[]>
539
- try {
540
- availableVersions = await engine.fetchAvailableVersions()
541
- spinner.stop()
542
- } catch {
543
- spinner.stop()
544
- // Fall back to major versions only
545
- availableVersions = {}
546
- for (const v of majorVersions) {
547
- availableVersions[v] = []
548
- }
549
- }
550
-
551
- // Step 1: Select major version
552
- type Choice =
553
- | { name: string; value: string; short?: string }
554
- | inquirer.Separator
555
-
556
- const majorChoices: Choice[] = []
557
- const engineDefs = getEngineDefaults(engineName)
558
-
559
- for (let i = 0; i < majorVersions.length; i++) {
560
- const major = majorVersions[i]
561
- const fullVersions = availableVersions[major] || []
562
- const versionCount = fullVersions.length
563
- const isLatestMajor = major === engineDefs.latestVersion
564
-
565
- const countLabel =
566
- versionCount > 0 ? chalk.gray(`(${versionCount} versions)`) : ''
567
- const label = isLatestMajor
568
- ? `${engine.displayName} ${major} ${countLabel} ${chalk.green('← latest')}`
569
- : `${engine.displayName} ${major} ${countLabel}`
570
-
571
- majorChoices.push({
572
- name: label,
573
- value: major,
574
- short: `${engine.displayName} ${major}`,
575
- })
576
- }
577
-
578
- if (options?.includeBack) {
579
- majorChoices.push(new inquirer.Separator())
580
- majorChoices.push({ name: `${chalk.blue('←')} Back`, value: BACK_VALUE })
581
- majorChoices.push({
582
- name: `${chalk.blue('⌂')} Back to main menu ${chalk.gray('(esc)')}`,
583
- value: MAIN_MENU_VALUE,
584
- })
585
- }
586
-
587
- const { majorVersion } = await escapeablePrompt<{ majorVersion: string }>([
588
- {
589
- type: 'list',
590
- name: 'majorVersion',
591
- message: 'Select major version:',
592
- choices: majorChoices,
593
- default: engineDefs.latestVersion, // Default to latest major
594
- },
595
- ])
596
-
597
- // Handle navigation (including escape)
598
- if (
599
- majorVersion === ESCAPE_VALUE ||
600
- majorVersion === BACK_VALUE ||
601
- majorVersion === MAIN_MENU_VALUE
602
- ) {
603
- return majorVersion === ESCAPE_VALUE ? MAIN_MENU_VALUE : majorVersion
604
- }
605
-
606
- // Step 2: Select specific version within the major version
607
- const minorVersions = availableVersions[majorVersion] || []
608
-
609
- if (minorVersions.length === 0) {
610
- // No versions fetched, return major version (will use fallback)
611
- return majorVersion
612
- }
613
-
614
- const minorChoices: Choice[] = minorVersions.map((v, i) => ({
615
- name: i === 0 ? `${v} ${chalk.green('← latest')}` : v,
616
- value: v,
617
- short: v,
618
- }))
619
-
620
- if (options?.includeBack) {
621
- minorChoices.push(new inquirer.Separator())
622
- minorChoices.push({
623
- name: `${chalk.blue('←')} Back to major versions`,
624
- value: BACK_VALUE,
625
- })
626
- minorChoices.push({
627
- name: `${chalk.blue('⌂')} Back to main menu ${chalk.gray('(esc)')}`,
628
- value: MAIN_MENU_VALUE,
629
- })
630
- }
631
-
632
- const { version } = await escapeablePrompt<{ version: string }>([
633
- {
634
- type: 'list',
635
- name: 'version',
636
- message: `Select ${engine.displayName} ${majorVersion} version:`,
637
- choices: minorChoices,
638
- default: minorVersions[0], // Default to latest
639
- },
640
- ])
641
-
642
- // Handle navigation from minor version selection (including escape)
643
- if (version === ESCAPE_VALUE) {
644
- return MAIN_MENU_VALUE
645
- }
646
- if (version === BACK_VALUE) {
647
- // Go back to major version selection (recursive call)
648
- return promptVersion(engineName, options)
649
- }
650
- if (version === MAIN_MENU_VALUE) {
651
- return MAIN_MENU_VALUE
652
- }
653
-
654
- return version
655
- }
656
-
657
- /**
658
- * Prompt for port with conflict detection
659
- * @param defaultPort - Default port number
660
- * @param engine - Engine name for port range lookup
661
- */
662
- export async function promptPort(
663
- defaultPort: number = defaults.port,
664
- engine?: string,
665
- ): Promise<number> {
666
- // Get engine-specific port range
667
- const portRange = engine
668
- ? getEngineDefaults(engine).portRange
669
- : defaults.portRange
670
-
671
- // Get running container ports for conflict detection
672
- // Stopped containers don't block ports - users can manage conflicts themselves
673
- const existingContainers = await containerManager.list()
674
- const containerPorts = new Map<number, string>()
675
- for (const c of existingContainers) {
676
- if (c.port > 0 && c.status === 'running') {
677
- containerPorts.set(c.port, c.name)
678
- }
679
- }
680
-
681
- // Check if default port has a conflict and find a better default
682
- let suggestedPort = defaultPort
683
- const defaultPortContainer = containerPorts.get(defaultPort)
684
- const defaultPortInUse =
685
- !defaultPortContainer && !(await portManager.isPortAvailable(defaultPort))
686
-
687
- if (defaultPortContainer || defaultPortInUse) {
688
- // Find next available port in the engine's port range
689
- try {
690
- const result = await portManager.findAvailablePortExcludingContainers({
691
- preferredPort: defaultPort,
692
- portRange,
693
- })
694
- suggestedPort = result.port
695
- } catch {
696
- // Fall back to default if no ports available
697
- suggestedPort = defaultPort
698
- }
699
- }
700
-
701
- const { port } = await escapeablePrompt<{ port: number }>([
702
- {
703
- type: 'input',
704
- name: 'port',
705
- message: 'Port:',
706
- default: String(suggestedPort),
707
- validate: (input: string) => {
708
- const num = parseInt(input, 10)
709
- if (isNaN(num) || num < 1 || num > 65535) {
710
- return 'Port must be a number between 1 and 65535'
711
- }
712
- return true
713
- },
714
- filter: (input: string) => parseInt(input, 10),
715
- },
716
- ])
717
-
718
- // Check for conflicts after selection
719
- const conflictContainer = containerPorts.get(port)
720
- if (conflictContainer) {
721
- console.log()
722
- console.log(
723
- chalk.yellow(
724
- ` ⚠ Warning: Port ${port} is already assigned to container "${conflictContainer}"`,
725
- ),
726
- )
727
- console.log(
728
- chalk.gray(' Only one container can run on this port at a time.'),
729
- )
730
- console.log()
731
-
732
- const { proceed } = await escapeablePrompt<{ proceed: string }>([
733
- {
734
- type: 'list',
735
- name: 'proceed',
736
- message: 'What would you like to do?',
737
- choices: [
738
- { name: `Use port ${port} anyway`, value: 'continue' },
739
- { name: 'Choose a different port', value: 'retry' },
740
- ],
741
- },
742
- ])
743
-
744
- if (proceed === 'retry') {
745
- return promptPort(defaultPort, engine)
746
- }
747
- } else {
748
- // Check if port is in use by something else
749
- const portAvailable = await portManager.isPortAvailable(port)
750
- if (!portAvailable) {
751
- console.log()
752
- console.log(
753
- chalk.yellow(` ⚠ Warning: Port ${port} is currently in use`),
754
- )
755
- console.log(
756
- chalk.gray(
757
- ' The container will be created but may fail to start until the port is freed.',
758
- ),
759
- )
760
- console.log()
761
-
762
- const { proceed } = await escapeablePrompt<{ proceed: string }>([
763
- {
764
- type: 'list',
765
- name: 'proceed',
766
- message: 'What would you like to do?',
767
- choices: [
768
- { name: `Use port ${port} anyway`, value: 'continue' },
769
- { name: 'Choose a different port', value: 'retry' },
770
- ],
771
- },
772
- ])
773
-
774
- if (proceed === 'retry') {
775
- return promptPort(defaultPort, engine)
776
- }
777
- }
778
- }
779
-
780
- return port
781
- }
782
-
783
- // Prompt for confirmation using arrow-key selection
784
- export async function promptConfirm(
785
- message: string,
786
- defaultValue: boolean = true,
787
- ): Promise<boolean> {
788
- const { confirmed } = await escapeablePrompt<{ confirmed: string }>([
789
- {
790
- type: 'list',
791
- name: 'confirmed',
792
- message,
793
- choices: [
794
- { name: 'Yes', value: 'yes' },
795
- { name: 'No', value: 'no' },
796
- ],
797
- default: defaultValue ? 'yes' : 'no',
798
- },
799
- ])
800
-
801
- return confirmed === 'yes'
802
- }
803
-
804
- /**
805
- * Prompt for container selection from a list with type-to-filter support
806
- * @param containers - List of containers to choose from
807
- * @param message - Prompt message
808
- * @param options - Optional settings
809
- * @param options.includeBack - Include back/main menu navigation options (returns null when selected)
810
- */
811
- export async function promptContainerSelect(
812
- containers: ContainerConfig[],
813
- message: string = 'Select container:',
814
- options: { includeBack?: boolean } = {},
815
- ): Promise<string | null> {
816
- if (containers.length === 0) {
817
- return null
818
- }
819
-
820
- // Build filterable container choices
821
- const containerChoices: FilterableChoice[] = containers.map((c) => ({
822
- name: `${c.name} ${chalk.gray(`(${getEngineIcon(c.engine)}${c.engine} ${c.version}, port ${c.port})`)} ${
823
- c.status === 'running'
824
- ? chalk.green('● running')
825
- : chalk.gray('○ stopped')
826
- }`,
827
- value: c.name,
828
- short: c.name,
829
- }))
830
-
831
- // Build footer with navigation options
832
- const footerChoices: (FilterableChoice | inquirer.Separator)[] = []
833
- if (options.includeBack) {
834
- footerChoices.push(new inquirer.Separator())
835
- footerChoices.push({ name: `${chalk.blue('←')} Back`, value: BACK_VALUE })
836
- footerChoices.push({
837
- name: `${chalk.blue('⌂')} Back to main menu ${chalk.gray('(esc)')}`,
838
- value: MAIN_MENU_VALUE,
839
- })
840
- footerChoices.push(new inquirer.Separator())
841
- }
842
-
843
- const allChoices = [...containerChoices, ...footerChoices]
844
-
845
- const container = await filterableListPrompt(allChoices, message, {
846
- filterableCount: containerChoices.length,
847
- pageSize: getPageSize(),
848
- emptyText: 'No containers match filter',
849
- })
850
-
851
- // Handle navigation (including escape)
852
- if (
853
- container === ESCAPE_VALUE ||
854
- container === BACK_VALUE ||
855
- container === MAIN_MENU_VALUE
856
- ) {
857
- return null
858
- }
859
-
860
- return container
861
- }
862
-
863
- /**
864
- * Sanitize a string to be a valid database name
865
- * Replaces invalid characters with underscores
866
- */
867
- function sanitizeDatabaseName(name: string): string {
868
- // Replace invalid characters with underscores
869
- // Note: hyphens are excluded because they require quoting in SQL
870
- let sanitized = name.replace(/[^a-zA-Z0-9_]/g, '_')
871
- // Ensure it starts with a letter or underscore
872
- if (sanitized && !/^[a-zA-Z_]/.test(sanitized)) {
873
- sanitized = '_' + sanitized
874
- }
875
- // Collapse multiple underscores
876
- sanitized = sanitized.replace(/_+/g, '_')
877
- // Trim trailing underscores
878
- sanitized = sanitized.replace(/_+$/, '')
879
- // Fallback if result is empty (e.g., input was "---")
880
- if (!sanitized) {
881
- sanitized = 'db'
882
- }
883
- return sanitized
884
- }
885
-
886
- /**
887
- * Prompt for database name
888
- * @param defaultName - Default value for the database name
889
- * @param engine - Database engine (mysql shows "schema" terminology)
890
- * @param options.allowBack - Allow empty input to go back (returns null)
891
- * @param options.existingDatabases - List of existing database names for context
892
- * @param options.disallowExisting - Validate that name is not in existingDatabases
893
- */
894
- export function promptDatabaseName(
895
- defaultName?: string,
896
- engine?: string,
897
- options?: {
898
- allowBack?: false
899
- existingDatabases?: string[]
900
- disallowExisting?: boolean
901
- },
902
- ): Promise<string>
903
- export function promptDatabaseName(
904
- defaultName: string | undefined,
905
- engine: string | undefined,
906
- options: {
907
- allowBack: true
908
- existingDatabases?: string[]
909
- disallowExisting?: boolean
910
- },
911
- ): Promise<string | null>
912
- export async function promptDatabaseName(
913
- defaultName?: string,
914
- engine?: string,
915
- options?: {
916
- allowBack?: boolean
917
- existingDatabases?: string[]
918
- disallowExisting?: boolean
919
- },
920
- ): Promise<string | null> {
921
- // MySQL uses "schema" terminology (database and schema are synonymous)
922
- const baseLabel =
923
- engine === 'mysql' ? 'Database (schema) name' : 'Database name'
924
-
925
- // Sanitize the default name to ensure it's valid
926
- const sanitizedDefault = defaultName
927
- ? sanitizeDatabaseName(defaultName)
928
- : undefined
929
-
930
- // When allowBack is true, show the default in the message (since we can't use inquirer's default)
931
- const label =
932
- options?.allowBack && sanitizedDefault
933
- ? `${baseLabel} [${sanitizedDefault}]:`
934
- : `${baseLabel}:`
935
-
936
- const { database } = await escapeablePrompt<{ database: string }>([
937
- {
938
- type: 'input',
939
- name: 'database',
940
- message: label,
941
- default: options?.allowBack ? undefined : sanitizedDefault,
942
- validate: (input: string) => {
943
- if (options?.allowBack && !input) return true // Allow empty for back
944
- if (!input) return 'Database name is required'
945
- // PostgreSQL database naming rules (also valid for MySQL)
946
- // Hyphens excluded to avoid requiring quoted identifiers in SQL
947
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(input)) {
948
- return 'Database name must start with a letter or underscore and contain only letters, numbers, and underscores'
949
- }
950
- if (input.length > 63) {
951
- return 'Database name must be 63 characters or less'
952
- }
953
- if (
954
- options?.disallowExisting &&
955
- options.existingDatabases?.includes(input)
956
- ) {
957
- return `Database "${input}" already exists. Choose a different name.`
958
- }
959
- return true
960
- },
961
- },
962
- ])
963
-
964
- if (options?.allowBack && !database) return null
965
- return database
966
- }
967
-
968
- /**
969
- * Prompt to select a database from a list of databases in a container
970
- * @param options.includeBack - Include a back option (returns null when selected)
971
- */
972
- export function promptDatabaseSelect(
973
- databases: string[],
974
- message?: string,
975
- options?: { includeBack?: false },
976
- ): Promise<string>
977
- export function promptDatabaseSelect(
978
- databases: string[],
979
- message: string | undefined,
980
- options: { includeBack: true },
981
- ): Promise<string | null>
982
- export async function promptDatabaseSelect(
983
- databases: string[],
984
- message: string = 'Select database:',
985
- options?: { includeBack?: boolean },
986
- ): Promise<string | null> {
987
- if (databases.length === 0) {
988
- throw new Error('No databases available to select')
989
- }
990
-
991
- if (databases.length === 1 && !options?.includeBack) {
992
- return databases[0]
993
- }
994
-
995
- type Choice =
996
- | { name: string; value: string; short?: string }
997
- | inquirer.Separator
998
-
999
- const choices: Choice[] = databases.map((db, index) => ({
1000
- name: index === 0 ? `${db} ${chalk.gray('(primary)')}` : db,
1001
- value: db,
1002
- short: db,
1003
- }))
1004
-
1005
- if (options?.includeBack) {
1006
- choices.push(new inquirer.Separator())
1007
- choices.push({ name: `${chalk.blue('←')} Back`, value: BACK_VALUE })
1008
- }
1009
-
1010
- const { database } = await escapeablePrompt<{ database: string }>([
1011
- {
1012
- type: 'list',
1013
- name: 'database',
1014
- message,
1015
- choices,
1016
- },
1017
- ])
1018
-
1019
- if (database === BACK_VALUE) return null
1020
- return database
1021
- }
1022
-
1023
- /**
1024
- * Prompt for backup format selection
1025
- * Uses centralized format configuration from config/backup-formats.ts
1026
- * Dynamically builds choices from engine-specific format definitions
1027
- * @param options.includeBack - Include a back option (returns null when selected)
1028
- */
1029
- export function promptBackupFormat(
1030
- engine: Engine,
1031
- options?: { includeBack?: false },
1032
- ): Promise<BackupFormatType>
1033
- export function promptBackupFormat(
1034
- engine: Engine,
1035
- options: { includeBack: true },
1036
- ): Promise<BackupFormatType | null>
1037
- export async function promptBackupFormat(
1038
- engine: Engine,
1039
- options?: { includeBack?: boolean },
1040
- ): Promise<BackupFormatType | null> {
1041
- // If engine doesn't support format choice (e.g., ClickHouse), return default
1042
- if (!supportsFormatChoice(engine)) {
1043
- return getDefaultFormat(engine)
1044
- }
1045
-
1046
- const engineFormats = BACKUP_FORMATS[engine]
1047
-
1048
- type Choice =
1049
- | { name: string; value: string; short?: string }
1050
- | inquirer.Separator
1051
-
1052
- // Build choices dynamically from the engine's format definitions
1053
- const choices: Choice[] = Object.entries(engineFormats.formats).map(
1054
- ([key, info]) => ({
1055
- name: `${info.label} ${chalk.gray(`- ${info.description}`)}`,
1056
- value: key,
1057
- }),
1058
- )
1059
-
1060
- if (options?.includeBack) {
1061
- choices.push(new inquirer.Separator())
1062
- choices.push({ name: `${chalk.blue('←')} Back`, value: BACK_VALUE })
1063
- }
1064
-
1065
- const { format } = await escapeablePrompt<{ format: string }>([
1066
- {
1067
- type: 'list',
1068
- name: 'format',
1069
- message: 'Select backup format:',
1070
- choices,
1071
- default: engineFormats.defaultFormat,
1072
- },
1073
- ])
1074
-
1075
- if (format === BACK_VALUE) return null
1076
- return format as BackupFormatType
1077
- }
1078
-
1079
- /**
1080
- * Prompt for backup output directory
1081
- * @returns Directory path or null if cancelled
1082
- */
1083
- export async function promptBackupDirectory(): Promise<string | null> {
1084
- const cwd = process.cwd()
1085
-
1086
- const { choice } = await escapeablePrompt<{ choice: string }>([
1087
- {
1088
- type: 'list',
1089
- name: 'choice',
1090
- message: 'Where to save the backup?',
1091
- choices: [
1092
- {
1093
- name: `${chalk.cyan('.')} Current directory ${chalk.gray(`(${cwd})`)}`,
1094
- value: 'cwd',
1095
- },
1096
- {
1097
- name: `${chalk.yellow('...')} Choose different directory`,
1098
- value: 'custom',
1099
- },
1100
- new inquirer.Separator(),
1101
- { name: `${chalk.blue('←')} Back`, value: BACK_VALUE },
1102
- ],
1103
- },
1104
- ])
1105
-
1106
- if (choice === BACK_VALUE) return null
1107
- if (choice === 'cwd') return cwd
1108
-
1109
- const { customPath } = await escapeablePrompt<{ customPath: string }>([
1110
- {
1111
- type: 'input',
1112
- name: 'customPath',
1113
- message: 'Enter directory path:',
1114
- default: cwd,
1115
- validate: (input: string) => {
1116
- if (!input.trim()) return 'Directory path is required'
1117
- const resolved = resolve(input.replace(/^~/, process.env.HOME || ''))
1118
- if (existsSync(resolved)) {
1119
- if (!statSync(resolved).isDirectory()) {
1120
- return 'Path is not a directory'
1121
- }
1122
- }
1123
- // Directory will be created if it doesn't exist
1124
- return true
1125
- },
1126
- },
1127
- ])
1128
-
1129
- return resolve(customPath.replace(/^~/, process.env.HOME || ''))
1130
- }
1131
-
1132
- /**
1133
- * Prompt for backup filename
1134
- * @param options.allowBack - Allow empty input to go back (returns null)
1135
- */
1136
- export function promptBackupFilename(
1137
- defaultName: string,
1138
- options?: { allowBack?: false },
1139
- ): Promise<string>
1140
- export function promptBackupFilename(
1141
- defaultName: string,
1142
- options: { allowBack: true },
1143
- ): Promise<string | null>
1144
- export async function promptBackupFilename(
1145
- defaultName: string,
1146
- options?: { allowBack?: boolean },
1147
- ): Promise<string | null> {
1148
- // Show the default in the message when allowBack is true
1149
- const message = options?.allowBack
1150
- ? `Backup filename [${defaultName}]:`
1151
- : 'Backup filename:'
1152
-
1153
- const { filename } = await escapeablePrompt<{ filename: string }>([
1154
- {
1155
- type: 'input',
1156
- name: 'filename',
1157
- message,
1158
- default: options?.allowBack ? undefined : defaultName,
1159
- validate: (input: string) => {
1160
- if (options?.allowBack && !input) return true // Allow empty for back
1161
- if (!input) return 'Filename is required'
1162
- if (!/^[a-zA-Z0-9_-]+$/.test(input)) {
1163
- return 'Filename must contain only letters, numbers, underscores, and hyphens'
1164
- }
1165
- return true
1166
- },
1167
- },
1168
- ])
1169
-
1170
- if (options?.allowBack && !filename) return null
1171
- return filename
1172
- }
1173
-
1174
- export type CreateOptions = {
1175
- name: string
1176
- engine: string
1177
- version: string
1178
- port: number
1179
- database: string
1180
- path?: string // SQLite file path
1181
- }
1182
-
1183
- /**
1184
- * Prompt for file-based database (SQLite/DuckDB) file location
1185
- * Similar to the relocate logic in container-handlers.ts
1186
- */
1187
- export async function promptFileDatabasePath(
1188
- containerName: string,
1189
- extension: string = '.sqlite',
1190
- ): Promise<string | undefined> {
1191
- const defaultPath = `./${containerName}${extension}`
1192
- const dbType = extension === '.duckdb' ? 'DuckDB' : 'SQLite'
1193
-
1194
- console.log(
1195
- chalk.gray(
1196
- ` ${dbType} databases are stored as files in your project directory.`,
1197
- ),
1198
- )
1199
- console.log(chalk.gray(` Default: ${defaultPath}`))
1200
- console.log()
1201
-
1202
- const { useDefault } = await escapeablePrompt<{ useDefault: string }>([
1203
- {
1204
- type: 'list',
1205
- name: 'useDefault',
1206
- message: 'Where should the database file be created?',
1207
- choices: [
1208
- { name: `Use default location (${defaultPath})`, value: 'default' },
1209
- { name: 'Specify custom path', value: 'custom' },
1210
- ],
1211
- },
1212
- ])
1213
-
1214
- if (useDefault === 'default') {
1215
- return undefined // Use default
1216
- }
1217
-
1218
- const { inputPath } = await escapeablePrompt<{ inputPath: string }>([
1219
- {
1220
- type: 'input',
1221
- name: 'inputPath',
1222
- message: 'File path:',
1223
- default: defaultPath,
1224
- validate: (input: string) => {
1225
- if (!input) return 'Path is required'
1226
- return true
1227
- },
1228
- },
1229
- ])
1230
-
1231
- // Expand ~ to home directory
1232
- let expandedPath = inputPath
1233
- if (inputPath === '~') {
1234
- expandedPath = homedir()
1235
- } else if (inputPath.startsWith('~/')) {
1236
- expandedPath = join(homedir(), inputPath.slice(2))
1237
- }
1238
-
1239
- // Convert relative paths to absolute
1240
- if (!expandedPath.startsWith('/')) {
1241
- expandedPath = resolve(process.cwd(), expandedPath)
1242
- }
1243
-
1244
- // Check if path looks like a file (has db extension) or directory
1245
- const hasDbExtension = /\.(sqlite3?|db|duckdb|ddb)$/i.test(expandedPath)
1246
-
1247
- // Treat as directory if:
1248
- // - ends with /
1249
- // - exists and is a directory
1250
- // - doesn't have a database file extension (assume it's a directory path)
1251
- const isDirectory =
1252
- expandedPath.endsWith('/') ||
1253
- (existsSync(expandedPath) && statSync(expandedPath).isDirectory()) ||
1254
- !hasDbExtension
1255
-
1256
- let finalPath: string
1257
- if (isDirectory) {
1258
- // Remove trailing slash if present, then append filename
1259
- const dirPath = expandedPath.endsWith('/')
1260
- ? expandedPath.slice(0, -1)
1261
- : expandedPath
1262
- finalPath = join(dirPath, `${containerName}${extension}`)
1263
- } else {
1264
- finalPath = expandedPath
1265
- }
1266
-
1267
- // Check if file already exists
1268
- if (existsSync(finalPath)) {
1269
- console.log(chalk.yellow(` Warning: File already exists: ${finalPath}`))
1270
- const { overwrite } = await escapeablePrompt<{ overwrite: string }>([
1271
- {
1272
- type: 'list',
1273
- name: 'overwrite',
1274
- message:
1275
- 'A file already exists at this location. What would you like to do?',
1276
- choices: [
1277
- { name: 'Choose a different path', value: 'different' },
1278
- { name: 'Cancel', value: 'cancel' },
1279
- ],
1280
- },
1281
- ])
1282
-
1283
- if (overwrite === 'cancel') {
1284
- throw new Error('Creation cancelled')
1285
- }
1286
-
1287
- // Recursively prompt again
1288
- return promptFileDatabasePath(containerName, extension)
1289
- }
1290
-
1291
- return finalPath
1292
- }
1293
-
1294
- // Full interactive create flow
1295
- export async function promptCreateOptions(): Promise<CreateOptions> {
1296
- console.log(chalk.cyan('\n ▣ Create New Database Container\n'))
1297
-
1298
- const engine = await promptEngine()
1299
- const version = await promptVersion(engine)
1300
- const name = await promptContainerName()
1301
- const database = await promptDatabaseName(name, engine) // Default to container name
1302
-
1303
- // File-based databases (SQLite/DuckDB) don't need a port but need a path
1304
- let port = 0
1305
- let path: string | undefined
1306
- if (engine === 'sqlite') {
1307
- path = await promptFileDatabasePath(name, '.sqlite')
1308
- } else if (engine === 'duckdb') {
1309
- path = await promptFileDatabasePath(name, '.duckdb')
1310
- } else {
1311
- const engineDefaults = getEngineDefaults(engine)
1312
- port = await promptPort(engineDefaults.defaultPort, engine)
1313
- }
1314
-
1315
- return { name, engine, version, port, database, path }
1316
- }
1317
-
1318
- /**
1319
- * Prompt user to install missing database client tools
1320
- *
1321
- * @param missingTool - The name of the missing tool (e.g., 'psql', 'pg_dump', 'mysql')
1322
- * @param engine - The database engine (defaults to 'postgresql')
1323
- * @returns true if installation was successful, false otherwise.
1324
- *
1325
- * Note: For PostgreSQL, this function always returns false because PostgreSQL
1326
- * client tools (psql, pg_dump, etc.) are bundled with the engine binaries from
1327
- * hostdb. Callers should treat this as "use bundled tools via spindb engines
1328
- * download postgresql" rather than an installation failure.
1329
- */
1330
- export async function promptInstallDependencies(
1331
- missingTool: string,
1332
- engine: string = 'postgresql',
1333
- ): Promise<boolean> {
1334
- const platform = getCurrentPlatform()
1335
-
1336
- console.log()
1337
- console.log(
1338
- chalk.yellow(` Database client tool "${missingTool}" is not installed.`),
1339
- )
1340
- console.log()
1341
-
1342
- // Check what package manager is available
1343
- const packageManager = await detectPackageManager()
1344
-
1345
- if (!packageManager) {
1346
- console.log(chalk.red(' No supported package manager found.'))
1347
- console.log()
1348
-
1349
- // Get instructions from the dependency registry
1350
- const engineDeps = getEngineDependencies(engine)
1351
- if (engineDeps) {
1352
- // Find the specific dependency or use the first one for general instructions
1353
- const dep =
1354
- engineDeps.dependencies.find((d) => d.binary === missingTool) ||
1355
- engineDeps.dependencies[0]
1356
-
1357
- if (dep) {
1358
- const instructions = getManualInstallInstructions(dep, platform)
1359
- console.log(
1360
- chalk.gray(
1361
- ` Please install ${engineDeps.displayName} client tools:`,
1362
- ),
1363
- )
1364
- console.log()
1365
- for (const instruction of instructions) {
1366
- console.log(chalk.gray(` ${instruction}`))
1367
- }
1368
- }
1369
- }
1370
- console.log()
1371
- return false
1372
- }
1373
-
1374
- console.log(
1375
- chalk.gray(
1376
- ` Detected package manager: ${chalk.white(packageManager.name)}`,
1377
- ),
1378
- )
1379
- console.log()
1380
-
1381
- // Get engine display name
1382
- const engineDeps = getEngineDependencies(engine)
1383
- const engineName = engineDeps?.displayName || engine
1384
-
1385
- // In CI environments (no TTY or CI env var), auto-install without prompting
1386
- const isCI = !!(
1387
- process.env.CI ||
1388
- process.env.GITHUB_ACTIONS ||
1389
- !process.stdin.isTTY
1390
- )
1391
-
1392
- let shouldInstall = 'yes'
1393
-
1394
- if (!isCI) {
1395
- const response = await escapeablePrompt<{ shouldInstall: string }>([
1396
- {
1397
- type: 'list',
1398
- name: 'shouldInstall',
1399
- message: `Would you like to install ${engineName} client tools now?`,
1400
- choices: [
1401
- { name: 'Yes, install now', value: 'yes' },
1402
- { name: 'No, I will install manually', value: 'no' },
1403
- ],
1404
- default: 'yes',
1405
- },
1406
- ])
1407
- shouldInstall = response.shouldInstall
1408
- } else {
1409
- console.log(
1410
- chalk.gray(
1411
- ` CI environment detected - auto-installing ${engineName} client tools...`,
1412
- ),
1413
- )
1414
- }
1415
-
1416
- if (shouldInstall === 'no') {
1417
- console.log()
1418
- console.log(chalk.gray(' To install manually, run:'))
1419
-
1420
- // Get the specific dependency and build install command info
1421
- if (engineDeps) {
1422
- const dep = engineDeps.dependencies.find((d) => d.binary === missingTool)
1423
- if (dep) {
1424
- const pkgDef = dep.packages[packageManager.id]
1425
- if (pkgDef) {
1426
- const installCmd = packageManager.config.installTemplate.replace(
1427
- '{package}',
1428
- pkgDef.package,
1429
- )
1430
- console.log(chalk.cyan(` ${installCmd}`))
1431
- if (pkgDef.postInstall) {
1432
- for (const postCmd of pkgDef.postInstall) {
1433
- console.log(chalk.cyan(` ${postCmd}`))
1434
- }
1435
- }
1436
- }
1437
- }
1438
- }
1439
- console.log()
1440
- return false
1441
- }
1442
-
1443
- console.log()
1444
-
1445
- // PostgreSQL client tools are bundled with hostdb binaries
1446
- if (engine === 'postgresql') {
1447
- console.log(
1448
- chalk.cyan(
1449
- ' PostgreSQL client tools are bundled with the engine binaries.',
1450
- ),
1451
- )
1452
- console.log(
1453
- chalk.cyan(' Download them with: spindb engines download postgresql'),
1454
- )
1455
- console.log()
1456
- return false
1457
- }
1458
-
1459
- // For other engines, use the generic installer
1460
- console.log(
1461
- chalk.cyan(` Installing ${engineName} with ${packageManager.name}...`),
1462
- )
1463
- console.log(chalk.gray(' You may be prompted for your password.'))
1464
- console.log()
1465
-
1466
- try {
1467
- const results = await installEngineDependencies(engine, packageManager)
1468
- const allSuccess = results.every((r) => r.success)
1469
-
1470
- if (allSuccess) {
1471
- console.log()
1472
- console.log(chalk.green(` ${engineName} tools installed successfully!`))
1473
- console.log(chalk.gray(' Continuing with your operation...'))
1474
- console.log()
1475
- return true
1476
- } else {
1477
- const failed = results.filter((r) => !r.success)
1478
- console.log()
1479
- console.log(chalk.red(' Some installations failed:'))
1480
- for (const f of failed) {
1481
- console.log(chalk.red(` ${f.dependency.name}: ${f.error}`))
1482
- }
1483
- console.log()
1484
-
1485
- // Show manual install instructions
1486
- if (engineDeps) {
1487
- const instructions = getManualInstallInstructions(
1488
- engineDeps.dependencies[0],
1489
- platform,
1490
- )
1491
- if (instructions.length > 0) {
1492
- console.log(chalk.gray(' To install manually:'))
1493
- for (const instruction of instructions) {
1494
- console.log(chalk.gray(` ${instruction}`))
1495
- }
1496
- console.log()
1497
- }
1498
- }
1499
-
1500
- return false
1501
- }
1502
- } catch (error) {
1503
- const e = error as Error
1504
- console.log()
1505
- console.log(chalk.red(` Installation failed: ${e.message}`))
1506
- console.log()
1507
-
1508
- // Show manual install instructions on error
1509
- if (engineDeps) {
1510
- const instructions = getManualInstallInstructions(
1511
- engineDeps.dependencies[0],
1512
- platform,
1513
- )
1514
- if (instructions.length > 0) {
1515
- console.log(chalk.gray(' To install manually:'))
1516
- for (const instruction of instructions) {
1517
- console.log(chalk.gray(` ${instruction}`))
1518
- }
1519
- console.log()
1520
- }
1521
- }
1522
-
1523
- return false
1524
- }
1525
- }