@joystick.js/db-canary 0.0.0-canary.2209

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 (354) hide show
  1. package/.build/getFilesToBuild.js +26 -0
  2. package/.build/getPlatformSafeFilePath.js +6 -0
  3. package/.build/getPlatformSafePath.js +6 -0
  4. package/.build/index.js +88 -0
  5. package/.build/isWindows.js +3 -0
  6. package/API_KEY +1 -0
  7. package/README.md +1821 -0
  8. package/data/data.mdb +0 -0
  9. package/data/lock.mdb +0 -0
  10. package/dist/client/database.js +1 -0
  11. package/dist/client/index.js +1 -0
  12. package/dist/server/cluster/index.js +1 -0
  13. package/dist/server/cluster/master.js +20 -0
  14. package/dist/server/cluster/worker.js +1 -0
  15. package/dist/server/index.js +1 -0
  16. package/dist/server/lib/api_key_manager.js +9 -0
  17. package/dist/server/lib/auth_manager.js +1 -0
  18. package/dist/server/lib/auto_index_manager.js +1 -0
  19. package/dist/server/lib/backup_manager.js +1 -0
  20. package/dist/server/lib/connection_manager.js +1 -0
  21. package/dist/server/lib/disk_utils.js +2 -0
  22. package/dist/server/lib/http_server.js +405 -0
  23. package/dist/server/lib/index_manager.js +1 -0
  24. package/dist/server/lib/load_settings.js +1 -0
  25. package/dist/server/lib/logger.js +1 -0
  26. package/dist/server/lib/op_types.js +1 -0
  27. package/dist/server/lib/operation_dispatcher.js +1 -0
  28. package/dist/server/lib/operations/admin.js +1 -0
  29. package/dist/server/lib/operations/bulk_write.js +1 -0
  30. package/dist/server/lib/operations/create_index.js +1 -0
  31. package/dist/server/lib/operations/delete_one.js +1 -0
  32. package/dist/server/lib/operations/drop_index.js +1 -0
  33. package/dist/server/lib/operations/find.js +1 -0
  34. package/dist/server/lib/operations/find_one.js +1 -0
  35. package/dist/server/lib/operations/get_indexes.js +1 -0
  36. package/dist/server/lib/operations/insert_one.js +1 -0
  37. package/dist/server/lib/operations/update_one.js +1 -0
  38. package/dist/server/lib/performance_monitor.js +1 -0
  39. package/dist/server/lib/query_engine.js +1 -0
  40. package/dist/server/lib/recovery_manager.js +1 -0
  41. package/dist/server/lib/replication_manager.js +1 -0
  42. package/dist/server/lib/safe_json_parse.js +1 -0
  43. package/dist/server/lib/send_response.js +1 -0
  44. package/dist/server/lib/tcp_protocol.js +1 -0
  45. package/dist/server/lib/write_forwarder.js +1 -0
  46. package/dist/server/lib/write_queue.js +1 -0
  47. package/increment_version.js +3 -0
  48. package/logs/.013e15b54597d05db4b4b53ecc37b10c92a72927-audit.json +20 -0
  49. package/logs/.02de550a67ea0f5961faa2dfd458a4d06f59ebd1-audit.json +20 -0
  50. package/logs/.03494ba24eb3c72214b4068a77d54b8993bee651-audit.json +20 -0
  51. package/logs/.06309ec60b339be1259a7993dd09c732f8907fbc-audit.json +20 -0
  52. package/logs/.0663a04dcfa17285661e5e1b8cfa51f41523b210-audit.json +20 -0
  53. package/logs/.0f06e6c4c9b824622729e13927587479e5060391-audit.json +20 -0
  54. package/logs/.16ccf58682ecb22b3e3ec63f0da1b7fe9be56528-audit.json +20 -0
  55. package/logs/.1fa1a5d02f496474b1ab473524c65c984146a9ad-audit.json +20 -0
  56. package/logs/.2223c0ae3bea6f0d62c62b1d319cc8634856abb7-audit.json +20 -0
  57. package/logs/.23dc79ffda3e083665e6f5993f59397adcbf4a46-audit.json +20 -0
  58. package/logs/.28104f49b03906b189eefd1cd462cb46c3c0af22-audit.json +20 -0
  59. package/logs/.29cdbf13808abe6a0ce70ee2f2efdd680ce3fd8e-audit.json +20 -0
  60. package/logs/.2a9889afd071f77f41f5170d08703a0afca866b7-audit.json +20 -0
  61. package/logs/.2acec3d1940a2bbed487528b703ee5948959a599-audit.json +20 -0
  62. package/logs/.2fb60ff326338c02bfedbcd0e936444e4a216750-audit.json +20 -0
  63. package/logs/.318fc7a19530d76a345f030f7cad00dda15300e7-audit.json +20 -0
  64. package/logs/.3cf27043e19085f908cedc7701e6d013463208ee-audit.json +25 -0
  65. package/logs/.3d90d785415817fc443402843b7c95f8371adc9b-audit.json +20 -0
  66. package/logs/.4074bca620375f72966fc52dfd439577727671e5-audit.json +20 -0
  67. package/logs/.40eecf018417ea80a70ea8ec7a3cc9406bc6334b-audit.json +20 -0
  68. package/logs/.50e974f1ef7c365fca6a1251b2e2c2252914cb5e-audit.json +20 -0
  69. package/logs/.52cb7d9e4223cf26ba36006ac26b949a97c7923c-audit.json +20 -0
  70. package/logs/.54befcdb84c15aad980705a31bcc9f555c3577ab-audit.json +20 -0
  71. package/logs/.57dfb70e22eddb84db2e3c0ceeefac5c0b9baffa-audit.json +20 -0
  72. package/logs/.5f0b24705a1eaad4eca4968f2d86f91b3f9be683-audit.json +20 -0
  73. package/logs/.61ba98fdda7db58576b382fee07904e5db1169d6-audit.json +20 -0
  74. package/logs/.6235017727ef6b199d569a99d6aa8c8e80a1b475-audit.json +20 -0
  75. package/logs/.63db16193699219489d218a1ddea5dde3750cae4-audit.json +20 -0
  76. package/logs/.64fb67dfe14149c9eef728d79bf30a54da809c60-audit.json +20 -0
  77. package/logs/.669137453368987c1f311b5345342527afb54e50-audit.json +20 -0
  78. package/logs/.7a71f8c89ea28ae266d356aeff6306e876a30fbb-audit.json +20 -0
  79. package/logs/.7afbaa90fe9dc3a7d682676f9bb79f9a1b1fd9a6-audit.json +20 -0
  80. package/logs/.7ca29e322cd05327035de850099e7610864f2347-audit.json +20 -0
  81. package/logs/.83335ab3347e449dae03455a110aaf7f120d4802-audit.json +20 -0
  82. package/logs/.8c2487b5fd445d2c8e5c483c80b9fa99bbf1ca58-audit.json +20 -0
  83. package/logs/.8c8b9dc386922c9f3b4c13251af7052aac1d24c0-audit.json +20 -0
  84. package/logs/.8d6155d94640c4863301ae0fee5e4e7372a21446-audit.json +20 -0
  85. package/logs/.944a3119a243deea7c8270d5d9e582bb1d0eaa10-audit.json +20 -0
  86. package/logs/.9816a845c30fb2909f3b26a23eeb3538ebcad5db-audit.json +20 -0
  87. package/logs/.9dc08784e38b865488177c26d4af5934555e0323-audit.json +20 -0
  88. package/logs/.9dd27d2e0e454ac0a37600206d1cac5493b0d7ee-audit.json +20 -0
  89. package/logs/.a3d486feeac7654c59b547de96600e8849a06d4f-audit.json +20 -0
  90. package/logs/.a5b811f4def22250f86cc18870d7c4573625df22-audit.json +20 -0
  91. package/logs/.a61648eb5f830e0b6f508ac35e4f8f629d2ad4c7-audit.json +20 -0
  92. package/logs/.a89016d507045771b4b5a65656944a9c0f1e528b-audit.json +20 -0
  93. package/logs/.a99bee160a1c590be959af46bacc02724803f691-audit.json +20 -0
  94. package/logs/.ada7906d6243fd7da802f03d86c4ae5dd9df6236-audit.json +20 -0
  95. package/logs/.b518339ee942143b6af983af167f5bbb6983b4de-audit.json +20 -0
  96. package/logs/.b51b124b166d53c9519017856ea610d61d65fabe-audit.json +20 -0
  97. package/logs/.b7a6aee19f58e55633d5e4a3709041c47dfff975-audit.json +20 -0
  98. package/logs/.bd7a8a6ba9c55d557a4867ab53f02e3ec2e1553d-audit.json +20 -0
  99. package/logs/.c1435dafe453b169d6392b25065f3cf4ab6fbb21-audit.json +20 -0
  100. package/logs/.c17e1ce043109f77dc2f0e2aa290a9d1ed842c03-audit.json +20 -0
  101. package/logs/.ca62637ce9540e5a38a2fbedb2115febb6ad308a-audit.json +15 -0
  102. package/logs/.ccee67b9c176967f8977071409a41f5cb5cd6ad4-audit.json +20 -0
  103. package/logs/.db24043417ea79a6f14cd947476399e53930b48d-audit.json +20 -0
  104. package/logs/.e0f12acccb57829f5f33712bb2e2607ecd808147-audit.json +20 -0
  105. package/logs/.e9b6cc33d0bbd2e644c4e2bf44d177f850016557-audit.json +20 -0
  106. package/logs/.f15291d434808e3bdca7963ccd2e73893be027e6-audit.json +20 -0
  107. package/logs/.f4bdf9e21ef84f8a3fae3ffb32bbc39275991351-audit.json +15 -0
  108. package/logs/.fbac3aefac1e81b4230df5aa50667cb90d51024f-audit.json +20 -0
  109. package/logs/.fcfd495c0a9169db243f4a4f21878ee02b76413c-audit.json +20 -0
  110. package/logs/admin-2025-09-12.log +580 -0
  111. package/logs/admin-2025-09-15.log +283 -0
  112. package/logs/admin-error-2025-09-12.log +22 -0
  113. package/logs/admin-error-2025-09-15.log +10 -0
  114. package/logs/api_key_manager-2025-09-12.log +658 -0
  115. package/logs/api_key_manager-2025-09-15.log +295 -0
  116. package/logs/api_key_manager-error-2025-09-12.log +0 -0
  117. package/logs/api_key_manager-error-2025-09-15.log +0 -0
  118. package/logs/auth_manager-2025-09-12.log +4432 -0
  119. package/logs/auth_manager-2025-09-15.log +2000 -0
  120. package/logs/auth_manager-error-2025-09-12.log +11 -0
  121. package/logs/auth_manager-error-2025-09-15.log +5 -0
  122. package/logs/auto_index_manager-2025-09-12.log +84 -0
  123. package/logs/auto_index_manager-2025-09-15.log +45 -0
  124. package/logs/auto_index_manager-error-2025-09-12.log +6 -0
  125. package/logs/auto_index_manager-error-2025-09-15.log +0 -0
  126. package/logs/backup_manager-2025-09-12.log +198 -0
  127. package/logs/backup_manager-2025-09-15.log +90 -0
  128. package/logs/backup_manager-error-2025-09-12.log +198 -0
  129. package/logs/backup_manager-error-2025-09-15.log +90 -0
  130. package/logs/bulk_write-2025-09-12.log +66 -0
  131. package/logs/bulk_write-2025-09-15.log +38 -0
  132. package/logs/bulk_write-error-2025-09-12.log +0 -0
  133. package/logs/bulk_write-error-2025-09-15.log +0 -0
  134. package/logs/connection_manager-2025-09-12.log +2412 -0
  135. package/logs/connection_manager-2025-09-15.log +1132 -0
  136. package/logs/connection_manager-error-2025-09-12.log +0 -0
  137. package/logs/connection_manager-error-2025-09-15.log +0 -0
  138. package/logs/create_index-2025-09-12.log +302 -0
  139. package/logs/create_index-2025-09-15.log +158 -0
  140. package/logs/create_index-error-2025-09-12.log +30 -0
  141. package/logs/create_index-error-2025-09-15.log +13 -0
  142. package/logs/delete_one-2025-09-12.log +73 -0
  143. package/logs/delete_one-2025-09-15.log +43 -0
  144. package/logs/delete_one-error-2025-09-12.log +0 -0
  145. package/logs/delete_one-error-2025-09-15.log +0 -0
  146. package/logs/disk_utils-2025-09-12.log +4954 -0
  147. package/logs/disk_utils-2025-09-15.log +2446 -0
  148. package/logs/disk_utils-error-2025-09-12.log +0 -0
  149. package/logs/disk_utils-error-2025-09-15.log +0 -0
  150. package/logs/drop_index-2025-09-12.log +41 -0
  151. package/logs/drop_index-2025-09-15.log +23 -0
  152. package/logs/drop_index-error-2025-09-12.log +11 -0
  153. package/logs/drop_index-error-2025-09-15.log +5 -0
  154. package/logs/find-2025-09-12.log +1050 -0
  155. package/logs/find-2025-09-15.log +592 -0
  156. package/logs/find-error-2025-09-12.log +1 -0
  157. package/logs/find-error-2025-09-15.log +0 -0
  158. package/logs/find_one-2025-09-12.log +425 -0
  159. package/logs/find_one-2025-09-15.log +264 -0
  160. package/logs/find_one-error-2025-09-12.log +5 -0
  161. package/logs/find_one-error-2025-09-15.log +0 -0
  162. package/logs/get_indexes-2025-09-12.log +84 -0
  163. package/logs/get_indexes-2025-09-15.log +56 -0
  164. package/logs/get_indexes-error-2025-09-12.log +6 -0
  165. package/logs/get_indexes-error-2025-09-15.log +0 -0
  166. package/logs/http_server-2025-09-12.log +2772 -0
  167. package/logs/http_server-2025-09-15.log +1276 -0
  168. package/logs/http_server-error-2025-09-12.log +212 -0
  169. package/logs/http_server-error-2025-09-15.log +44 -0
  170. package/logs/index_manager-2025-09-12.log +5031 -0
  171. package/logs/index_manager-2025-09-15.log +2909 -0
  172. package/logs/index_manager-error-2025-09-12.log +80 -0
  173. package/logs/index_manager-error-2025-09-15.log +38 -0
  174. package/logs/insert_one-2025-09-12.log +2181 -0
  175. package/logs/insert_one-2025-09-15.log +1293 -0
  176. package/logs/insert_one-error-2025-09-12.log +0 -0
  177. package/logs/insert_one-error-2025-09-15.log +0 -0
  178. package/logs/master-2025-09-12.log +1882 -0
  179. package/logs/master-2025-09-15.log +910 -0
  180. package/logs/master-error-2025-09-12.log +80 -0
  181. package/logs/master-error-2025-09-15.log +0 -0
  182. package/logs/operation_dispatcher-2025-09-12.log +751 -0
  183. package/logs/operation_dispatcher-2025-09-15.log +359 -0
  184. package/logs/operation_dispatcher-error-2025-09-12.log +33 -0
  185. package/logs/operation_dispatcher-error-2025-09-15.log +11 -0
  186. package/logs/performance_monitor-2025-09-12.log +14889 -0
  187. package/logs/performance_monitor-2025-09-15.log +6803 -0
  188. package/logs/performance_monitor-error-2025-09-12.log +0 -0
  189. package/logs/performance_monitor-error-2025-09-15.log +0 -0
  190. package/logs/query_engine-2025-09-12.log +5310 -0
  191. package/logs/query_engine-2025-09-15.log +2639 -0
  192. package/logs/query_engine-error-2025-09-12.log +0 -0
  193. package/logs/query_engine-error-2025-09-15.log +0 -0
  194. package/logs/recovery_manager-2025-09-12.log +462 -0
  195. package/logs/recovery_manager-2025-09-15.log +210 -0
  196. package/logs/recovery_manager-error-2025-09-12.log +22 -0
  197. package/logs/recovery_manager-error-2025-09-15.log +10 -0
  198. package/logs/replication-2025-09-12.log +1923 -0
  199. package/logs/replication-2025-09-15.log +917 -0
  200. package/logs/replication-error-2025-09-12.log +33 -0
  201. package/logs/replication-error-2025-09-15.log +15 -0
  202. package/logs/server-2025-09-12.log +2601 -0
  203. package/logs/server-2025-09-15.log +1191 -0
  204. package/logs/server-error-2025-09-12.log +0 -0
  205. package/logs/server-error-2025-09-15.log +0 -0
  206. package/logs/tcp_protocol-2025-09-12.log +22 -0
  207. package/logs/tcp_protocol-2025-09-15.log +10 -0
  208. package/logs/tcp_protocol-error-2025-09-12.log +22 -0
  209. package/logs/tcp_protocol-error-2025-09-15.log +10 -0
  210. package/logs/test-2025-09-12.log +0 -0
  211. package/logs/test-2025-09-15.log +0 -0
  212. package/logs/test-error-2025-09-12.log +0 -0
  213. package/logs/test-error-2025-09-15.log +0 -0
  214. package/logs/update_one-2025-09-12.log +173 -0
  215. package/logs/update_one-2025-09-15.log +118 -0
  216. package/logs/update_one-error-2025-09-12.log +0 -0
  217. package/logs/update_one-error-2025-09-15.log +0 -0
  218. package/logs/worker-2025-09-12.log +1457 -0
  219. package/logs/worker-2025-09-15.log +695 -0
  220. package/logs/worker-error-2025-09-12.log +0 -0
  221. package/logs/worker-error-2025-09-15.log +0 -0
  222. package/logs/write_forwarder-2025-09-12.log +1956 -0
  223. package/logs/write_forwarder-2025-09-15.log +932 -0
  224. package/logs/write_forwarder-error-2025-09-12.log +66 -0
  225. package/logs/write_forwarder-error-2025-09-15.log +30 -0
  226. package/logs/write_queue-2025-09-12.log +612 -0
  227. package/logs/write_queue-2025-09-15.log +301 -0
  228. package/logs/write_queue-error-2025-09-12.log +184 -0
  229. package/logs/write_queue-error-2025-09-15.log +83 -0
  230. package/package.json +48 -0
  231. package/prompts/01-core-infrastructure.md +56 -0
  232. package/prompts/02-secondary-indexing.md +65 -0
  233. package/prompts/03-write-serialization.md +63 -0
  234. package/prompts/04-enhanced-authentication.md +75 -0
  235. package/prompts/05-comprehensive-admin-operations.md +75 -0
  236. package/prompts/06-backup-and-restore-system.md +106 -0
  237. package/prompts/07-production-safety-features.md +107 -0
  238. package/prompts/08-tcp-client-library.md +121 -0
  239. package/prompts/09-api-method-chaining.md +134 -0
  240. package/prompts/10-automatic-index-creation.md +223 -0
  241. package/prompts/11-operation-naming-consistency.md +268 -0
  242. package/prompts/12-tcp-replication-system.md +333 -0
  243. package/prompts/13-master-read-write-operations.md +57 -0
  244. package/prompts/14-index-upsert-operations.md +68 -0
  245. package/prompts/15-client-api-return-types.md +81 -0
  246. package/prompts/16-server-setup-ui.md +97 -0
  247. package/prompts/17-emergency-password-change.md +108 -0
  248. package/prompts/18-joystick-framework-integration.md +116 -0
  249. package/prompts/19-api-key-authentication-system.md +137 -0
  250. package/prompts/20-configurable-server-port.md +105 -0
  251. package/prompts/21-multi-database-support.md +161 -0
  252. package/prompts/FULL_TEXT_SEARCH.md +293 -0
  253. package/prompts/PROMPTS.md +158 -0
  254. package/prompts/README.md +221 -0
  255. package/prompts/TYPESCRIPT_GENERATION.md +179 -0
  256. package/src/client/database.js +166 -0
  257. package/src/client/index.js +752 -0
  258. package/src/server/cluster/index.js +53 -0
  259. package/src/server/cluster/master.js +774 -0
  260. package/src/server/cluster/worker.js +537 -0
  261. package/src/server/index.js +540 -0
  262. package/src/server/lib/api_key_manager.js +473 -0
  263. package/src/server/lib/auth_manager.js +375 -0
  264. package/src/server/lib/auto_index_manager.js +681 -0
  265. package/src/server/lib/backup_manager.js +650 -0
  266. package/src/server/lib/connection_manager.js +218 -0
  267. package/src/server/lib/disk_utils.js +118 -0
  268. package/src/server/lib/http_server.js +1165 -0
  269. package/src/server/lib/index_manager.js +756 -0
  270. package/src/server/lib/load_settings.js +143 -0
  271. package/src/server/lib/logger.js +135 -0
  272. package/src/server/lib/op_types.js +29 -0
  273. package/src/server/lib/operation_dispatcher.js +268 -0
  274. package/src/server/lib/operations/admin.js +808 -0
  275. package/src/server/lib/operations/bulk_write.js +367 -0
  276. package/src/server/lib/operations/create_index.js +68 -0
  277. package/src/server/lib/operations/delete_one.js +114 -0
  278. package/src/server/lib/operations/drop_index.js +58 -0
  279. package/src/server/lib/operations/find.js +340 -0
  280. package/src/server/lib/operations/find_one.js +319 -0
  281. package/src/server/lib/operations/get_indexes.js +52 -0
  282. package/src/server/lib/operations/insert_one.js +113 -0
  283. package/src/server/lib/operations/update_one.js +225 -0
  284. package/src/server/lib/performance_monitor.js +313 -0
  285. package/src/server/lib/query_engine.js +243 -0
  286. package/src/server/lib/recovery_manager.js +388 -0
  287. package/src/server/lib/replication_manager.js +727 -0
  288. package/src/server/lib/safe_json_parse.js +21 -0
  289. package/src/server/lib/send_response.js +47 -0
  290. package/src/server/lib/tcp_protocol.js +130 -0
  291. package/src/server/lib/write_forwarder.js +636 -0
  292. package/src/server/lib/write_queue.js +335 -0
  293. package/test_data/data.mdb +0 -0
  294. package/test_data/lock.mdb +0 -0
  295. package/tests/client/index.test.js +1232 -0
  296. package/tests/server/cluster/cluster.test.js +248 -0
  297. package/tests/server/cluster/master_read_write_operations.test.js +577 -0
  298. package/tests/server/index.test.js +651 -0
  299. package/tests/server/integration/authentication_integration.test.js +294 -0
  300. package/tests/server/integration/auto_indexing_integration.test.js +268 -0
  301. package/tests/server/integration/backup_integration.test.js +513 -0
  302. package/tests/server/integration/indexing_integration.test.js +126 -0
  303. package/tests/server/integration/production_safety_integration.test.js +358 -0
  304. package/tests/server/integration/replication_integration.test.js +227 -0
  305. package/tests/server/integration/write_serialization_integration.test.js +246 -0
  306. package/tests/server/lib/api_key_manager.test.js +516 -0
  307. package/tests/server/lib/auth_manager.test.js +317 -0
  308. package/tests/server/lib/auto_index_manager.test.js +275 -0
  309. package/tests/server/lib/backup_manager.test.js +238 -0
  310. package/tests/server/lib/connection_manager.test.js +221 -0
  311. package/tests/server/lib/disk_utils.test.js +63 -0
  312. package/tests/server/lib/http_server.test.js +389 -0
  313. package/tests/server/lib/index_manager.test.js +301 -0
  314. package/tests/server/lib/load_settings.test.js +107 -0
  315. package/tests/server/lib/load_settings_port_config.test.js +243 -0
  316. package/tests/server/lib/logger.test.js +282 -0
  317. package/tests/server/lib/operations/admin.test.js +638 -0
  318. package/tests/server/lib/operations/bulk_write.test.js +128 -0
  319. package/tests/server/lib/operations/create_index.test.js +138 -0
  320. package/tests/server/lib/operations/delete_one.test.js +52 -0
  321. package/tests/server/lib/operations/drop_index.test.js +72 -0
  322. package/tests/server/lib/operations/find.test.js +93 -0
  323. package/tests/server/lib/operations/find_one.test.js +91 -0
  324. package/tests/server/lib/operations/get_indexes.test.js +87 -0
  325. package/tests/server/lib/operations/insert_one.test.js +42 -0
  326. package/tests/server/lib/operations/update_one.test.js +89 -0
  327. package/tests/server/lib/performance_monitor.test.js +185 -0
  328. package/tests/server/lib/query_engine.test.js +46 -0
  329. package/tests/server/lib/recovery_manager.test.js +414 -0
  330. package/tests/server/lib/replication_manager.test.js +202 -0
  331. package/tests/server/lib/safe_json_parse.test.js +45 -0
  332. package/tests/server/lib/send_response.test.js +155 -0
  333. package/tests/server/lib/tcp_protocol.test.js +169 -0
  334. package/tests/server/lib/write_forwarder.test.js +258 -0
  335. package/tests/server/lib/write_queue.test.js +255 -0
  336. package/tsconfig.json +30 -0
  337. package/types/client/index.d.ts +447 -0
  338. package/types/server/cluster/index.d.ts +28 -0
  339. package/types/server/cluster/master.d.ts +115 -0
  340. package/types/server/cluster/worker.d.ts +1 -0
  341. package/types/server/lib/auth_manager.d.ts +13 -0
  342. package/types/server/lib/backup_manager.d.ts +43 -0
  343. package/types/server/lib/connection_manager.d.ts +15 -0
  344. package/types/server/lib/disk_utils.d.ts +3 -0
  345. package/types/server/lib/index_manager.d.ts +24 -0
  346. package/types/server/lib/load_settings.d.ts +4 -0
  347. package/types/server/lib/logger.d.ts +44 -0
  348. package/types/server/lib/op_types.d.ts +6 -0
  349. package/types/server/lib/performance_monitor.d.ts +68 -0
  350. package/types/server/lib/query_engine.d.ts +10 -0
  351. package/types/server/lib/safe_json_parse.d.ts +7 -0
  352. package/types/server/lib/send_response.d.ts +3 -0
  353. package/types/server/lib/tcp_protocol.d.ts +12 -0
  354. package/types/server/lib/write_queue.d.ts +2 -0
@@ -0,0 +1,516 @@
1
+ import test from 'ava';
2
+ import { existsSync, unlinkSync, statSync } from 'fs';
3
+ import {
4
+ load_or_generate_api_key,
5
+ validate_api_key,
6
+ create_user,
7
+ get_all_users,
8
+ get_user,
9
+ update_user,
10
+ delete_user,
11
+ verify_user_password,
12
+ check_admin_user_exists,
13
+ initialize_api_key_manager,
14
+ reset_api_key_state
15
+ } from '../../../src/server/lib/api_key_manager.js';
16
+ import { initialize_database, cleanup_database } from '../../../src/server/lib/query_engine.js';
17
+
18
+ const API_KEY_FILE_PATH = './API_KEY';
19
+
20
+ test.beforeEach(async (t) => {
21
+ // Clean up any existing database first
22
+ try {
23
+ await cleanup_database();
24
+ } catch (error) {
25
+ // Ignore cleanup errors
26
+ }
27
+
28
+ // Clean up any existing API key file and reset state
29
+ reset_api_key_state();
30
+
31
+ // Initialize database for user storage tests with unique path per test
32
+ const test_db_path = `./test_data_api_key_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
33
+ initialize_database(test_db_path);
34
+
35
+ // Store the test db path for cleanup
36
+ t.context.test_db_path = test_db_path;
37
+ });
38
+
39
+ test.afterEach(async (t) => {
40
+ // Clean up database and API key state
41
+ try {
42
+ await cleanup_database(true); // Remove test database directory
43
+ } catch (error) {
44
+ // Ignore cleanup errors
45
+ }
46
+
47
+ reset_api_key_state();
48
+ });
49
+
50
+ test('load_or_generate_api_key generates new API key when file does not exist', (t) => {
51
+ const api_key = load_or_generate_api_key();
52
+
53
+ t.is(typeof api_key, 'string');
54
+ t.is(api_key.length, 32);
55
+ t.true(/^[A-Za-z0-9]{32}$/.test(api_key));
56
+ t.true(existsSync(API_KEY_FILE_PATH));
57
+ });
58
+
59
+ test('load_or_generate_api_key loads existing API key from file', (t) => {
60
+ const first_key = load_or_generate_api_key();
61
+ const second_key = load_or_generate_api_key();
62
+
63
+ t.is(first_key, second_key);
64
+ });
65
+
66
+ test('load_or_generate_api_key generates unique keys', (t) => {
67
+ const first_key = load_or_generate_api_key();
68
+ reset_api_key_state();
69
+
70
+ const second_key = load_or_generate_api_key();
71
+
72
+ t.not(first_key, second_key);
73
+ });
74
+
75
+ test('validate_api_key returns true for valid API key', (t) => {
76
+ const api_key = load_or_generate_api_key();
77
+ const is_valid = validate_api_key(api_key);
78
+
79
+ t.true(is_valid);
80
+ });
81
+
82
+ test('validate_api_key returns false for invalid API key', (t) => {
83
+ load_or_generate_api_key();
84
+ const is_valid = validate_api_key('invalid_key');
85
+
86
+ t.false(is_valid);
87
+ });
88
+
89
+ test('validate_api_key returns false for null/undefined API key', (t) => {
90
+ load_or_generate_api_key();
91
+
92
+ t.false(validate_api_key(null));
93
+ t.false(validate_api_key(undefined));
94
+ t.false(validate_api_key(''));
95
+ });
96
+
97
+ test('create_user creates user with valid data', async (t) => {
98
+ const user_data = {
99
+ username: 'testuser',
100
+ password: 'testpassword123',
101
+ role: 'read_write'
102
+ };
103
+
104
+ const created_user = await create_user(user_data);
105
+
106
+ t.is(created_user.username, 'testuser');
107
+ t.is(created_user.role, 'read_write');
108
+ t.true(typeof created_user.created_at === 'string');
109
+ t.is(created_user.password_hash, undefined); // Should not return password hash
110
+ });
111
+
112
+ test('create_user validates username format', async (t) => {
113
+ const invalid_usernames = ['ab', 'user@name', 'user name', '', null, undefined];
114
+
115
+ for (const username of invalid_usernames) {
116
+ const error = await t.throwsAsync(async () => {
117
+ await create_user({
118
+ username,
119
+ password: 'testpassword123',
120
+ role: 'read_write'
121
+ });
122
+ });
123
+
124
+ t.true(error.message.includes('Username must be alphanumeric and 3-50 characters long'));
125
+ }
126
+ });
127
+
128
+ test('create_user validates password requirements', async (t) => {
129
+ const invalid_passwords = ['short', '', null, undefined];
130
+
131
+ for (const password of invalid_passwords) {
132
+ const error = await t.throwsAsync(async () => {
133
+ await create_user({
134
+ username: 'testuser',
135
+ password,
136
+ role: 'read_write'
137
+ });
138
+ });
139
+
140
+ t.true(error.message.includes('Password'));
141
+ }
142
+ });
143
+
144
+ test('create_user validates role values', async (t) => {
145
+ const invalid_roles = ['admin', 'superuser', '', null, undefined];
146
+
147
+ for (const role of invalid_roles) {
148
+ const error = await t.throwsAsync(async () => {
149
+ await create_user({
150
+ username: 'testuser',
151
+ password: 'testpassword123',
152
+ role
153
+ });
154
+ });
155
+
156
+ t.true(error.message.includes('Role must be one of: read, write, read_write'));
157
+ }
158
+ });
159
+
160
+ test('create_user prevents duplicate usernames', async (t) => {
161
+ const user_data = {
162
+ username: 'testuser',
163
+ password: 'testpassword123',
164
+ role: 'read_write'
165
+ };
166
+
167
+ await create_user(user_data);
168
+
169
+ const error = await t.throwsAsync(async () => {
170
+ await create_user(user_data);
171
+ });
172
+
173
+ t.is(error.message, 'Username already exists');
174
+ });
175
+
176
+ test('get_all_users returns empty array when no users exist', (t) => {
177
+ const users = get_all_users();
178
+
179
+ t.true(Array.isArray(users));
180
+ t.is(users.length, 0);
181
+ });
182
+
183
+ test('get_all_users returns all users without password hashes', async (t) => {
184
+ await create_user({
185
+ username: 'user1',
186
+ password: 'password123',
187
+ role: 'read'
188
+ });
189
+
190
+ await create_user({
191
+ username: 'user2',
192
+ password: 'password456',
193
+ role: 'write'
194
+ });
195
+
196
+ const users = get_all_users();
197
+
198
+ t.is(users.length, 2);
199
+
200
+ const user1 = users.find(u => u.username === 'user1');
201
+ const user2 = users.find(u => u.username === 'user2');
202
+
203
+ t.truthy(user1);
204
+ t.truthy(user2);
205
+ t.is(user1.role, 'read');
206
+ t.is(user2.role, 'write');
207
+ t.is(user1.password_hash, undefined);
208
+ t.is(user2.password_hash, undefined);
209
+ });
210
+
211
+ test('get_user returns user by username', async (t) => {
212
+ await create_user({
213
+ username: 'testuser',
214
+ password: 'testpassword123',
215
+ role: 'read_write'
216
+ });
217
+
218
+ const user = get_user('testuser');
219
+
220
+ t.truthy(user);
221
+ t.is(user.username, 'testuser');
222
+ t.is(user.role, 'read_write');
223
+ t.is(user.password_hash, undefined);
224
+ });
225
+
226
+ test('get_user returns null for non-existent user', (t) => {
227
+ const user = get_user('nonexistent');
228
+
229
+ t.is(user, null);
230
+ });
231
+
232
+ test('update_user updates user role', async (t) => {
233
+ await create_user({
234
+ username: 'testuser',
235
+ password: 'testpassword123',
236
+ role: 'read'
237
+ });
238
+
239
+ const updated_user = await update_user('testuser', { role: 'read_write' });
240
+
241
+ t.is(updated_user.username, 'testuser');
242
+ t.is(updated_user.role, 'read_write');
243
+ t.true(typeof updated_user.updated_at === 'string');
244
+ });
245
+
246
+ test('update_user updates user password', async (t) => {
247
+ await create_user({
248
+ username: 'testuser',
249
+ password: 'oldpassword123',
250
+ role: 'read'
251
+ });
252
+
253
+ const updated_user = await update_user('testuser', { password: 'newpassword456' });
254
+
255
+ t.is(updated_user.username, 'testuser');
256
+ t.is(updated_user.role, 'read');
257
+
258
+ // Verify new password works
259
+ const verified_user = await verify_user_password('testuser', 'newpassword456');
260
+ t.truthy(verified_user);
261
+
262
+ // Verify old password doesn't work
263
+ const old_password_result = await verify_user_password('testuser', 'oldpassword123');
264
+ t.is(old_password_result, null);
265
+ });
266
+
267
+ test('update_user throws error for non-existent user', async (t) => {
268
+ const error = await t.throwsAsync(async () => {
269
+ await update_user('nonexistent', { role: 'read_write' });
270
+ });
271
+
272
+ t.is(error.message, 'User not found');
273
+ });
274
+
275
+ test('update_user validates new role', async (t) => {
276
+ await create_user({
277
+ username: 'testuser',
278
+ password: 'testpassword123',
279
+ role: 'read'
280
+ });
281
+
282
+ const error = await t.throwsAsync(async () => {
283
+ await update_user('testuser', { role: 'invalid_role' });
284
+ });
285
+
286
+ t.true(error.message.includes('Role must be one of: read, write, read_write'));
287
+ });
288
+
289
+ test('update_user validates new password', async (t) => {
290
+ await create_user({
291
+ username: 'testuser',
292
+ password: 'testpassword123',
293
+ role: 'read'
294
+ });
295
+
296
+ const error = await t.throwsAsync(async () => {
297
+ await update_user('testuser', { password: 'short' });
298
+ });
299
+
300
+ t.true(error.message.includes('Password must be at least 8 characters long'));
301
+ });
302
+
303
+ test('delete_user removes user from database', async (t) => {
304
+ await create_user({
305
+ username: 'testuser',
306
+ password: 'testpassword123',
307
+ role: 'read'
308
+ });
309
+
310
+ const result = delete_user('testuser');
311
+
312
+ t.true(result);
313
+
314
+ const user = get_user('testuser');
315
+ t.is(user, null);
316
+ });
317
+
318
+ test('delete_user throws error for non-existent user', (t) => {
319
+ const error = t.throws(() => {
320
+ delete_user('nonexistent');
321
+ });
322
+
323
+ t.is(error.message, 'User not found');
324
+ });
325
+
326
+ test('verify_user_password returns user for correct password', async (t) => {
327
+ await create_user({
328
+ username: 'testuser',
329
+ password: 'testpassword123',
330
+ role: 'read_write'
331
+ });
332
+
333
+ const verified_user = await verify_user_password('testuser', 'testpassword123');
334
+
335
+ t.truthy(verified_user);
336
+ t.is(verified_user.username, 'testuser');
337
+ t.is(verified_user.role, 'read_write');
338
+ t.is(verified_user.password_hash, undefined);
339
+ });
340
+
341
+ test('verify_user_password returns null for incorrect password', async (t) => {
342
+ await create_user({
343
+ username: 'testuser',
344
+ password: 'testpassword123',
345
+ role: 'read_write'
346
+ });
347
+
348
+ const result = await verify_user_password('testuser', 'wrongpassword');
349
+
350
+ t.is(result, null);
351
+ });
352
+
353
+ test('verify_user_password returns null for non-existent user', async (t) => {
354
+ const result = await verify_user_password('nonexistent', 'anypassword');
355
+
356
+ t.is(result, null);
357
+ });
358
+
359
+ test('check_admin_user_exists returns false when no users exist', (t) => {
360
+ const has_admin = check_admin_user_exists();
361
+
362
+ t.false(has_admin);
363
+ });
364
+
365
+ test('check_admin_user_exists returns false when no admin users exist', async (t) => {
366
+ await create_user({
367
+ username: 'readuser',
368
+ password: 'testpassword123',
369
+ role: 'read'
370
+ });
371
+
372
+ await create_user({
373
+ username: 'writeuser',
374
+ password: 'testpassword123',
375
+ role: 'write'
376
+ });
377
+
378
+ const has_admin = check_admin_user_exists();
379
+
380
+ t.false(has_admin);
381
+ });
382
+
383
+ test('check_admin_user_exists returns true when admin user exists', async (t) => {
384
+ await create_user({
385
+ username: 'admin',
386
+ password: 'testpassword123',
387
+ role: 'read_write'
388
+ });
389
+
390
+ const has_admin = check_admin_user_exists();
391
+
392
+ t.true(has_admin);
393
+ });
394
+
395
+ test('create_user sets admin flag when creating read_write user', async (t) => {
396
+ t.false(check_admin_user_exists());
397
+
398
+ await create_user({
399
+ username: 'admin',
400
+ password: 'testpassword123',
401
+ role: 'read_write'
402
+ });
403
+
404
+ t.true(check_admin_user_exists());
405
+ });
406
+
407
+ test('initialize_api_key_manager generates API key and checks for admin users', (t) => {
408
+ t.notThrows(() => {
409
+ initialize_api_key_manager();
410
+ });
411
+
412
+ t.true(existsSync(API_KEY_FILE_PATH));
413
+ });
414
+
415
+ test('reset_api_key_state cleans up API key file and state', (t) => {
416
+ load_or_generate_api_key();
417
+ t.true(existsSync(API_KEY_FILE_PATH));
418
+
419
+ reset_api_key_state();
420
+
421
+ t.false(existsSync(API_KEY_FILE_PATH));
422
+ });
423
+
424
+ test('API key file has secure permissions', (t) => {
425
+ load_or_generate_api_key();
426
+
427
+ const stats = statSync(API_KEY_FILE_PATH);
428
+ const mode = stats.mode & parseInt('777', 8);
429
+
430
+ // Should be readable/writable by owner only (600)
431
+ t.is(mode, parseInt('600', 8));
432
+ });
433
+
434
+ test('password hashing uses bcrypt', async (t) => {
435
+ const user_data = {
436
+ username: 'testuser',
437
+ password: 'testpassword123',
438
+ role: 'read'
439
+ };
440
+
441
+ await create_user(user_data);
442
+
443
+ // Verify password works
444
+ const verified_user = await verify_user_password('testuser', 'testpassword123');
445
+ t.truthy(verified_user);
446
+
447
+ // Verify wrong password fails
448
+ const wrong_password_result = await verify_user_password('testuser', 'wrongpassword');
449
+ t.is(wrong_password_result, null);
450
+ });
451
+
452
+ test('username validation accepts valid usernames', async (t) => {
453
+ const valid_usernames = ['abc', 'user123', 'TestUser', 'a'.repeat(50)];
454
+
455
+ for (const username of valid_usernames) {
456
+ await t.notThrowsAsync(async () => {
457
+ await create_user({
458
+ username,
459
+ password: 'testpassword123',
460
+ role: 'read'
461
+ });
462
+ });
463
+
464
+ // Clean up for next iteration
465
+ delete_user(username);
466
+ }
467
+ });
468
+
469
+ test('password validation accepts valid passwords', async (t) => {
470
+ const valid_passwords = [
471
+ 'password',
472
+ 'testpassword123',
473
+ 'a'.repeat(128), // Max length
474
+ 'complex!@#$%^&*()password'
475
+ ];
476
+
477
+ for (let i = 0; i < valid_passwords.length; i++) {
478
+ const username = `user${i}`;
479
+ await t.notThrowsAsync(async () => {
480
+ await create_user({
481
+ username,
482
+ password: valid_passwords[i],
483
+ role: 'read'
484
+ });
485
+ });
486
+ }
487
+ });
488
+
489
+ test('password validation rejects passwords that are too long', async (t) => {
490
+ const too_long_password = 'a'.repeat(129); // Over 128 character limit
491
+
492
+ const error = await t.throwsAsync(async () => {
493
+ await create_user({
494
+ username: 'testuser',
495
+ password: too_long_password,
496
+ role: 'read'
497
+ });
498
+ });
499
+
500
+ t.true(error.message.includes('Password must be no more than 128 characters long'));
501
+ });
502
+
503
+ test('role validation accepts all valid roles', async (t) => {
504
+ const valid_roles = ['read', 'write', 'read_write'];
505
+
506
+ for (let i = 0; i < valid_roles.length; i++) {
507
+ const username = `user${i}`;
508
+ await t.notThrowsAsync(async () => {
509
+ await create_user({
510
+ username,
511
+ password: 'testpassword123',
512
+ role: valid_roles[i]
513
+ });
514
+ });
515
+ }
516
+ });