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
@@ -1,1429 +0,0 @@
1
- import { spawn, type SpawnOptions } from 'child_process'
2
- import { existsSync } from 'fs'
3
- import { mkdir, writeFile, readFile, unlink } from 'fs/promises'
4
- import { join, dirname } from 'path'
5
- import { BaseEngine } from '../base-engine'
6
- import { paths } from '../../config/paths'
7
- import { getEngineDefaults } from '../../config/defaults'
8
- import { platformService, isWindows } from '../../core/platform-service'
9
- import { configManager } from '../../core/config-manager'
10
- import {
11
- logDebug,
12
- logWarning,
13
- assertValidUsername,
14
- } from '../../core/error-handler'
15
- import { processManager } from '../../core/process-manager'
16
- import { portManager } from '../../core/port-manager'
17
- import { couchdbBinaryManager } from './binary-manager'
18
- import { getBinaryUrl } from './binary-urls'
19
- import {
20
- normalizeVersion,
21
- SUPPORTED_MAJOR_VERSIONS,
22
- COUCHDB_VERSION_MAP,
23
- } from './version-maps'
24
- import { fetchAvailableVersions as fetchHostdbVersions } from './hostdb-releases'
25
- import {
26
- detectBackupFormat as detectBackupFormatImpl,
27
- restoreBackup,
28
- } from './restore'
29
- import { createBackup } from './backup'
30
- import { couchdbApiRequest } from './api-client'
31
- import {
32
- type Platform,
33
- type Arch,
34
- type ContainerConfig,
35
- type ProgressCallback,
36
- type BackupFormat,
37
- type BackupOptions,
38
- type BackupResult,
39
- type RestoreResult,
40
- type DumpResult,
41
- type StatusResult,
42
- type QueryResult,
43
- type QueryOptions,
44
- type CreateUserOptions,
45
- type UserCredentials,
46
- } from '../../types'
47
- import { parseRESTAPIResult } from '../../core/query-parser'
48
-
49
- const ENGINE = 'couchdb'
50
- const engineDef = getEngineDefaults(ENGINE)
51
-
52
- /**
53
- * Get the correct extension for CouchDB binary.
54
- * On Windows, CouchDB uses a .cmd batch file, not .exe
55
- */
56
- function getCouchDBExtension(): string {
57
- return isWindows() ? '.cmd' : ''
58
- }
59
-
60
- /**
61
- * Generate CouchDB local.ini configuration content
62
- * CouchDB 3.x requires at least one admin account to start
63
- */
64
- function generateCouchDBConfig(options: {
65
- port: number
66
- dataDir: string
67
- logDir: string
68
- bindAddress?: string
69
- }): string {
70
- const bindAddress = options.bindAddress || '127.0.0.1'
71
-
72
- return `; SpinDB generated CouchDB configuration
73
- [couchdb]
74
- database_dir = ${options.dataDir}
75
- view_index_dir = ${options.dataDir}
76
-
77
- [chttpd]
78
- port = ${options.port}
79
- bind_address = ${bindAddress}
80
- ; Allow anonymous access for local development (no login required)
81
- require_valid_user = false
82
-
83
- [chttpd_auth]
84
- ; Allow anonymous access to Fauxton dashboard
85
- require_valid_user = false
86
-
87
- [log]
88
- file = ${options.logDir}/couchdb.log
89
- level = info
90
-
91
- [admins]
92
- ; CouchDB 3.x requires admin account - credentials available if needed: admin/admin
93
- admin = admin
94
- `
95
- }
96
-
97
- /**
98
- * Generate container-specific vm.args with unique Erlang node name
99
- * Each CouchDB instance needs a unique node name to avoid conflicts
100
- */
101
- function generateVmArgs(port: number, _containerDir: string): string {
102
- // Use port in node name to ensure uniqueness
103
- const nodeName = `couchdb_${port}@127.0.0.1`
104
-
105
- // Read base vm.args and replace the node name
106
- return `# SpinDB generated CouchDB vm.args
107
- # Unique node name based on port to allow multiple instances
108
- -name ${nodeName}
109
-
110
- # All nodes must share the same magic cookie for distributed Erlang to work.
111
- # -setcookie
112
-
113
- # Which interfaces should the node listen on?
114
- -kernel inet_dist_use_interface {127,0,0,1}
115
-
116
- # Tell kernel and SASL not to log anything
117
- -kernel error_logger silent
118
- -sasl sasl_error_logger false
119
-
120
- # Prevent overlapping partitions
121
- -kernel prevent_overlapping_partitions false
122
-
123
- # Erlang process limit
124
- +P 1048576
125
-
126
- # Increase the pool of dirty IO schedulers
127
- +SDio 16
128
-
129
- # Increase distribution buffer size
130
- +zdbbl 32768
131
-
132
- # Disable interactive shell
133
- +Bd -noinput
134
-
135
- # Set maximum SSL session lifetime
136
- -ssl session_lifetime 300
137
-
138
- # OS Mon Settings - disable all monitoring on Windows to avoid win32sysinfo issues
139
- -os_mon start_cpu_sup false
140
- -os_mon start_memsup false
141
- -os_mon start_disksup false
142
- `
143
- }
144
-
145
- /**
146
- * Generate Erlang sys.config to disable os_mon features before application starts.
147
- * On Windows, os_mon tries to use win32sysinfo which may crash if the port program
148
- * is missing or broken. Setting these in sys.config takes effect before os_mon starts.
149
- */
150
- function generateSysConfig(): string {
151
- // Minimal Erlang sys.config - no comments, just config
152
- // os_mon settings must be set BEFORE the application starts
153
- return `[{os_mon,[{start_cpu_sup,false},{start_disksup,false},{start_memsup,false}]}].
154
- `
155
- }
156
-
157
- /**
158
- * Parse a CouchDB connection string for remote operations
159
- */
160
- function parseCouchDBConnectionString(connectionString: string): {
161
- baseUrl: string
162
- headers: Record<string, string>
163
- database?: string
164
- } {
165
- let url: URL
166
- let scheme = 'http'
167
-
168
- // Handle couchdb:// scheme by converting to http://
169
- let normalized = connectionString.trim()
170
- if (normalized.startsWith('couchdb://')) {
171
- normalized = normalized.replace('couchdb://', 'http://')
172
- }
173
-
174
- // Ensure scheme is present
175
- if (!normalized.startsWith('http://') && !normalized.startsWith('https://')) {
176
- normalized = `http://${normalized}`
177
- }
178
-
179
- try {
180
- url = new URL(normalized)
181
- scheme = url.protocol.replace(':', '')
182
- } catch {
183
- throw new Error(
184
- `Invalid CouchDB connection string: ${connectionString}\n` +
185
- 'Expected format: http://host:port or couchdb://host:port',
186
- )
187
- }
188
-
189
- const headers: Record<string, string> = {
190
- 'Content-Type': 'application/json',
191
- }
192
-
193
- // Handle basic auth if present
194
- if (url.username && url.password) {
195
- const auth = Buffer.from(`${url.username}:${url.password}`).toString(
196
- 'base64',
197
- )
198
- headers['Authorization'] = `Basic ${auth}`
199
- }
200
-
201
- // Construct base URL without auth and query params
202
- const port = url.port || '5984'
203
- const baseUrl = `${scheme}://${url.hostname}:${port}`
204
-
205
- // Extract database from pathname
206
- const pathname = url.pathname || ''
207
- const database =
208
- pathname.length > 1 ? pathname.slice(1).split('/')[0] : undefined
209
-
210
- return { baseUrl, headers, database }
211
- }
212
-
213
- /**
214
- * Make an HTTP request to a remote CouchDB server
215
- */
216
- async function remoteCouchDBRequest(
217
- baseUrl: string,
218
- method: string,
219
- path: string,
220
- headers: Record<string, string>,
221
- body?: Record<string, unknown>,
222
- timeoutMs = 30000,
223
- ): Promise<{ status: number; data: unknown }> {
224
- const url = `${baseUrl}${path}`
225
-
226
- const controller = new AbortController()
227
- const timeoutId = setTimeout(() => controller.abort(), timeoutMs)
228
-
229
- const options: RequestInit = {
230
- method,
231
- headers,
232
- signal: controller.signal,
233
- }
234
-
235
- if (body) {
236
- options.body = JSON.stringify(body)
237
- }
238
-
239
- try {
240
- const response = await fetch(url, options)
241
-
242
- let data: unknown
243
- const contentType = response.headers.get('content-type') || ''
244
- if (contentType.includes('application/json')) {
245
- data = await response.json()
246
- } else {
247
- data = await response.text()
248
- }
249
-
250
- return { status: response.status, data }
251
- } catch (error) {
252
- if (error instanceof Error && error.name === 'AbortError') {
253
- throw new Error(
254
- `Remote CouchDB request timed out after ${timeoutMs / 1000}s: ${method} ${path}`,
255
- )
256
- }
257
- throw error
258
- } finally {
259
- clearTimeout(timeoutId)
260
- }
261
- }
262
-
263
- export class CouchDBEngine extends BaseEngine {
264
- name = ENGINE
265
- displayName = 'CouchDB'
266
- defaultPort = engineDef.defaultPort
267
- supportedVersions = SUPPORTED_MAJOR_VERSIONS
268
-
269
- // Get platform info for binary operations
270
- getPlatformInfo(): { platform: Platform; arch: Arch } {
271
- return platformService.getPlatformInfo()
272
- }
273
-
274
- // Fetch available versions from hostdb
275
- async fetchAvailableVersions(): Promise<Record<string, string[]>> {
276
- return fetchHostdbVersions()
277
- }
278
-
279
- // Get binary download URL from hostdb
280
- getBinaryUrl(version: string, platform: Platform, arch: Arch): string {
281
- return getBinaryUrl(version, platform, arch)
282
- }
283
-
284
- // Resolves version string to full version (e.g., '3' -> '3.5.1')
285
- resolveFullVersion(version: string): string {
286
- if (/^\d+\.\d+\.\d+$/.test(version)) {
287
- return version
288
- }
289
- if (COUCHDB_VERSION_MAP[version]) {
290
- return COUCHDB_VERSION_MAP[version]
291
- }
292
- // Normalize to exactly 3 segments (e.g., "3" -> "3.0.0", "3.5" -> "3.5.0")
293
- const segments = version.split('.').slice(0, 3)
294
- while (segments.length < 3) {
295
- segments.push('0')
296
- }
297
- return segments.join('.')
298
- }
299
-
300
- // Get the path where binaries for a version would be installed
301
- getBinaryPath(version: string): string {
302
- const fullVersion = this.resolveFullVersion(version)
303
- const { platform: p, arch: a } = this.getPlatformInfo()
304
- return paths.getBinaryPath({
305
- engine: 'couchdb',
306
- version: fullVersion,
307
- platform: p,
308
- arch: a,
309
- })
310
- }
311
-
312
- // Verify that CouchDB binaries are available
313
- async verifyBinary(binPath: string): Promise<boolean> {
314
- // CouchDB has a startup script rather than a direct binary
315
- // On Windows it's .cmd, on Unix it's just 'couchdb'
316
- const serverPath = join(binPath, 'bin', `couchdb${getCouchDBExtension()}`)
317
- return existsSync(serverPath)
318
- }
319
-
320
- // Check if a specific CouchDB version is installed
321
- async isBinaryInstalled(version: string): Promise<boolean> {
322
- const { platform, arch } = this.getPlatformInfo()
323
- return couchdbBinaryManager.isInstalled(version, platform, arch)
324
- }
325
-
326
- /**
327
- * Ensure CouchDB binaries are available for a specific version
328
- */
329
- async ensureBinaries(
330
- version: string,
331
- onProgress?: ProgressCallback,
332
- ): Promise<string> {
333
- const { platform, arch } = this.getPlatformInfo()
334
-
335
- const binPath = await couchdbBinaryManager.ensureInstalled(
336
- version,
337
- platform,
338
- arch,
339
- onProgress,
340
- )
341
-
342
- // Register binaries in config
343
- const toolPath = join(binPath, 'bin', `couchdb${getCouchDBExtension()}`)
344
- if (existsSync(toolPath)) {
345
- await configManager.setBinaryPath('couchdb', toolPath, 'bundled')
346
- }
347
-
348
- return binPath
349
- }
350
-
351
- /**
352
- * Initialize a new CouchDB data directory
353
- */
354
- async initDataDir(
355
- containerName: string,
356
- _version: string,
357
- options: Record<string, unknown> = {},
358
- ): Promise<string> {
359
- const dataDir = paths.getContainerDataPath(containerName, {
360
- engine: ENGINE,
361
- })
362
- const containerDir = paths.getContainerPath(containerName, {
363
- engine: ENGINE,
364
- })
365
- const port = (options.port as number) || engineDef.defaultPort
366
-
367
- // Create directories
368
- if (!existsSync(dataDir)) {
369
- await mkdir(dataDir, { recursive: true })
370
- logDebug(`Created CouchDB data directory: ${dataDir}`)
371
- }
372
-
373
- const logDir = join(containerDir, 'log')
374
- if (!existsSync(logDir)) {
375
- await mkdir(logDir, { recursive: true })
376
- }
377
-
378
- // Generate local.ini config
379
- const configPath = join(containerDir, 'local.ini')
380
- const configContent = generateCouchDBConfig({
381
- port,
382
- dataDir,
383
- logDir,
384
- })
385
- await writeFile(configPath, configContent)
386
- logDebug(`Generated CouchDB config: ${configPath}`)
387
-
388
- // Generate container-specific vm.args with unique node name
389
- const vmArgsPath = join(containerDir, 'vm.args')
390
- const vmArgsContent = generateVmArgs(port, containerDir)
391
- await writeFile(vmArgsPath, vmArgsContent)
392
- logDebug(`Generated CouchDB vm.args: ${vmArgsPath}`)
393
-
394
- return dataDir
395
- }
396
-
397
- // Get the path to couchdb server
398
- async getCouchDBServerPath(version: string): Promise<string> {
399
- const { platform, arch } = this.getPlatformInfo()
400
- const fullVersion = normalizeVersion(version)
401
- const binPath = paths.getBinaryPath({
402
- engine: 'couchdb',
403
- version: fullVersion,
404
- platform,
405
- arch,
406
- })
407
- const serverPath = join(binPath, 'bin', `couchdb${getCouchDBExtension()}`)
408
- if (existsSync(serverPath)) {
409
- return serverPath
410
- }
411
- throw new Error(
412
- `CouchDB ${version} is not installed. Run: spindb engines download couchdb ${version}`,
413
- )
414
- }
415
-
416
- // Get the path to couchdb binary
417
- async getCouchDBPath(version?: string): Promise<string> {
418
- const cached = await configManager.getBinaryPath('couchdb')
419
- if (cached && existsSync(cached)) {
420
- return cached
421
- }
422
-
423
- if (version) {
424
- const { platform, arch } = this.getPlatformInfo()
425
- const fullVersion = normalizeVersion(version)
426
- const binPath = paths.getBinaryPath({
427
- engine: 'couchdb',
428
- version: fullVersion,
429
- platform,
430
- arch,
431
- })
432
- const couchdbPath = join(
433
- binPath,
434
- 'bin',
435
- `couchdb${getCouchDBExtension()}`,
436
- )
437
- if (existsSync(couchdbPath)) {
438
- return couchdbPath
439
- }
440
- }
441
-
442
- throw new Error(
443
- 'couchdb not found. Run: spindb engines download couchdb <version>',
444
- )
445
- }
446
-
447
- /**
448
- * Start CouchDB server
449
- */
450
- async start(
451
- container: ContainerConfig,
452
- onProgress?: ProgressCallback,
453
- ): Promise<{ port: number; connectionString: string }> {
454
- const { name, port, version, binaryPath } = container
455
-
456
- // Check if already running
457
- const alreadyRunning = await processManager.isRunning(name, {
458
- engine: ENGINE,
459
- })
460
- if (alreadyRunning) {
461
- return {
462
- port,
463
- connectionString: this.getConnectionString(container),
464
- }
465
- }
466
-
467
- // Find couchdb binary
468
- let couchdbServer: string | null = null
469
-
470
- if (binaryPath && existsSync(binaryPath)) {
471
- const serverPath = join(
472
- binaryPath,
473
- 'bin',
474
- `couchdb${getCouchDBExtension()}`,
475
- )
476
- if (existsSync(serverPath)) {
477
- couchdbServer = serverPath
478
- logDebug(`Using stored binary path: ${couchdbServer}`)
479
- }
480
- }
481
-
482
- if (!couchdbServer) {
483
- try {
484
- couchdbServer = await this.getCouchDBServerPath(version)
485
- } catch (error) {
486
- const originalMessage =
487
- error instanceof Error ? error.message : String(error)
488
- throw new Error(
489
- `CouchDB ${version} is not installed. Run: spindb engines download couchdb ${version}\n` +
490
- ` Original error: ${originalMessage}`,
491
- )
492
- }
493
- }
494
-
495
- logDebug(`Using couchdb for version ${version}: ${couchdbServer}`)
496
-
497
- const containerDir = paths.getContainerPath(name, { engine: ENGINE })
498
- const configPath = join(containerDir, 'local.ini')
499
- const dataDir = paths.getContainerDataPath(name, { engine: ENGINE })
500
- const logDir = join(containerDir, 'log')
501
- const logFile = join(logDir, 'couchdb.log')
502
- const pidFile = join(containerDir, 'couchdb.pid')
503
-
504
- // Check port availability
505
- const portWaitTimeout = isWindows() ? 60000 : 0
506
- const portCheckStart = Date.now()
507
- const portCheckInterval = 1000
508
-
509
- while (!(await portManager.isPortAvailable(port))) {
510
- if (Date.now() - portCheckStart >= portWaitTimeout) {
511
- throw new Error(`Port ${port} is already in use.`)
512
- }
513
- logDebug(`Waiting for port ${port} to become available...`)
514
- await new Promise((resolve) => setTimeout(resolve, portCheckInterval))
515
- }
516
-
517
- // Regenerate config with current port
518
- const configContent = generateCouchDBConfig({
519
- port,
520
- dataDir,
521
- logDir,
522
- })
523
- await writeFile(configPath, configContent)
524
-
525
- // Regenerate vm.args with unique node name for this port
526
- const vmArgsPath = join(containerDir, 'vm.args')
527
- const vmArgsContent = generateVmArgs(port, containerDir)
528
- await writeFile(vmArgsPath, vmArgsContent)
529
-
530
- onProgress?.({ stage: 'starting', message: 'Starting CouchDB...' })
531
-
532
- logDebug(`Starting couchdb with config: ${configPath}`)
533
-
534
- // Get the binary directory for default config paths
535
- const binDir = dirname(dirname(couchdbServer))
536
- const defaultIni = join(binDir, 'etc', 'default.ini')
537
-
538
- // CouchDB uses COUCHDB_INI_FILES to load config files in order
539
- // COUCHDB_ARGS_FILE specifies custom vm.args with unique node name
540
- // On Windows, CouchDB may need additional paths set
541
- const env: Record<string, string | undefined> = {
542
- ...process.env,
543
- COUCHDB_INI_FILES: `${defaultIni} ${configPath}`,
544
- COUCHDB_ARGS_FILE: vmArgsPath,
545
- // Set CouchDB binary directory for Windows
546
- COUCHDB_BINDIR: join(binDir, 'bin'),
547
- COUCHDB_QUERY_SERVER_JAVASCRIPT: join(binDir, 'bin', 'couchjs'),
548
- }
549
-
550
- // On Windows, use sys.config to disable os_mon before it starts
551
- // The vm.args settings are too late - os_mon crashes during init
552
- // Erlang reads releases/sys.config at startup, so we modify that file
553
- if (isWindows()) {
554
- const sysConfigContent = generateSysConfig()
555
-
556
- // The CRITICAL location - Erlang release reads from releases/sys.config
557
- const releasesSysConfig = join(binDir, 'releases', 'sys.config')
558
- await writeFile(releasesSysConfig, sysConfigContent)
559
-
560
- // Copy vm.args to where Windows CouchDB expects it
561
- const expectedVmArgs = join(binDir, 'etc', 'vm.args')
562
- await writeFile(expectedVmArgs, vmArgsContent)
563
-
564
- // Also update releases/vm.args
565
- const releasesVmArgs = join(binDir, 'releases', 'vm.args')
566
- await writeFile(releasesVmArgs, vmArgsContent)
567
-
568
- // CRITICAL: Write config to binary's etc/local.ini
569
- // Windows CouchDB doesn't respect COUCHDB_INI_FILES env var and may not scan local.d/
570
- // Write directly to etc/local.ini which CouchDB definitely reads
571
- // Note: This means only one container can run per binary install (typical for local dev)
572
- const localIniPath = join(binDir, 'etc', 'local.ini')
573
- await writeFile(localIniPath, configContent)
574
- logDebug(`Wrote config to ${localIniPath}`)
575
-
576
- // Modify the os_mon.app file directly to disable features
577
- // This sets the default env values in the application spec itself
578
- const osMonAppPath = join(
579
- binDir,
580
- 'lib',
581
- 'os_mon-2.9.1',
582
- 'ebin',
583
- 'os_mon.app',
584
- )
585
- try {
586
- const osMonApp = await readFile(osMonAppPath, 'utf8')
587
- // Replace the default env settings to disable all features
588
- const modifiedApp = osMonApp
589
- .replace('{start_cpu_sup, true}', '{start_cpu_sup, false}')
590
- .replace('{start_disksup, true}', '{start_disksup, false}')
591
- .replace('{start_memsup, true}', '{start_memsup, false}')
592
- await writeFile(osMonAppPath, modifiedApp)
593
- logDebug('Modified os_mon.app to disable features')
594
- } catch (err) {
595
- logDebug(`Failed to modify os_mon.app: ${err}`)
596
- }
597
-
598
- // Add os_mon priv/bin to PATH so win32sysinfo.exe can be found
599
- const osMonPrivBin = join(binDir, 'lib', 'os_mon-2.9.1', 'priv', 'bin')
600
- const existingPath = env.PATH || process.env.PATH || ''
601
- env.PATH = `${osMonPrivBin};${existingPath}`
602
-
603
- logDebug(`Wrote sys.config to ${releasesSysConfig}`)
604
- logDebug(`Wrote vm.args to ${releasesVmArgs}`)
605
- logDebug(`Added to PATH: ${osMonPrivBin}`)
606
- }
607
-
608
- // Spawn CouchDB process
609
- if (isWindows()) {
610
- return new Promise((resolve, reject) => {
611
- // On Windows, run from the CouchDB installation directory
612
- // The Erlang VM expects to find files relative to its installation
613
- const spawnOpts: SpawnOptions = {
614
- cwd: binDir,
615
- stdio: ['ignore', 'pipe', 'pipe'],
616
- detached: true,
617
- windowsHide: true,
618
- env,
619
- }
620
-
621
- // On Windows, .cmd files must be executed via cmd.exe
622
- const proc = spawn('cmd.exe', ['/c', couchdbServer!], spawnOpts)
623
- let settled = false
624
- let stderrOutput = ''
625
- let stdoutOutput = ''
626
-
627
- proc.on('error', (err) => {
628
- if (settled) return
629
- settled = true
630
- reject(new Error(`Failed to spawn CouchDB server: ${err.message}`))
631
- })
632
-
633
- proc.on('exit', (code, signal) => {
634
- if (settled) return
635
- settled = true
636
- const reason = signal ? `signal ${signal}` : `code ${code}`
637
- reject(
638
- new Error(
639
- `CouchDB process exited unexpectedly (${reason}).\n` +
640
- `Stderr: ${stderrOutput || '(none)'}\n` +
641
- `Stdout: ${stdoutOutput || '(none)'}`,
642
- ),
643
- )
644
- })
645
-
646
- proc.stdout?.on('data', (data: Buffer) => {
647
- stdoutOutput += data.toString()
648
- })
649
- proc.stderr?.on('data', (data: Buffer) => {
650
- stderrOutput += data.toString()
651
- })
652
-
653
- proc.unref()
654
-
655
- setTimeout(async () => {
656
- if (settled) return
657
-
658
- if (!proc.pid) {
659
- settled = true
660
- reject(new Error('CouchDB server process failed to start (no PID)'))
661
- return
662
- }
663
-
664
- try {
665
- await writeFile(pidFile, String(proc.pid))
666
- } catch {
667
- // Non-fatal
668
- }
669
-
670
- const ready = await this.waitForReady(port)
671
- if (settled) return
672
-
673
- if (ready) {
674
- settled = true
675
- resolve({
676
- port,
677
- connectionString: this.getConnectionString(container),
678
- })
679
- } else {
680
- settled = true
681
-
682
- if (proc.pid && platformService.isProcessRunning(proc.pid)) {
683
- try {
684
- await platformService.terminateProcess(proc.pid, true)
685
- } catch {
686
- // Ignore cleanup errors
687
- }
688
- }
689
-
690
- reject(
691
- new Error(
692
- `CouchDB failed to start within timeout.\n` +
693
- `Binary: ${couchdbServer}\n` +
694
- `Config: ${configPath}\n` +
695
- `Log file: ${logFile}`,
696
- ),
697
- )
698
- }
699
- }, 500)
700
- })
701
- }
702
-
703
- // macOS/Linux
704
- const proc = spawn(couchdbServer, [], {
705
- cwd: containerDir,
706
- stdio: ['ignore', 'ignore', 'ignore'],
707
- detached: true,
708
- env,
709
- })
710
- proc.unref()
711
-
712
- if (!proc.pid) {
713
- throw new Error('CouchDB server process failed to start (no PID)')
714
- }
715
-
716
- try {
717
- await writeFile(pidFile, String(proc.pid))
718
- } catch {
719
- // Non-fatal
720
- }
721
-
722
- const ready = await this.waitForReady(port)
723
-
724
- if (ready) {
725
- return {
726
- port,
727
- connectionString: this.getConnectionString(container),
728
- }
729
- }
730
-
731
- throw new Error(
732
- `CouchDB failed to start within timeout.\n` +
733
- `Binary: ${couchdbServer}\n` +
734
- `Config: ${configPath}\n` +
735
- `Log file: ${logFile}`,
736
- )
737
- }
738
-
739
- // Wait for CouchDB to be ready
740
- private async waitForReady(
741
- port: number,
742
- timeoutMs = 30000,
743
- ): Promise<boolean> {
744
- const startTime = Date.now()
745
- const checkInterval = 500
746
-
747
- while (Date.now() - startTime < timeoutMs) {
748
- try {
749
- const response = await couchdbApiRequest(port, 'GET', '/')
750
- if (response.status === 200) {
751
- logDebug(`CouchDB ready on port ${port}`)
752
- return true
753
- }
754
- } catch {
755
- // Connection failed, wait and retry
756
- }
757
- await new Promise((resolve) => setTimeout(resolve, checkInterval))
758
- }
759
-
760
- logDebug(`CouchDB did not become ready within ${timeoutMs}ms`)
761
- return false
762
- }
763
-
764
- /**
765
- * Stop CouchDB server
766
- */
767
- async stop(container: ContainerConfig): Promise<void> {
768
- const { name, port } = container
769
- const containerDir = paths.getContainerPath(name, { engine: ENGINE })
770
- const pidFile = join(containerDir, 'couchdb.pid')
771
-
772
- logDebug(`Stopping CouchDB container "${name}" on port ${port}`)
773
-
774
- let pid: number | null = null
775
-
776
- if (existsSync(pidFile)) {
777
- try {
778
- const content = await readFile(pidFile, 'utf8')
779
- pid = parseInt(content.trim(), 10)
780
- } catch {
781
- // Ignore
782
- }
783
- }
784
-
785
- if (pid && platformService.isProcessRunning(pid)) {
786
- logDebug(`Killing CouchDB process ${pid}`)
787
- try {
788
- if (isWindows()) {
789
- await platformService.terminateProcess(pid, true)
790
- } else {
791
- await platformService.terminateProcess(pid, false)
792
- await new Promise((resolve) => setTimeout(resolve, 2000))
793
-
794
- if (platformService.isProcessRunning(pid)) {
795
- logWarning(`Graceful termination failed, force killing ${pid}`)
796
- await platformService.terminateProcess(pid, true)
797
- }
798
- }
799
- } catch (error) {
800
- logDebug(`Process termination error: ${error}`)
801
- }
802
- }
803
-
804
- if (isWindows()) {
805
- await new Promise((resolve) => setTimeout(resolve, 3000))
806
- }
807
-
808
- // Kill any processes still listening on the port
809
- const portPids = await platformService.findProcessByPort(port)
810
- for (const portPid of portPids) {
811
- if (platformService.isProcessRunning(portPid)) {
812
- logDebug(`Killing process ${portPid} still on port ${port}`)
813
- try {
814
- await platformService.terminateProcess(portPid, true)
815
- } catch {
816
- // Ignore
817
- }
818
- }
819
- }
820
-
821
- if (isWindows() && portPids.length > 0) {
822
- await new Promise((resolve) => setTimeout(resolve, 2000))
823
- }
824
-
825
- // Cleanup PID file
826
- if (existsSync(pidFile)) {
827
- try {
828
- await unlink(pidFile)
829
- } catch {
830
- // Ignore
831
- }
832
- }
833
-
834
- // Note: On Windows, we write to etc/local.ini which gets overwritten on each start
835
- // No cleanup needed as the file is shared and will be updated on next container start
836
-
837
- // Wait for port to be released on Windows
838
- if (isWindows()) {
839
- logDebug(`Waiting for port ${port} to be released...`)
840
- const portWaitStart = Date.now()
841
- const portWaitTimeout = 30000
842
- const checkInterval = 500
843
-
844
- while (Date.now() - portWaitStart < portWaitTimeout) {
845
- if (await portManager.isPortAvailable(port)) {
846
- logDebug('Port released successfully')
847
- break
848
- }
849
- await new Promise((resolve) => setTimeout(resolve, checkInterval))
850
- }
851
- }
852
-
853
- logDebug('CouchDB stopped')
854
- }
855
-
856
- // Get CouchDB server status
857
- async status(container: ContainerConfig): Promise<StatusResult> {
858
- const { name, port } = container
859
- const containerDir = paths.getContainerPath(name, { engine: ENGINE })
860
- const pidFile = join(containerDir, 'couchdb.pid')
861
-
862
- // Try health check via REST API
863
- try {
864
- const response = await couchdbApiRequest(port, 'GET', '/')
865
- if (response.status === 200) {
866
- return { running: true, message: 'CouchDB is running' }
867
- }
868
- } catch {
869
- // Not responding, check PID
870
- }
871
-
872
- // Check PID file
873
- if (existsSync(pidFile)) {
874
- try {
875
- const content = await readFile(pidFile, 'utf8')
876
- const pid = parseInt(content.trim(), 10)
877
- if (!isNaN(pid) && pid > 0 && platformService.isProcessRunning(pid)) {
878
- return {
879
- running: true,
880
- message: `CouchDB is running (PID: ${pid})`,
881
- }
882
- }
883
- } catch {
884
- // Ignore
885
- }
886
- }
887
-
888
- return { running: false, message: 'CouchDB is not running' }
889
- }
890
-
891
- // Detect backup format
892
- async detectBackupFormat(filePath: string): Promise<BackupFormat> {
893
- return detectBackupFormatImpl(filePath)
894
- }
895
-
896
- /**
897
- * Restore a backup
898
- * CouchDB can restore while running (uses REST API)
899
- */
900
- async restore(
901
- container: ContainerConfig,
902
- backupPath: string,
903
- options: { database?: string; flush?: boolean } = {},
904
- ): Promise<RestoreResult> {
905
- const { port } = container
906
-
907
- return restoreBackup(backupPath, {
908
- port,
909
- database: options.database,
910
- flush: options.flush,
911
- })
912
- }
913
-
914
- /**
915
- * Get connection string
916
- * Format: http://127.0.0.1:PORT
917
- */
918
- getConnectionString(container: ContainerConfig, database?: string): string {
919
- const { port } = container
920
- const base = `http://127.0.0.1:${port}`
921
- return database ? `${base}/${database}` : base
922
- }
923
-
924
- // Open Fauxton web UI
925
- async connect(container: ContainerConfig, _database?: string): Promise<void> {
926
- const { port } = container
927
- const url = `http://127.0.0.1:${port}/_utils`
928
-
929
- console.log(`CouchDB REST API available at: http://127.0.0.1:${port}`)
930
- console.log(`CouchDB Fauxton UI: ${url}`)
931
- console.log('')
932
- console.log('Example commands:')
933
- console.log(` curl http://127.0.0.1:${port}`)
934
- console.log(` curl http://127.0.0.1:${port}/_all_dbs`)
935
- }
936
-
937
- /**
938
- * Create a new database
939
- */
940
- async createDatabase(
941
- container: ContainerConfig,
942
- database: string,
943
- ): Promise<void> {
944
- const { port } = container
945
-
946
- const response = await couchdbApiRequest(
947
- port,
948
- 'PUT',
949
- `/${encodeURIComponent(database)}`,
950
- )
951
-
952
- if (response.status !== 201 && response.status !== 412) {
953
- // 412 means database already exists
954
- throw new Error(
955
- `Failed to create database: ${JSON.stringify(response.data)}`,
956
- )
957
- }
958
-
959
- logDebug(`Created CouchDB database: ${database}`)
960
- }
961
-
962
- /**
963
- * Drop a database
964
- */
965
- async dropDatabase(
966
- container: ContainerConfig,
967
- database: string,
968
- ): Promise<void> {
969
- const { port } = container
970
-
971
- const response = await couchdbApiRequest(
972
- port,
973
- 'DELETE',
974
- `/${encodeURIComponent(database)}`,
975
- )
976
-
977
- // Accept 200 (OK) or 202 (Accepted) for async deletes
978
- if (response.status !== 200 && response.status !== 202) {
979
- throw new Error(
980
- `Failed to delete database: ${JSON.stringify(response.data)}`,
981
- )
982
- }
983
-
984
- logDebug(
985
- `Deleted CouchDB database: ${database} (status: ${response.status})`,
986
- )
987
- }
988
-
989
- /**
990
- * Get the size of the CouchDB instance
991
- */
992
- async getDatabaseSize(container: ContainerConfig): Promise<number | null> {
993
- const { port } = container
994
-
995
- try {
996
- // CouchDB doesn't directly expose total size, but we can sum up database sizes
997
- const dbsResponse = await couchdbApiRequest(port, 'GET', '/_all_dbs')
998
- if (dbsResponse.status !== 200) {
999
- return null
1000
- }
1001
-
1002
- const dbs = dbsResponse.data as string[]
1003
- let totalSize = 0
1004
-
1005
- for (const db of dbs) {
1006
- if (db.startsWith('_')) continue // Skip system dbs
1007
- const infoResponse = await couchdbApiRequest(
1008
- port,
1009
- 'GET',
1010
- `/${encodeURIComponent(db)}`,
1011
- )
1012
- if (infoResponse.status === 200) {
1013
- const info = infoResponse.data as { sizes?: { file?: number } }
1014
- totalSize += info.sizes?.file || 0
1015
- }
1016
- }
1017
-
1018
- return totalSize > 0 ? totalSize : null
1019
- } catch {
1020
- return null
1021
- }
1022
- }
1023
-
1024
- /**
1025
- * Dump from a remote CouchDB connection
1026
- */
1027
- async dumpFromConnectionString(
1028
- connectionString: string,
1029
- outputPath: string,
1030
- ): Promise<DumpResult> {
1031
- const { baseUrl, headers, database } =
1032
- parseCouchDBConnectionString(connectionString)
1033
-
1034
- logDebug(`Connecting to remote CouchDB at ${baseUrl}`)
1035
-
1036
- // Check connectivity
1037
- const infoResponse = await remoteCouchDBRequest(
1038
- baseUrl,
1039
- 'GET',
1040
- '/',
1041
- headers,
1042
- )
1043
- if (infoResponse.status !== 200) {
1044
- throw new Error(
1045
- `Failed to connect to CouchDB at ${baseUrl}: ${JSON.stringify(infoResponse.data)}`,
1046
- )
1047
- }
1048
-
1049
- const serverInfo = infoResponse.data as { version?: string }
1050
- logDebug(`Connected to CouchDB ${serverInfo?.version || 'unknown'}`)
1051
-
1052
- // Get databases to backup
1053
- let databasesToBackup: string[]
1054
-
1055
- if (database) {
1056
- databasesToBackup = [database]
1057
- } else {
1058
- const dbsResponse = await remoteCouchDBRequest(
1059
- baseUrl,
1060
- 'GET',
1061
- '/_all_dbs',
1062
- headers,
1063
- )
1064
- if (dbsResponse.status !== 200) {
1065
- throw new Error(
1066
- `Failed to list databases: ${JSON.stringify(dbsResponse.data)}`,
1067
- )
1068
- }
1069
- const allDbs = dbsResponse.data as string[]
1070
- databasesToBackup = allDbs.filter((db) => !db.startsWith('_'))
1071
- }
1072
-
1073
- logDebug(`Backing up ${databasesToBackup.length} database(s)`)
1074
-
1075
- // Export documents from each database
1076
- const backup = {
1077
- version: serverInfo?.version || 'unknown',
1078
- created: new Date().toISOString(),
1079
- databases: [] as Array<{ name: string; docs: unknown[] }>,
1080
- }
1081
-
1082
- for (const dbName of databasesToBackup) {
1083
- logDebug(`Exporting database: ${dbName}`)
1084
-
1085
- const docsResponse = await remoteCouchDBRequest(
1086
- baseUrl,
1087
- 'GET',
1088
- `/${encodeURIComponent(dbName)}/_all_docs?include_docs=true`,
1089
- headers,
1090
- undefined,
1091
- 300000, // 5 minutes for large databases
1092
- )
1093
-
1094
- if (docsResponse.status !== 200) {
1095
- throw new Error(
1096
- `Failed to export database ${dbName}: ${JSON.stringify(docsResponse.data)}`,
1097
- )
1098
- }
1099
-
1100
- const docsData = docsResponse.data as {
1101
- rows?: Array<{ doc?: unknown }>
1102
- }
1103
- const docs =
1104
- docsData.rows
1105
- ?.map((row) => row.doc)
1106
- .filter((doc): doc is unknown => doc !== undefined) || []
1107
-
1108
- // Filter out design documents
1109
- const userDocs = docs.filter((doc) => {
1110
- const d = doc as { _id?: string }
1111
- return d._id && !d._id.startsWith('_design/')
1112
- })
1113
-
1114
- backup.databases.push({
1115
- name: dbName,
1116
- docs: userDocs,
1117
- })
1118
- }
1119
-
1120
- // Write backup to file
1121
- await mkdir(dirname(outputPath), { recursive: true })
1122
- await writeFile(outputPath, JSON.stringify(backup, null, 2))
1123
-
1124
- return {
1125
- filePath: outputPath,
1126
- warnings:
1127
- databasesToBackup.length === 0
1128
- ? ['Remote CouchDB instance has no user databases']
1129
- : undefined,
1130
- }
1131
- }
1132
-
1133
- // Create a backup
1134
- async backup(
1135
- container: ContainerConfig,
1136
- outputPath: string,
1137
- options: BackupOptions,
1138
- ): Promise<BackupResult> {
1139
- return createBackup(container, outputPath, options)
1140
- }
1141
-
1142
- // Run a command - CouchDB uses REST API, not command files
1143
- async runScript(
1144
- container: ContainerConfig,
1145
- options: { file?: string; sql?: string; database?: string },
1146
- ): Promise<void> {
1147
- const { port } = container
1148
-
1149
- if (options.file) {
1150
- throw new Error(
1151
- 'CouchDB does not support command files. Use the REST API directly.\n' +
1152
- `Example: curl http://127.0.0.1:${port}/_all_dbs`,
1153
- )
1154
- }
1155
-
1156
- if (options.sql) {
1157
- const command = options.sql.trim().toUpperCase()
1158
-
1159
- if (command === 'LIST DATABASES' || command === 'SHOW DATABASES') {
1160
- const response = await couchdbApiRequest(port, 'GET', '/_all_dbs')
1161
- console.log(JSON.stringify(response.data, null, 2))
1162
- return
1163
- }
1164
-
1165
- throw new Error(
1166
- 'CouchDB uses REST API for operations. Use curl or the CouchDB client libraries.\n' +
1167
- `API endpoint: http://127.0.0.1:${port}`,
1168
- )
1169
- }
1170
-
1171
- throw new Error('Either file or sql option must be provided')
1172
- }
1173
-
1174
- /**
1175
- * Execute a query via REST API
1176
- *
1177
- * Query format: METHOD /path [JSON body]
1178
- * Examples:
1179
- * GET /_all_dbs
1180
- * GET /mydb/_all_docs
1181
- * POST /mydb/_find {"selector": {"type": "user"}}
1182
- */
1183
- async executeQuery(
1184
- container: ContainerConfig,
1185
- query: string,
1186
- options?: QueryOptions,
1187
- ): Promise<QueryResult> {
1188
- const { port } = container
1189
-
1190
- // Parse the query string: METHOD /path [body]
1191
- // If options?.method is provided, query can be just the path
1192
- const trimmed = query.trim()
1193
- const spaceIdx = trimmed.indexOf(' ')
1194
-
1195
- let method: 'GET' | 'POST' | 'PUT' | 'DELETE'
1196
- let rest: string
1197
-
1198
- if (options?.method) {
1199
- // Method provided via options
1200
- method = options.method as 'GET' | 'POST' | 'PUT' | 'DELETE'
1201
- if (spaceIdx !== -1) {
1202
- // Check if first token looks like a method (GET, POST, etc.)
1203
- const firstToken = trimmed.substring(0, spaceIdx).toUpperCase()
1204
- if (['GET', 'POST', 'PUT', 'DELETE'].includes(firstToken)) {
1205
- // Query has method prefix, use rest after it
1206
- rest = trimmed.substring(spaceIdx + 1).trim()
1207
- } else {
1208
- // Query is path + body, use entire trimmed
1209
- rest = trimmed
1210
- }
1211
- } else {
1212
- // Query is just the path
1213
- rest = trimmed
1214
- }
1215
- } else {
1216
- // No method in options, must parse from query
1217
- if (spaceIdx === -1) {
1218
- throw new Error(
1219
- 'Invalid query format. Expected: METHOD /path [body]\n' +
1220
- 'Example: GET /_all_dbs',
1221
- )
1222
- }
1223
- method = trimmed.substring(0, spaceIdx).toUpperCase() as
1224
- | 'GET'
1225
- | 'POST'
1226
- | 'PUT'
1227
- | 'DELETE'
1228
- rest = trimmed.substring(spaceIdx + 1).trim()
1229
- }
1230
-
1231
- // Extract path and optional JSON body
1232
- let path: string
1233
- let body: Record<string, unknown> | undefined = options?.body
1234
-
1235
- const bodyStart = rest.indexOf('{')
1236
- if (bodyStart !== -1 && !body) {
1237
- path = rest.substring(0, bodyStart).trim()
1238
- try {
1239
- body = JSON.parse(rest.substring(bodyStart)) as Record<string, unknown>
1240
- } catch {
1241
- throw new Error('Invalid JSON body in query')
1242
- }
1243
- } else {
1244
- path = rest
1245
- }
1246
-
1247
- // Ensure path starts with /
1248
- if (!path.startsWith('/')) {
1249
- path = '/' + path
1250
- }
1251
-
1252
- const response = await couchdbApiRequest(port, method, path, body)
1253
-
1254
- if (response.status >= 400) {
1255
- throw new Error(
1256
- `CouchDB API error (${response.status}): ${JSON.stringify(response.data)}`,
1257
- )
1258
- }
1259
-
1260
- return parseRESTAPIResult(JSON.stringify(response.data))
1261
- }
1262
-
1263
- /**
1264
- * List all user databases, excluding system databases (_users, _replicator, _global_changes).
1265
- */
1266
- async listDatabases(container: ContainerConfig): Promise<string[]> {
1267
- const { port } = container
1268
-
1269
- const response = await couchdbApiRequest(port, 'GET', '/_all_dbs')
1270
-
1271
- if (response.status >= 400) {
1272
- throw new Error(
1273
- `CouchDB API error (${response.status}): ${JSON.stringify(response.data)}`,
1274
- )
1275
- }
1276
-
1277
- const allDatabases = response.data as string[]
1278
- const systemDatabases = ['_users', '_replicator', '_global_changes']
1279
- const databases = allDatabases.filter(
1280
- (db) => !systemDatabases.includes(db) && !db.startsWith('_'),
1281
- )
1282
-
1283
- return databases
1284
- }
1285
-
1286
- async createUser(
1287
- container: ContainerConfig,
1288
- options: CreateUserOptions,
1289
- ): Promise<UserCredentials> {
1290
- const { username, password, database } = options
1291
- assertValidUsername(username)
1292
- const { port } = container
1293
- const db = database || container.database
1294
- if (!db) {
1295
- throw new Error(
1296
- 'No database specified. Use --database or create a database first.',
1297
- )
1298
- }
1299
-
1300
- // Ensure _users system database exists (CouchDB 3.x doesn't auto-create it)
1301
- const usersDbResponse = await couchdbApiRequest(port, 'PUT', '/_users')
1302
- if (usersDbResponse.status !== 201 && usersDbResponse.status !== 412) {
1303
- throw new Error(
1304
- `Failed to ensure _users database exists: ${JSON.stringify(usersDbResponse.data)}`,
1305
- )
1306
- }
1307
-
1308
- // Create user document in _users database
1309
- const userDoc = {
1310
- _id: `org.couchdb.user:${username}`,
1311
- name: username,
1312
- type: 'user',
1313
- roles: [],
1314
- password,
1315
- }
1316
-
1317
- const createResponse = await couchdbApiRequest(
1318
- port,
1319
- 'PUT',
1320
- `/_users/org.couchdb.user:${encodeURIComponent(username)}`,
1321
- userDoc as unknown as Record<string, unknown>,
1322
- )
1323
-
1324
- if (createResponse.status !== 201 && createResponse.status !== 409) {
1325
- throw new Error(
1326
- `Failed to create user: ${JSON.stringify(createResponse.data)}`,
1327
- )
1328
- }
1329
-
1330
- if (createResponse.status === 409) {
1331
- // User exists — fetch current doc revision and update password
1332
- const getResponse = await couchdbApiRequest(
1333
- port,
1334
- 'GET',
1335
- `/_users/org.couchdb.user:${encodeURIComponent(username)}`,
1336
- )
1337
-
1338
- if (getResponse.status !== 200 || !getResponse.data) {
1339
- throw new Error(
1340
- `Failed to fetch existing user "${username}" (status ${getResponse.status}): ${JSON.stringify(getResponse.data)}`,
1341
- )
1342
- }
1343
-
1344
- const existingDoc = getResponse.data as Record<string, unknown>
1345
- const rev = existingDoc._rev as string
1346
- if (!rev) {
1347
- throw new Error(
1348
- `User "${username}" already exists but document has no _rev field: ${JSON.stringify(getResponse.data)}`,
1349
- )
1350
- }
1351
- const updateResponse = await couchdbApiRequest(
1352
- port,
1353
- 'PUT',
1354
- `/_users/org.couchdb.user:${encodeURIComponent(username)}`,
1355
- { ...existingDoc, password, _rev: rev },
1356
- )
1357
- if (updateResponse.status !== 201) {
1358
- throw new Error(
1359
- `Failed to update user: ${JSON.stringify(updateResponse.data)}`,
1360
- )
1361
- }
1362
- }
1363
-
1364
- // Ensure the target database exists before setting security
1365
- const dbCreateResponse = await couchdbApiRequest(
1366
- port,
1367
- 'PUT',
1368
- `/${encodeURIComponent(db)}`,
1369
- )
1370
- // 201 = created, 412 = already exists — both are fine
1371
- if (dbCreateResponse.status !== 201 && dbCreateResponse.status !== 412) {
1372
- throw new Error(
1373
- `Failed to ensure database "${db}" exists: ${JSON.stringify(dbCreateResponse.data)}`,
1374
- )
1375
- }
1376
-
1377
- // Grant access to the target database via _security document
1378
- const secResponse = await couchdbApiRequest(
1379
- port,
1380
- 'GET',
1381
- `/${encodeURIComponent(db)}/_security`,
1382
- )
1383
-
1384
- if (secResponse.status !== 200) {
1385
- throw new Error(
1386
- `Failed to read database security for "${db}": ${JSON.stringify(secResponse.data)}`,
1387
- )
1388
- }
1389
-
1390
- const security = (secResponse.data || {}) as Record<string, unknown>
1391
- const members = (security.members || {}) as Record<string, unknown>
1392
- const names = ((members.names || []) as string[]).slice()
1393
-
1394
- if (!names.includes(username)) {
1395
- names.push(username)
1396
- }
1397
-
1398
- const secPutResponse = await couchdbApiRequest(
1399
- port,
1400
- 'PUT',
1401
- `/${encodeURIComponent(db)}/_security`,
1402
- {
1403
- ...security,
1404
- members: { ...members, names },
1405
- },
1406
- )
1407
-
1408
- if (secPutResponse.status !== 200 && secPutResponse.status !== 201) {
1409
- throw new Error(
1410
- `Failed to update database security for "${db}": ${JSON.stringify(secPutResponse.data)}`,
1411
- )
1412
- }
1413
-
1414
- logDebug(`Created CouchDB user: ${username}`)
1415
-
1416
- const connectionString = `http://${encodeURIComponent(username)}:${encodeURIComponent(password)}@127.0.0.1:${port}/${encodeURIComponent(db)}`
1417
-
1418
- return {
1419
- username,
1420
- password,
1421
- connectionString,
1422
- engine: container.engine,
1423
- container: container.name,
1424
- database: db,
1425
- }
1426
- }
1427
- }
1428
-
1429
- export const couchdbEngine = new CouchDBEngine()