mongo.do 0.1.0 → 0.1.1

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 (706) hide show
  1. package/dist/cli/index.d.ts +1 -15
  2. package/dist/cli/index.js +4083 -196
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/index.d.ts +2740 -20
  5. package/dist/index.js +9375 -27
  6. package/dist/index.js.map +1 -1
  7. package/dist/worker-entrypoint-BEW23Gmp.d.ts +1331 -0
  8. package/dist/worker.d.ts +6 -5
  9. package/dist/worker.js +5477 -18
  10. package/dist/worker.js.map +1 -1
  11. package/package.json +3 -2
  12. package/dist/agentfs/adapters/anthropic.d.ts +0 -176
  13. package/dist/agentfs/adapters/anthropic.d.ts.map +0 -1
  14. package/dist/agentfs/adapters/anthropic.js +0 -629
  15. package/dist/agentfs/adapters/anthropic.js.map +0 -1
  16. package/dist/agentfs/adapters/index.d.ts +0 -21
  17. package/dist/agentfs/adapters/index.d.ts.map +0 -1
  18. package/dist/agentfs/adapters/index.js +0 -23
  19. package/dist/agentfs/adapters/index.js.map +0 -1
  20. package/dist/agentfs/adapters/vercel.d.ts +0 -260
  21. package/dist/agentfs/adapters/vercel.d.ts.map +0 -1
  22. package/dist/agentfs/adapters/vercel.js +0 -288
  23. package/dist/agentfs/adapters/vercel.js.map +0 -1
  24. package/dist/agentfs/glob.d.ts +0 -116
  25. package/dist/agentfs/glob.d.ts.map +0 -1
  26. package/dist/agentfs/glob.js +0 -270
  27. package/dist/agentfs/glob.js.map +0 -1
  28. package/dist/agentfs/grep.d.ts +0 -83
  29. package/dist/agentfs/grep.d.ts.map +0 -1
  30. package/dist/agentfs/grep.js +0 -193
  31. package/dist/agentfs/grep.js.map +0 -1
  32. package/dist/agentfs/index.d.ts +0 -22
  33. package/dist/agentfs/index.d.ts.map +0 -1
  34. package/dist/agentfs/index.js +0 -18
  35. package/dist/agentfs/index.js.map +0 -1
  36. package/dist/agentfs/kv-store.d.ts +0 -128
  37. package/dist/agentfs/kv-store.d.ts.map +0 -1
  38. package/dist/agentfs/kv-store.js +0 -227
  39. package/dist/agentfs/kv-store.js.map +0 -1
  40. package/dist/agentfs/mondo-agent.d.ts +0 -255
  41. package/dist/agentfs/mondo-agent.d.ts.map +0 -1
  42. package/dist/agentfs/mondo-agent.js +0 -879
  43. package/dist/agentfs/mondo-agent.js.map +0 -1
  44. package/dist/agentfs/toolcalls.d.ts +0 -130
  45. package/dist/agentfs/toolcalls.d.ts.map +0 -1
  46. package/dist/agentfs/toolcalls.js +0 -178
  47. package/dist/agentfs/toolcalls.js.map +0 -1
  48. package/dist/agentfs/types.d.ts +0 -171
  49. package/dist/agentfs/types.d.ts.map +0 -1
  50. package/dist/agentfs/types.js +0 -7
  51. package/dist/agentfs/types.js.map +0 -1
  52. package/dist/agentfs/vfs.d.ts +0 -249
  53. package/dist/agentfs/vfs.d.ts.map +0 -1
  54. package/dist/agentfs/vfs.js +0 -469
  55. package/dist/agentfs/vfs.js.map +0 -1
  56. package/dist/cli/index.d.ts.map +0 -1
  57. package/dist/cli/mcp.d.ts +0 -119
  58. package/dist/cli/mcp.d.ts.map +0 -1
  59. package/dist/cli/mcp.js +0 -418
  60. package/dist/cli/mcp.js.map +0 -1
  61. package/dist/cli/server.d.ts +0 -179
  62. package/dist/cli/server.d.ts.map +0 -1
  63. package/dist/cli/server.js +0 -441
  64. package/dist/cli/server.js.map +0 -1
  65. package/dist/client/Collection.d.ts +0 -199
  66. package/dist/client/Collection.d.ts.map +0 -1
  67. package/dist/client/Collection.js +0 -256
  68. package/dist/client/Collection.js.map +0 -1
  69. package/dist/client/Database.d.ts +0 -68
  70. package/dist/client/Database.d.ts.map +0 -1
  71. package/dist/client/Database.js +0 -105
  72. package/dist/client/Database.js.map +0 -1
  73. package/dist/client/MongoClient.d.ts +0 -165
  74. package/dist/client/MongoClient.d.ts.map +0 -1
  75. package/dist/client/MongoClient.js +0 -307
  76. package/dist/client/MongoClient.js.map +0 -1
  77. package/dist/client/aggregation-cursor.d.ts +0 -210
  78. package/dist/client/aggregation-cursor.d.ts.map +0 -1
  79. package/dist/client/aggregation-cursor.js +0 -509
  80. package/dist/client/aggregation-cursor.js.map +0 -1
  81. package/dist/client/bulk-write.d.ts +0 -216
  82. package/dist/client/bulk-write.d.ts.map +0 -1
  83. package/dist/client/bulk-write.js +0 -63
  84. package/dist/client/bulk-write.js.map +0 -1
  85. package/dist/client/change-stream.d.ts +0 -245
  86. package/dist/client/change-stream.d.ts.map +0 -1
  87. package/dist/client/change-stream.js +0 -429
  88. package/dist/client/change-stream.js.map +0 -1
  89. package/dist/client/cursor.d.ts +0 -85
  90. package/dist/client/cursor.d.ts.map +0 -1
  91. package/dist/client/cursor.js +0 -156
  92. package/dist/client/cursor.js.map +0 -1
  93. package/dist/client/http-cursor.d.ts +0 -233
  94. package/dist/client/http-cursor.d.ts.map +0 -1
  95. package/dist/client/http-cursor.js +0 -496
  96. package/dist/client/http-cursor.js.map +0 -1
  97. package/dist/client/index.d.ts +0 -18
  98. package/dist/client/index.d.ts.map +0 -1
  99. package/dist/client/index.js +0 -24
  100. package/dist/client/index.js.map +0 -1
  101. package/dist/client/mongo-client.d.ts +0 -60
  102. package/dist/client/mongo-client.d.ts.map +0 -1
  103. package/dist/client/mongo-client.js +0 -190
  104. package/dist/client/mongo-client.js.map +0 -1
  105. package/dist/client/mongo-collection.d.ts +0 -359
  106. package/dist/client/mongo-collection.d.ts.map +0 -1
  107. package/dist/client/mongo-collection.js +0 -1641
  108. package/dist/client/mongo-collection.js.map +0 -1
  109. package/dist/client/mongo-cursor.d.ts +0 -257
  110. package/dist/client/mongo-cursor.d.ts.map +0 -1
  111. package/dist/client/mongo-cursor.js +0 -621
  112. package/dist/client/mongo-cursor.js.map +0 -1
  113. package/dist/client/mongo-database.d.ts +0 -88
  114. package/dist/client/mongo-database.d.ts.map +0 -1
  115. package/dist/client/mongo-database.js +0 -139
  116. package/dist/client/mongo-database.js.map +0 -1
  117. package/dist/client/session.d.ts +0 -210
  118. package/dist/client/session.d.ts.map +0 -1
  119. package/dist/client/session.js +0 -326
  120. package/dist/client/session.js.map +0 -1
  121. package/dist/durable-object/index-manager.d.ts +0 -173
  122. package/dist/durable-object/index-manager.d.ts.map +0 -1
  123. package/dist/durable-object/index-manager.js +0 -764
  124. package/dist/durable-object/index-manager.js.map +0 -1
  125. package/dist/durable-object/index.d.ts +0 -12
  126. package/dist/durable-object/index.d.ts.map +0 -1
  127. package/dist/durable-object/index.js +0 -8
  128. package/dist/durable-object/index.js.map +0 -1
  129. package/dist/durable-object/mcp-handler.d.ts +0 -52
  130. package/dist/durable-object/mcp-handler.d.ts.map +0 -1
  131. package/dist/durable-object/mcp-handler.js +0 -186
  132. package/dist/durable-object/mcp-handler.js.map +0 -1
  133. package/dist/durable-object/migrations.d.ts +0 -40
  134. package/dist/durable-object/migrations.d.ts.map +0 -1
  135. package/dist/durable-object/migrations.js +0 -121
  136. package/dist/durable-object/migrations.js.map +0 -1
  137. package/dist/durable-object/mondo-database.d.ts +0 -148
  138. package/dist/durable-object/mondo-database.d.ts.map +0 -1
  139. package/dist/durable-object/mondo-database.js +0 -621
  140. package/dist/durable-object/mondo-database.js.map +0 -1
  141. package/dist/durable-object/schema.d.ts +0 -192
  142. package/dist/durable-object/schema.d.ts.map +0 -1
  143. package/dist/durable-object/schema.js +0 -186
  144. package/dist/durable-object/schema.js.map +0 -1
  145. package/dist/embedding/document-serializer.d.ts +0 -118
  146. package/dist/embedding/document-serializer.d.ts.map +0 -1
  147. package/dist/embedding/document-serializer.js +0 -339
  148. package/dist/embedding/document-serializer.js.map +0 -1
  149. package/dist/embedding/embedding-manager.d.ts +0 -136
  150. package/dist/embedding/embedding-manager.d.ts.map +0 -1
  151. package/dist/embedding/embedding-manager.js +0 -176
  152. package/dist/embedding/embedding-manager.js.map +0 -1
  153. package/dist/embedding/index.d.ts +0 -9
  154. package/dist/embedding/index.d.ts.map +0 -1
  155. package/dist/embedding/index.js +0 -9
  156. package/dist/embedding/index.js.map +0 -1
  157. package/dist/executor/aggregation-executor.d.ts +0 -93
  158. package/dist/executor/aggregation-executor.d.ts.map +0 -1
  159. package/dist/executor/aggregation-executor.js +0 -275
  160. package/dist/executor/aggregation-executor.js.map +0 -1
  161. package/dist/executor/function-executor.d.ts +0 -39
  162. package/dist/executor/function-executor.d.ts.map +0 -1
  163. package/dist/executor/function-executor.js +0 -168
  164. package/dist/executor/function-executor.js.map +0 -1
  165. package/dist/executor/index.d.ts +0 -4
  166. package/dist/executor/index.d.ts.map +0 -1
  167. package/dist/executor/index.js +0 -4
  168. package/dist/executor/index.js.map +0 -1
  169. package/dist/executor/vector-search-executor.d.ts +0 -71
  170. package/dist/executor/vector-search-executor.d.ts.map +0 -1
  171. package/dist/executor/vector-search-executor.js +0 -113
  172. package/dist/executor/vector-search-executor.js.map +0 -1
  173. package/dist/index.d.ts.map +0 -1
  174. package/dist/mcp/adapters/anthropic-adapter.d.ts +0 -256
  175. package/dist/mcp/adapters/anthropic-adapter.d.ts.map +0 -1
  176. package/dist/mcp/adapters/anthropic-adapter.js +0 -409
  177. package/dist/mcp/adapters/anthropic-adapter.js.map +0 -1
  178. package/dist/mcp/adapters/base-adapter.d.ts +0 -164
  179. package/dist/mcp/adapters/base-adapter.d.ts.map +0 -1
  180. package/dist/mcp/adapters/base-adapter.js +0 -277
  181. package/dist/mcp/adapters/base-adapter.js.map +0 -1
  182. package/dist/mcp/adapters/errors.d.ts +0 -173
  183. package/dist/mcp/adapters/errors.d.ts.map +0 -1
  184. package/dist/mcp/adapters/errors.js +0 -305
  185. package/dist/mcp/adapters/errors.js.map +0 -1
  186. package/dist/mcp/adapters/index.d.ts +0 -65
  187. package/dist/mcp/adapters/index.d.ts.map +0 -1
  188. package/dist/mcp/adapters/index.js +0 -92
  189. package/dist/mcp/adapters/index.js.map +0 -1
  190. package/dist/mcp/adapters/streaming.d.ts +0 -200
  191. package/dist/mcp/adapters/streaming.d.ts.map +0 -1
  192. package/dist/mcp/adapters/streaming.js +0 -381
  193. package/dist/mcp/adapters/streaming.js.map +0 -1
  194. package/dist/mcp/adapters/vercel-adapter.d.ts +0 -321
  195. package/dist/mcp/adapters/vercel-adapter.d.ts.map +0 -1
  196. package/dist/mcp/adapters/vercel-adapter.js +0 -487
  197. package/dist/mcp/adapters/vercel-adapter.js.map +0 -1
  198. package/dist/mcp/agent.d.ts +0 -192
  199. package/dist/mcp/agent.d.ts.map +0 -1
  200. package/dist/mcp/agent.js +0 -338
  201. package/dist/mcp/agent.js.map +0 -1
  202. package/dist/mcp/cli.d.ts +0 -71
  203. package/dist/mcp/cli.d.ts.map +0 -1
  204. package/dist/mcp/cli.js +0 -218
  205. package/dist/mcp/cli.js.map +0 -1
  206. package/dist/mcp/index.d.ts +0 -15
  207. package/dist/mcp/index.d.ts.map +0 -1
  208. package/dist/mcp/index.js +0 -20
  209. package/dist/mcp/index.js.map +0 -1
  210. package/dist/mcp/sandbox/database-proxy.d.ts +0 -118
  211. package/dist/mcp/sandbox/database-proxy.d.ts.map +0 -1
  212. package/dist/mcp/sandbox/database-proxy.js +0 -154
  213. package/dist/mcp/sandbox/database-proxy.js.map +0 -1
  214. package/dist/mcp/sandbox/index.d.ts +0 -8
  215. package/dist/mcp/sandbox/index.d.ts.map +0 -1
  216. package/dist/mcp/sandbox/index.js +0 -7
  217. package/dist/mcp/sandbox/index.js.map +0 -1
  218. package/dist/mcp/sandbox/miniflare-evaluator.d.ts +0 -72
  219. package/dist/mcp/sandbox/miniflare-evaluator.d.ts.map +0 -1
  220. package/dist/mcp/sandbox/miniflare-evaluator.js +0 -379
  221. package/dist/mcp/sandbox/miniflare-evaluator.js.map +0 -1
  222. package/dist/mcp/sandbox/template.d.ts +0 -48
  223. package/dist/mcp/sandbox/template.d.ts.map +0 -1
  224. package/dist/mcp/sandbox/template.js +0 -147
  225. package/dist/mcp/sandbox/template.js.map +0 -1
  226. package/dist/mcp/sandbox/worker-evaluator.d.ts +0 -160
  227. package/dist/mcp/sandbox/worker-evaluator.d.ts.map +0 -1
  228. package/dist/mcp/sandbox/worker-evaluator.js +0 -217
  229. package/dist/mcp/sandbox/worker-evaluator.js.map +0 -1
  230. package/dist/mcp/server.d.ts +0 -75
  231. package/dist/mcp/server.d.ts.map +0 -1
  232. package/dist/mcp/server.js +0 -278
  233. package/dist/mcp/server.js.map +0 -1
  234. package/dist/mcp/tool-call-auditor.d.ts +0 -188
  235. package/dist/mcp/tool-call-auditor.d.ts.map +0 -1
  236. package/dist/mcp/tool-call-auditor.js +0 -198
  237. package/dist/mcp/tool-call-auditor.js.map +0 -1
  238. package/dist/mcp/tools/do.d.ts +0 -51
  239. package/dist/mcp/tools/do.d.ts.map +0 -1
  240. package/dist/mcp/tools/do.js +0 -113
  241. package/dist/mcp/tools/do.js.map +0 -1
  242. package/dist/mcp/tools/fetch.d.ts +0 -43
  243. package/dist/mcp/tools/fetch.d.ts.map +0 -1
  244. package/dist/mcp/tools/fetch.js +0 -127
  245. package/dist/mcp/tools/fetch.js.map +0 -1
  246. package/dist/mcp/tools/index.d.ts +0 -9
  247. package/dist/mcp/tools/index.d.ts.map +0 -1
  248. package/dist/mcp/tools/index.js +0 -9
  249. package/dist/mcp/tools/index.js.map +0 -1
  250. package/dist/mcp/tools/search.d.ts +0 -60
  251. package/dist/mcp/tools/search.d.ts.map +0 -1
  252. package/dist/mcp/tools/search.js +0 -278
  253. package/dist/mcp/tools/search.js.map +0 -1
  254. package/dist/mcp/transport/http.d.ts +0 -144
  255. package/dist/mcp/transport/http.d.ts.map +0 -1
  256. package/dist/mcp/transport/http.js +0 -545
  257. package/dist/mcp/transport/http.js.map +0 -1
  258. package/dist/mcp/transport/index.d.ts +0 -10
  259. package/dist/mcp/transport/index.d.ts.map +0 -1
  260. package/dist/mcp/transport/index.js +0 -12
  261. package/dist/mcp/transport/index.js.map +0 -1
  262. package/dist/mcp/transport/stdio.d.ts +0 -132
  263. package/dist/mcp/transport/stdio.d.ts.map +0 -1
  264. package/dist/mcp/transport/stdio.js +0 -466
  265. package/dist/mcp/transport/stdio.js.map +0 -1
  266. package/dist/mcp/types.d.ts +0 -476
  267. package/dist/mcp/types.d.ts.map +0 -1
  268. package/dist/mcp/types.js +0 -178
  269. package/dist/mcp/types.js.map +0 -1
  270. package/dist/olap/cdc/cdc-buffer.d.ts +0 -92
  271. package/dist/olap/cdc/cdc-buffer.d.ts.map +0 -1
  272. package/dist/olap/cdc/cdc-buffer.js +0 -146
  273. package/dist/olap/cdc/cdc-buffer.js.map +0 -1
  274. package/dist/olap/cdc/cdc-emitter.d.ts +0 -118
  275. package/dist/olap/cdc/cdc-emitter.d.ts.map +0 -1
  276. package/dist/olap/cdc/cdc-emitter.js +0 -217
  277. package/dist/olap/cdc/cdc-emitter.js.map +0 -1
  278. package/dist/olap/cdc/cdc-schema.d.ts +0 -119
  279. package/dist/olap/cdc/cdc-schema.d.ts.map +0 -1
  280. package/dist/olap/cdc/cdc-schema.js +0 -253
  281. package/dist/olap/cdc/cdc-schema.js.map +0 -1
  282. package/dist/olap/cdc/index.d.ts +0 -10
  283. package/dist/olap/cdc/index.d.ts.map +0 -1
  284. package/dist/olap/cdc/index.js +0 -10
  285. package/dist/olap/cdc/index.js.map +0 -1
  286. package/dist/olap/clickhouse/iceberg.d.ts +0 -164
  287. package/dist/olap/clickhouse/iceberg.d.ts.map +0 -1
  288. package/dist/olap/clickhouse/iceberg.js +0 -138
  289. package/dist/olap/clickhouse/iceberg.js.map +0 -1
  290. package/dist/olap/clickhouse/index.d.ts +0 -14
  291. package/dist/olap/clickhouse/index.d.ts.map +0 -1
  292. package/dist/olap/clickhouse/index.js +0 -14
  293. package/dist/olap/clickhouse/index.js.map +0 -1
  294. package/dist/olap/clickhouse/mapper.d.ts +0 -170
  295. package/dist/olap/clickhouse/mapper.d.ts.map +0 -1
  296. package/dist/olap/clickhouse/mapper.js +0 -654
  297. package/dist/olap/clickhouse/mapper.js.map +0 -1
  298. package/dist/olap/clickhouse/olap-backend.d.ts +0 -181
  299. package/dist/olap/clickhouse/olap-backend.d.ts.map +0 -1
  300. package/dist/olap/clickhouse/olap-backend.js +0 -1083
  301. package/dist/olap/clickhouse/olap-backend.js.map +0 -1
  302. package/dist/olap/clickhouse/query-executor.d.ts +0 -163
  303. package/dist/olap/clickhouse/query-executor.d.ts.map +0 -1
  304. package/dist/olap/clickhouse/query-executor.js +0 -560
  305. package/dist/olap/clickhouse/query-executor.js.map +0 -1
  306. package/dist/olap/clickhouse/query.d.ts +0 -134
  307. package/dist/olap/clickhouse/query.d.ts.map +0 -1
  308. package/dist/olap/clickhouse/query.js +0 -512
  309. package/dist/olap/clickhouse/query.js.map +0 -1
  310. package/dist/olap/stage/index.d.ts +0 -6
  311. package/dist/olap/stage/index.d.ts.map +0 -1
  312. package/dist/olap/stage/index.js +0 -6
  313. package/dist/olap/stage/index.js.map +0 -1
  314. package/dist/olap/stage/parser.d.ts +0 -68
  315. package/dist/olap/stage/parser.d.ts.map +0 -1
  316. package/dist/olap/stage/parser.js +0 -293
  317. package/dist/olap/stage/parser.js.map +0 -1
  318. package/dist/olap/stage/router.d.ts +0 -94
  319. package/dist/olap/stage/router.d.ts.map +0 -1
  320. package/dist/olap/stage/router.js +0 -390
  321. package/dist/olap/stage/router.js.map +0 -1
  322. package/dist/rpc/endpoint.d.ts +0 -52
  323. package/dist/rpc/endpoint.d.ts.map +0 -1
  324. package/dist/rpc/endpoint.js +0 -734
  325. package/dist/rpc/endpoint.js.map +0 -1
  326. package/dist/rpc/index.d.ts +0 -34
  327. package/dist/rpc/index.d.ts.map +0 -1
  328. package/dist/rpc/index.js +0 -45
  329. package/dist/rpc/index.js.map +0 -1
  330. package/dist/rpc/rpc-client.d.ts +0 -275
  331. package/dist/rpc/rpc-client.d.ts.map +0 -1
  332. package/dist/rpc/rpc-client.js +0 -735
  333. package/dist/rpc/rpc-client.js.map +0 -1
  334. package/dist/rpc/rpc-target.d.ts +0 -220
  335. package/dist/rpc/rpc-target.d.ts.map +0 -1
  336. package/dist/rpc/rpc-target.js +0 -500
  337. package/dist/rpc/rpc-target.js.map +0 -1
  338. package/dist/rpc/worker-entrypoint.d.ts +0 -159
  339. package/dist/rpc/worker-entrypoint.d.ts.map +0 -1
  340. package/dist/rpc/worker-entrypoint.js +0 -212
  341. package/dist/rpc/worker-entrypoint.js.map +0 -1
  342. package/dist/server.d.ts +0 -18
  343. package/dist/server.d.ts.map +0 -1
  344. package/dist/server.js +0 -129
  345. package/dist/server.js.map +0 -1
  346. package/dist/studio/components/browser/CollectionItem.d.ts +0 -26
  347. package/dist/studio/components/browser/CollectionItem.d.ts.map +0 -1
  348. package/dist/studio/components/browser/CollectionItem.js +0 -143
  349. package/dist/studio/components/browser/CollectionItem.js.map +0 -1
  350. package/dist/studio/components/browser/CollectionTree.d.ts +0 -45
  351. package/dist/studio/components/browser/CollectionTree.d.ts.map +0 -1
  352. package/dist/studio/components/browser/CollectionTree.js +0 -207
  353. package/dist/studio/components/browser/CollectionTree.js.map +0 -1
  354. package/dist/studio/components/browser/ConnectedDatabaseBrowser.d.ts +0 -51
  355. package/dist/studio/components/browser/ConnectedDatabaseBrowser.d.ts.map +0 -1
  356. package/dist/studio/components/browser/ConnectedDatabaseBrowser.js +0 -185
  357. package/dist/studio/components/browser/ConnectedDatabaseBrowser.js.map +0 -1
  358. package/dist/studio/components/browser/DatabaseBrowser.d.ts +0 -46
  359. package/dist/studio/components/browser/DatabaseBrowser.d.ts.map +0 -1
  360. package/dist/studio/components/browser/DatabaseBrowser.js +0 -304
  361. package/dist/studio/components/browser/DatabaseBrowser.js.map +0 -1
  362. package/dist/studio/components/browser/__tests__/CollectionItem.test.d.ts +0 -5
  363. package/dist/studio/components/browser/__tests__/CollectionItem.test.d.ts.map +0 -1
  364. package/dist/studio/components/browser/__tests__/CollectionItem.test.js +0 -169
  365. package/dist/studio/components/browser/__tests__/CollectionItem.test.js.map +0 -1
  366. package/dist/studio/components/browser/__tests__/CollectionTree.test.d.ts +0 -5
  367. package/dist/studio/components/browser/__tests__/CollectionTree.test.d.ts.map +0 -1
  368. package/dist/studio/components/browser/__tests__/CollectionTree.test.js +0 -203
  369. package/dist/studio/components/browser/__tests__/CollectionTree.test.js.map +0 -1
  370. package/dist/studio/components/browser/__tests__/DatabaseBrowser.e2e.test.d.ts +0 -8
  371. package/dist/studio/components/browser/__tests__/DatabaseBrowser.e2e.test.d.ts.map +0 -1
  372. package/dist/studio/components/browser/__tests__/DatabaseBrowser.e2e.test.js +0 -522
  373. package/dist/studio/components/browser/__tests__/DatabaseBrowser.e2e.test.js.map +0 -1
  374. package/dist/studio/components/browser/__tests__/DatabaseBrowser.test.d.ts +0 -5
  375. package/dist/studio/components/browser/__tests__/DatabaseBrowser.test.d.ts.map +0 -1
  376. package/dist/studio/components/browser/__tests__/DatabaseBrowser.test.js +0 -518
  377. package/dist/studio/components/browser/__tests__/DatabaseBrowser.test.js.map +0 -1
  378. package/dist/studio/components/browser/__tests__/setup.d.ts +0 -5
  379. package/dist/studio/components/browser/__tests__/setup.d.ts.map +0 -1
  380. package/dist/studio/components/browser/__tests__/setup.js +0 -22
  381. package/dist/studio/components/browser/__tests__/setup.js.map +0 -1
  382. package/dist/studio/components/browser/index.d.ts +0 -15
  383. package/dist/studio/components/browser/index.d.ts.map +0 -1
  384. package/dist/studio/components/browser/index.js +0 -10
  385. package/dist/studio/components/browser/index.js.map +0 -1
  386. package/dist/studio/components/browser/types.d.ts +0 -33
  387. package/dist/studio/components/browser/types.d.ts.map +0 -1
  388. package/dist/studio/components/browser/types.js +0 -5
  389. package/dist/studio/components/browser/types.js.map +0 -1
  390. package/dist/studio/components/connection/ConnectionForm.d.ts +0 -59
  391. package/dist/studio/components/connection/ConnectionForm.d.ts.map +0 -1
  392. package/dist/studio/components/connection/ConnectionForm.js +0 -274
  393. package/dist/studio/components/connection/ConnectionForm.js.map +0 -1
  394. package/dist/studio/components/connection/ConnectionList.d.ts +0 -59
  395. package/dist/studio/components/connection/ConnectionList.d.ts.map +0 -1
  396. package/dist/studio/components/connection/ConnectionList.js +0 -286
  397. package/dist/studio/components/connection/ConnectionList.js.map +0 -1
  398. package/dist/studio/components/connection/ConnectionPanel.d.ts +0 -132
  399. package/dist/studio/components/connection/ConnectionPanel.d.ts.map +0 -1
  400. package/dist/studio/components/connection/ConnectionPanel.js +0 -293
  401. package/dist/studio/components/connection/ConnectionPanel.js.map +0 -1
  402. package/dist/studio/components/connection/__tests__/ConnectionPanel.test.d.ts +0 -8
  403. package/dist/studio/components/connection/__tests__/ConnectionPanel.test.d.ts.map +0 -1
  404. package/dist/studio/components/connection/__tests__/ConnectionPanel.test.js +0 -632
  405. package/dist/studio/components/connection/__tests__/ConnectionPanel.test.js.map +0 -1
  406. package/dist/studio/components/connection/__tests__/setup.d.ts +0 -5
  407. package/dist/studio/components/connection/__tests__/setup.d.ts.map +0 -1
  408. package/dist/studio/components/connection/__tests__/setup.js +0 -11
  409. package/dist/studio/components/connection/__tests__/setup.js.map +0 -1
  410. package/dist/studio/components/connection/index.d.ts +0 -10
  411. package/dist/studio/components/connection/index.d.ts.map +0 -1
  412. package/dist/studio/components/connection/index.js +0 -7
  413. package/dist/studio/components/connection/index.js.map +0 -1
  414. package/dist/studio/components/crud/DeleteDocumentDialog.d.ts +0 -91
  415. package/dist/studio/components/crud/DeleteDocumentDialog.d.ts.map +0 -1
  416. package/dist/studio/components/crud/DeleteDocumentDialog.js +0 -273
  417. package/dist/studio/components/crud/DeleteDocumentDialog.js.map +0 -1
  418. package/dist/studio/components/crud/DocumentEditor.d.ts +0 -32
  419. package/dist/studio/components/crud/DocumentEditor.d.ts.map +0 -1
  420. package/dist/studio/components/crud/DocumentEditor.js +0 -546
  421. package/dist/studio/components/crud/DocumentEditor.js.map +0 -1
  422. package/dist/studio/components/crud/InsertDocumentDialog.d.ts +0 -78
  423. package/dist/studio/components/crud/InsertDocumentDialog.d.ts.map +0 -1
  424. package/dist/studio/components/crud/InsertDocumentDialog.js +0 -323
  425. package/dist/studio/components/crud/InsertDocumentDialog.js.map +0 -1
  426. package/dist/studio/components/crud/__tests__/DeleteDocumentDialog.test.d.ts +0 -5
  427. package/dist/studio/components/crud/__tests__/DeleteDocumentDialog.test.d.ts.map +0 -1
  428. package/dist/studio/components/crud/__tests__/DeleteDocumentDialog.test.js +0 -298
  429. package/dist/studio/components/crud/__tests__/DeleteDocumentDialog.test.js.map +0 -1
  430. package/dist/studio/components/crud/__tests__/DocumentEditor.test.d.ts +0 -8
  431. package/dist/studio/components/crud/__tests__/DocumentEditor.test.d.ts.map +0 -1
  432. package/dist/studio/components/crud/__tests__/DocumentEditor.test.js +0 -368
  433. package/dist/studio/components/crud/__tests__/DocumentEditor.test.js.map +0 -1
  434. package/dist/studio/components/crud/__tests__/InsertDocumentDialog.test.d.ts +0 -2
  435. package/dist/studio/components/crud/__tests__/InsertDocumentDialog.test.d.ts.map +0 -1
  436. package/dist/studio/components/crud/__tests__/InsertDocumentDialog.test.js +0 -352
  437. package/dist/studio/components/crud/__tests__/InsertDocumentDialog.test.js.map +0 -1
  438. package/dist/studio/components/crud/__tests__/setup.d.ts +0 -5
  439. package/dist/studio/components/crud/__tests__/setup.d.ts.map +0 -1
  440. package/dist/studio/components/crud/__tests__/setup.js +0 -22
  441. package/dist/studio/components/crud/__tests__/setup.js.map +0 -1
  442. package/dist/studio/components/crud/index.d.ts +0 -12
  443. package/dist/studio/components/crud/index.d.ts.map +0 -1
  444. package/dist/studio/components/crud/index.js +0 -11
  445. package/dist/studio/components/crud/index.js.map +0 -1
  446. package/dist/studio/hooks/useConnection.d.ts +0 -127
  447. package/dist/studio/hooks/useConnection.d.ts.map +0 -1
  448. package/dist/studio/hooks/useConnection.js +0 -414
  449. package/dist/studio/hooks/useConnection.js.map +0 -1
  450. package/dist/studio/hooks/useDatabaseBrowser.d.ts +0 -107
  451. package/dist/studio/hooks/useDatabaseBrowser.d.ts.map +0 -1
  452. package/dist/studio/hooks/useDatabaseBrowser.js +0 -294
  453. package/dist/studio/hooks/useDatabaseBrowser.js.map +0 -1
  454. package/dist/studio/index.d.ts +0 -16
  455. package/dist/studio/index.d.ts.map +0 -1
  456. package/dist/studio/index.js +0 -14
  457. package/dist/studio/index.js.map +0 -1
  458. package/dist/studio/types/connection.d.ts +0 -266
  459. package/dist/studio/types/connection.d.ts.map +0 -1
  460. package/dist/studio/types/connection.js +0 -159
  461. package/dist/studio/types/connection.js.map +0 -1
  462. package/dist/studio/vitest.config.d.ts +0 -3
  463. package/dist/studio/vitest.config.d.ts.map +0 -1
  464. package/dist/studio/vitest.config.js +0 -33
  465. package/dist/studio/vitest.config.js.map +0 -1
  466. package/dist/translator/aggregation-translator.d.ts +0 -51
  467. package/dist/translator/aggregation-translator.d.ts.map +0 -1
  468. package/dist/translator/aggregation-translator.js +0 -324
  469. package/dist/translator/aggregation-translator.js.map +0 -1
  470. package/dist/translator/dialect.d.ts +0 -131
  471. package/dist/translator/dialect.d.ts.map +0 -1
  472. package/dist/translator/dialect.js +0 -276
  473. package/dist/translator/dialect.js.map +0 -1
  474. package/dist/translator/geo-translator.d.ts +0 -91
  475. package/dist/translator/geo-translator.d.ts.map +0 -1
  476. package/dist/translator/geo-translator.js +0 -587
  477. package/dist/translator/geo-translator.js.map +0 -1
  478. package/dist/translator/hybrid-translator.d.ts +0 -70
  479. package/dist/translator/hybrid-translator.d.ts.map +0 -1
  480. package/dist/translator/hybrid-translator.js +0 -193
  481. package/dist/translator/hybrid-translator.js.map +0 -1
  482. package/dist/translator/index.d.ts +0 -13
  483. package/dist/translator/index.d.ts.map +0 -1
  484. package/dist/translator/index.js +0 -11
  485. package/dist/translator/index.js.map +0 -1
  486. package/dist/translator/query-translator.d.ts +0 -211
  487. package/dist/translator/query-translator.d.ts.map +0 -1
  488. package/dist/translator/query-translator.js +0 -1276
  489. package/dist/translator/query-translator.js.map +0 -1
  490. package/dist/translator/search-highlight.d.ts +0 -83
  491. package/dist/translator/search-highlight.d.ts.map +0 -1
  492. package/dist/translator/search-highlight.js +0 -83
  493. package/dist/translator/search-highlight.js.map +0 -1
  494. package/dist/translator/search-translator.d.ts +0 -155
  495. package/dist/translator/search-translator.d.ts.map +0 -1
  496. package/dist/translator/search-translator.js +0 -241
  497. package/dist/translator/search-translator.js.map +0 -1
  498. package/dist/translator/stages/add-fields-stage.d.ts +0 -7
  499. package/dist/translator/stages/add-fields-stage.d.ts.map +0 -1
  500. package/dist/translator/stages/add-fields-stage.js +0 -72
  501. package/dist/translator/stages/add-fields-stage.js.map +0 -1
  502. package/dist/translator/stages/bucket-stage.d.ts +0 -7
  503. package/dist/translator/stages/bucket-stage.d.ts.map +0 -1
  504. package/dist/translator/stages/bucket-stage.js +0 -87
  505. package/dist/translator/stages/bucket-stage.js.map +0 -1
  506. package/dist/translator/stages/count-stage.d.ts +0 -7
  507. package/dist/translator/stages/count-stage.d.ts.map +0 -1
  508. package/dist/translator/stages/count-stage.js +0 -12
  509. package/dist/translator/stages/count-stage.js.map +0 -1
  510. package/dist/translator/stages/expression-translator.d.ts +0 -68
  511. package/dist/translator/stages/expression-translator.d.ts.map +0 -1
  512. package/dist/translator/stages/expression-translator.js +0 -467
  513. package/dist/translator/stages/expression-translator.js.map +0 -1
  514. package/dist/translator/stages/facet-stage.d.ts +0 -13
  515. package/dist/translator/stages/facet-stage.d.ts.map +0 -1
  516. package/dist/translator/stages/facet-stage.js +0 -26
  517. package/dist/translator/stages/facet-stage.js.map +0 -1
  518. package/dist/translator/stages/fusion-stages.d.ts +0 -118
  519. package/dist/translator/stages/fusion-stages.d.ts.map +0 -1
  520. package/dist/translator/stages/fusion-stages.js +0 -201
  521. package/dist/translator/stages/fusion-stages.js.map +0 -1
  522. package/dist/translator/stages/group-stage.d.ts +0 -8
  523. package/dist/translator/stages/group-stage.d.ts.map +0 -1
  524. package/dist/translator/stages/group-stage.js +0 -123
  525. package/dist/translator/stages/group-stage.js.map +0 -1
  526. package/dist/translator/stages/index.d.ts +0 -24
  527. package/dist/translator/stages/index.d.ts.map +0 -1
  528. package/dist/translator/stages/index.js +0 -24
  529. package/dist/translator/stages/index.js.map +0 -1
  530. package/dist/translator/stages/join-optimizer.d.ts +0 -37
  531. package/dist/translator/stages/join-optimizer.d.ts.map +0 -1
  532. package/dist/translator/stages/join-optimizer.js +0 -93
  533. package/dist/translator/stages/join-optimizer.js.map +0 -1
  534. package/dist/translator/stages/limit-stage.d.ts +0 -7
  535. package/dist/translator/stages/limit-stage.d.ts.map +0 -1
  536. package/dist/translator/stages/limit-stage.js +0 -11
  537. package/dist/translator/stages/limit-stage.js.map +0 -1
  538. package/dist/translator/stages/lookup-stage.d.ts +0 -7
  539. package/dist/translator/stages/lookup-stage.d.ts.map +0 -1
  540. package/dist/translator/stages/lookup-stage.js +0 -73
  541. package/dist/translator/stages/lookup-stage.js.map +0 -1
  542. package/dist/translator/stages/match-stage.d.ts +0 -7
  543. package/dist/translator/stages/match-stage.d.ts.map +0 -1
  544. package/dist/translator/stages/match-stage.js +0 -14
  545. package/dist/translator/stages/match-stage.js.map +0 -1
  546. package/dist/translator/stages/optimizer.d.ts +0 -15
  547. package/dist/translator/stages/optimizer.d.ts.map +0 -1
  548. package/dist/translator/stages/optimizer.js +0 -249
  549. package/dist/translator/stages/optimizer.js.map +0 -1
  550. package/dist/translator/stages/parallel-facet.d.ts +0 -47
  551. package/dist/translator/stages/parallel-facet.d.ts.map +0 -1
  552. package/dist/translator/stages/parallel-facet.js +0 -57
  553. package/dist/translator/stages/parallel-facet.js.map +0 -1
  554. package/dist/translator/stages/project-stage.d.ts +0 -8
  555. package/dist/translator/stages/project-stage.d.ts.map +0 -1
  556. package/dist/translator/stages/project-stage.js +0 -145
  557. package/dist/translator/stages/project-stage.js.map +0 -1
  558. package/dist/translator/stages/search-stage.d.ts +0 -60
  559. package/dist/translator/stages/search-stage.d.ts.map +0 -1
  560. package/dist/translator/stages/search-stage.js +0 -89
  561. package/dist/translator/stages/search-stage.js.map +0 -1
  562. package/dist/translator/stages/skip-stage.d.ts +0 -7
  563. package/dist/translator/stages/skip-stage.d.ts.map +0 -1
  564. package/dist/translator/stages/skip-stage.js +0 -11
  565. package/dist/translator/stages/skip-stage.js.map +0 -1
  566. package/dist/translator/stages/sort-stage.d.ts +0 -7
  567. package/dist/translator/stages/sort-stage.d.ts.map +0 -1
  568. package/dist/translator/stages/sort-stage.js +0 -21
  569. package/dist/translator/stages/sort-stage.js.map +0 -1
  570. package/dist/translator/stages/types.d.ts +0 -136
  571. package/dist/translator/stages/types.d.ts.map +0 -1
  572. package/dist/translator/stages/types.js +0 -5
  573. package/dist/translator/stages/types.js.map +0 -1
  574. package/dist/translator/stages/unwind-stage.d.ts +0 -7
  575. package/dist/translator/stages/unwind-stage.d.ts.map +0 -1
  576. package/dist/translator/stages/unwind-stage.js +0 -61
  577. package/dist/translator/stages/unwind-stage.js.map +0 -1
  578. package/dist/translator/stages/vector-search-stage.d.ts +0 -53
  579. package/dist/translator/stages/vector-search-stage.d.ts.map +0 -1
  580. package/dist/translator/stages/vector-search-stage.js +0 -62
  581. package/dist/translator/stages/vector-search-stage.js.map +0 -1
  582. package/dist/translator/update-translator.d.ts +0 -148
  583. package/dist/translator/update-translator.d.ts.map +0 -1
  584. package/dist/translator/update-translator.js +0 -819
  585. package/dist/translator/update-translator.js.map +0 -1
  586. package/dist/translator/vector-translator.d.ts +0 -89
  587. package/dist/translator/vector-translator.d.ts.map +0 -1
  588. package/dist/translator/vector-translator.js +0 -106
  589. package/dist/translator/vector-translator.js.map +0 -1
  590. package/dist/types/env.d.ts +0 -31
  591. package/dist/types/env.d.ts.map +0 -1
  592. package/dist/types/env.js +0 -5
  593. package/dist/types/env.js.map +0 -1
  594. package/dist/types/function.d.ts +0 -65
  595. package/dist/types/function.d.ts.map +0 -1
  596. package/dist/types/function.js +0 -5
  597. package/dist/types/function.js.map +0 -1
  598. package/dist/types/index.d.ts +0 -137
  599. package/dist/types/index.d.ts.map +0 -1
  600. package/dist/types/index.js +0 -13
  601. package/dist/types/index.js.map +0 -1
  602. package/dist/types/mongodb.d.ts +0 -258
  603. package/dist/types/mongodb.d.ts.map +0 -1
  604. package/dist/types/mongodb.js +0 -5
  605. package/dist/types/mongodb.js.map +0 -1
  606. package/dist/types/objectid.d.ts +0 -130
  607. package/dist/types/objectid.d.ts.map +0 -1
  608. package/dist/types/objectid.js +0 -314
  609. package/dist/types/objectid.js.map +0 -1
  610. package/dist/types/rpc.d.ts +0 -313
  611. package/dist/types/rpc.d.ts.map +0 -1
  612. package/dist/types/rpc.js +0 -136
  613. package/dist/types/rpc.js.map +0 -1
  614. package/dist/types/vectorize.d.ts +0 -136
  615. package/dist/types/vectorize.d.ts.map +0 -1
  616. package/dist/types/vectorize.js +0 -8
  617. package/dist/types/vectorize.js.map +0 -1
  618. package/dist/utils/sql-safety.d.ts +0 -64
  619. package/dist/utils/sql-safety.d.ts.map +0 -1
  620. package/dist/utils/sql-safety.js +0 -112
  621. package/dist/utils/sql-safety.js.map +0 -1
  622. package/dist/validation/document-validator.d.ts +0 -195
  623. package/dist/validation/document-validator.d.ts.map +0 -1
  624. package/dist/validation/document-validator.js +0 -529
  625. package/dist/validation/document-validator.js.map +0 -1
  626. package/dist/vectorize/document-serializer.d.ts +0 -119
  627. package/dist/vectorize/document-serializer.d.ts.map +0 -1
  628. package/dist/vectorize/document-serializer.js +0 -320
  629. package/dist/vectorize/document-serializer.js.map +0 -1
  630. package/dist/wire/auth/index.d.ts +0 -5
  631. package/dist/wire/auth/index.d.ts.map +0 -1
  632. package/dist/wire/auth/index.js +0 -5
  633. package/dist/wire/auth/index.js.map +0 -1
  634. package/dist/wire/auth/scram.d.ts +0 -160
  635. package/dist/wire/auth/scram.d.ts.map +0 -1
  636. package/dist/wire/auth/scram.js +0 -425
  637. package/dist/wire/auth/scram.js.map +0 -1
  638. package/dist/wire/backend/interface.d.ts +0 -168
  639. package/dist/wire/backend/interface.d.ts.map +0 -1
  640. package/dist/wire/backend/interface.js +0 -10
  641. package/dist/wire/backend/interface.js.map +0 -1
  642. package/dist/wire/backend/local-sqlite.d.ts +0 -89
  643. package/dist/wire/backend/local-sqlite.d.ts.map +0 -1
  644. package/dist/wire/backend/local-sqlite.js +0 -1002
  645. package/dist/wire/backend/local-sqlite.js.map +0 -1
  646. package/dist/wire/backend/query-router.d.ts +0 -197
  647. package/dist/wire/backend/query-router.d.ts.map +0 -1
  648. package/dist/wire/backend/query-router.js +0 -590
  649. package/dist/wire/backend/query-router.js.map +0 -1
  650. package/dist/wire/backend/validation.d.ts +0 -26
  651. package/dist/wire/backend/validation.d.ts.map +0 -1
  652. package/dist/wire/backend/validation.js +0 -79
  653. package/dist/wire/backend/validation.js.map +0 -1
  654. package/dist/wire/backend/workers-proxy.d.ts +0 -95
  655. package/dist/wire/backend/workers-proxy.d.ts.map +0 -1
  656. package/dist/wire/backend/workers-proxy.js +0 -429
  657. package/dist/wire/backend/workers-proxy.js.map +0 -1
  658. package/dist/wire/commands/admin.d.ts +0 -49
  659. package/dist/wire/commands/admin.d.ts.map +0 -1
  660. package/dist/wire/commands/admin.js +0 -272
  661. package/dist/wire/commands/admin.js.map +0 -1
  662. package/dist/wire/commands/aggregate.d.ts +0 -15
  663. package/dist/wire/commands/aggregate.d.ts.map +0 -1
  664. package/dist/wire/commands/aggregate.js +0 -98
  665. package/dist/wire/commands/aggregate.js.map +0 -1
  666. package/dist/wire/commands/auth.d.ts +0 -58
  667. package/dist/wire/commands/auth.d.ts.map +0 -1
  668. package/dist/wire/commands/auth.js +0 -158
  669. package/dist/wire/commands/auth.js.map +0 -1
  670. package/dist/wire/commands/crud.d.ts +0 -49
  671. package/dist/wire/commands/crud.d.ts.map +0 -1
  672. package/dist/wire/commands/crud.js +0 -336
  673. package/dist/wire/commands/crud.js.map +0 -1
  674. package/dist/wire/commands/hello.d.ts +0 -35
  675. package/dist/wire/commands/hello.d.ts.map +0 -1
  676. package/dist/wire/commands/hello.js +0 -204
  677. package/dist/wire/commands/hello.js.map +0 -1
  678. package/dist/wire/commands/index.d.ts +0 -24
  679. package/dist/wire/commands/index.d.ts.map +0 -1
  680. package/dist/wire/commands/index.js +0 -145
  681. package/dist/wire/commands/index.js.map +0 -1
  682. package/dist/wire/commands/router.d.ts +0 -46
  683. package/dist/wire/commands/router.d.ts.map +0 -1
  684. package/dist/wire/commands/router.js +0 -151
  685. package/dist/wire/commands/router.js.map +0 -1
  686. package/dist/wire/commands/types.d.ts +0 -51
  687. package/dist/wire/commands/types.d.ts.map +0 -1
  688. package/dist/wire/commands/types.js +0 -15
  689. package/dist/wire/commands/types.js.map +0 -1
  690. package/dist/wire/index.d.ts +0 -15
  691. package/dist/wire/index.d.ts.map +0 -1
  692. package/dist/wire/index.js +0 -19
  693. package/dist/wire/index.js.map +0 -1
  694. package/dist/wire/message.d.ts +0 -49
  695. package/dist/wire/message.d.ts.map +0 -1
  696. package/dist/wire/message.js +0 -299
  697. package/dist/wire/message.js.map +0 -1
  698. package/dist/wire/server.d.ts +0 -145
  699. package/dist/wire/server.d.ts.map +0 -1
  700. package/dist/wire/server.js +0 -284
  701. package/dist/wire/server.js.map +0 -1
  702. package/dist/wire/types.d.ts +0 -140
  703. package/dist/wire/types.d.ts.map +0 -1
  704. package/dist/wire/types.js +0 -64
  705. package/dist/wire/types.js.map +0 -1
  706. package/dist/worker.d.ts.map +0 -1
@@ -1,1641 +0,0 @@
1
- /**
2
- * MongoCollection - MongoDB-compatible collection interface
3
- *
4
- * Provides CRUD operations and query support for documents.
5
- * This is the client-side in-memory implementation for testing.
6
- */
7
- import { ObjectId } from '../types/objectid';
8
- import { FindCursor } from './cursor';
9
- import { BulkWriteException, isInsertOneModel, isUpdateOneModel, isUpdateManyModel, isReplaceOneModel, isDeleteOneModel, isDeleteManyModel, } from './bulk-write';
10
- import { ChangeStream, ChangeEventStore, } from './change-stream';
11
- import { AggregationCursor, } from './aggregation-cursor';
12
- /**
13
- * MongoCollection provides CRUD operations for documents
14
- */
15
- export class MongoCollection {
16
- database;
17
- _collectionName;
18
- documents = new Map();
19
- _changeEventStore = new ChangeEventStore();
20
- _activeChangeStreams = new Set();
21
- constructor(database, name) {
22
- this.database = database;
23
- this._collectionName = name;
24
- }
25
- /**
26
- * Get the collection name
27
- */
28
- get collectionName() {
29
- return this._collectionName;
30
- }
31
- /**
32
- * Ensure collection is created in the database
33
- * @internal
34
- */
35
- async _ensureCreated() {
36
- this.database._registerCollection(this._collectionName);
37
- }
38
- /**
39
- * Drop collection data
40
- * @internal
41
- */
42
- async _drop() {
43
- this.documents.clear();
44
- }
45
- /**
46
- * Get a unique key for this collection (used for transaction tracking)
47
- * @internal
48
- */
49
- _getCollectionKey() {
50
- return `${this.database.databaseName}.${this._collectionName}`;
51
- }
52
- /**
53
- * Create a snapshot of the current collection data
54
- * @internal
55
- */
56
- _createSnapshot() {
57
- const snapshot = new Map();
58
- for (const [key, doc] of this.documents) {
59
- // Deep clone the document
60
- snapshot.set(key, JSON.parse(JSON.stringify(doc)));
61
- }
62
- return snapshot;
63
- }
64
- /**
65
- * Restore collection data from a snapshot (used for transaction rollback)
66
- * @internal
67
- */
68
- _restoreFromSnapshot(snapshot) {
69
- this.documents.clear();
70
- for (const [key, doc] of snapshot) {
71
- // Reconstruct ObjectId for _id field
72
- const restoredDoc = { ...doc };
73
- if (doc._id && typeof doc._id === 'object' && '_hexString' in doc._id) {
74
- restoredDoc._id = new ObjectId(doc._id._hexString);
75
- }
76
- this.documents.set(key, restoredDoc);
77
- }
78
- }
79
- /**
80
- * Track this collection in a session for transaction support
81
- * @internal
82
- */
83
- _trackInSession(session) {
84
- if (session && session.inTransaction) {
85
- session._trackCollection(this);
86
- session._markInProgress();
87
- }
88
- }
89
- /**
90
- * Insert a single document
91
- */
92
- async insertOne(doc, options) {
93
- await this._ensureCreated();
94
- // Track collection in session for transaction rollback support
95
- this._trackInSession(options?.session);
96
- // Generate _id if not provided
97
- const docWithId = { ...doc };
98
- if (!docWithId._id) {
99
- docWithId._id = new ObjectId();
100
- }
101
- else if (typeof docWithId._id === 'string') {
102
- docWithId._id = new ObjectId(docWithId._id);
103
- }
104
- // Check for duplicate _id
105
- const idHex = docWithId._id.toHexString();
106
- if (this.documents.has(idHex)) {
107
- const error = new Error(`E11000 duplicate key error collection: ${this._collectionName} dup key: { _id: "${idHex}" }`);
108
- error.code = 11000;
109
- throw error;
110
- }
111
- // Store document
112
- this.documents.set(idHex, docWithId);
113
- // Emit insert change event
114
- this._changeEventStore.addEvent({
115
- operationType: 'insert',
116
- documentId: docWithId._id,
117
- fullDocument: docWithId,
118
- });
119
- return {
120
- acknowledged: true,
121
- insertedId: docWithId._id,
122
- };
123
- }
124
- /**
125
- * Insert multiple documents
126
- */
127
- async insertMany(docs, options) {
128
- await this._ensureCreated();
129
- // Track collection in session for transaction rollback support
130
- this._trackInSession(options?.session);
131
- const insertedIds = {};
132
- for (let i = 0; i < docs.length; i++) {
133
- const doc = docs[i];
134
- if (doc === undefined)
135
- continue;
136
- const result = await this.insertOne(doc, options);
137
- insertedIds[i] = result.insertedId;
138
- }
139
- return {
140
- acknowledged: true,
141
- insertedCount: docs.length,
142
- insertedIds,
143
- };
144
- }
145
- /**
146
- * Find a single document
147
- */
148
- async findOne(filter = {}, options) {
149
- const docs = this._findDocuments(filter);
150
- if (docs.length === 0) {
151
- return null;
152
- }
153
- const doc = docs[0];
154
- if (doc === undefined) {
155
- return null;
156
- }
157
- return options?.projection ? this._applyProjection(doc, options.projection) : doc;
158
- }
159
- /**
160
- * Find multiple documents, returns a cursor
161
- */
162
- find(filter = {}, options) {
163
- // Convert to a clean object to avoid exactOptionalPropertyTypes issues
164
- const cursorOptions = options ? {
165
- ...(options.projection !== undefined && { projection: options.projection }),
166
- ...(options.sort !== undefined && { sort: options.sort }),
167
- ...(options.limit !== undefined && { limit: options.limit }),
168
- ...(options.skip !== undefined && { skip: options.skip }),
169
- } : undefined;
170
- return new FindCursor(this, filter, cursorOptions);
171
- }
172
- /**
173
- * Internal method to execute find query
174
- * @internal
175
- */
176
- _findDocuments(filter, options) {
177
- let results = [];
178
- // Get all documents and filter
179
- for (const doc of this.documents.values()) {
180
- if (this._matchesFilter(doc, filter)) {
181
- results.push({ ...doc });
182
- }
183
- }
184
- // Apply sort
185
- if (options?.sort) {
186
- results = this._sortDocuments(results, options.sort);
187
- }
188
- // Apply skip
189
- if (options?.skip && options.skip > 0) {
190
- results = results.slice(options.skip);
191
- }
192
- // Apply limit
193
- if (options?.limit && options.limit > 0) {
194
- results = results.slice(0, options.limit);
195
- }
196
- return results;
197
- }
198
- /**
199
- * Update a single document
200
- */
201
- async updateOne(filter, update, options) {
202
- // Track collection in session for transaction rollback support
203
- this._trackInSession(options?.session);
204
- const docs = this._findDocuments(filter);
205
- if (docs.length === 0) {
206
- // Handle upsert
207
- if (options?.upsert) {
208
- const newDoc = this._applyUpdate({}, update, filter);
209
- const result = await this.insertOne(newDoc, options);
210
- return {
211
- acknowledged: true,
212
- matchedCount: 0,
213
- modifiedCount: 0,
214
- upsertedId: result.insertedId,
215
- upsertedCount: 1,
216
- };
217
- }
218
- return {
219
- acknowledged: true,
220
- matchedCount: 0,
221
- modifiedCount: 0,
222
- };
223
- }
224
- // Update first matching document
225
- const doc = docs[0];
226
- if (doc === undefined) {
227
- return {
228
- acknowledged: true,
229
- matchedCount: 0,
230
- modifiedCount: 0,
231
- };
232
- }
233
- const updatedDoc = this._applyUpdate(doc, update);
234
- this.documents.set(doc._id.toHexString(), updatedDoc);
235
- // Emit update change event
236
- const { updatedFields, removedFields } = this._extractUpdateChanges(update);
237
- this._changeEventStore.addEvent({
238
- operationType: 'update',
239
- documentId: doc._id,
240
- updatedFields,
241
- removedFields,
242
- });
243
- return {
244
- acknowledged: true,
245
- matchedCount: 1,
246
- modifiedCount: 1,
247
- };
248
- }
249
- /**
250
- * Update multiple documents
251
- */
252
- async updateMany(filter, update, options) {
253
- // Track collection in session for transaction rollback support
254
- this._trackInSession(options?.session);
255
- const docs = this._findDocuments(filter);
256
- if (docs.length === 0) {
257
- if (options?.upsert) {
258
- const newDoc = this._applyUpdate({}, update, filter);
259
- const result = await this.insertOne(newDoc, options);
260
- return {
261
- acknowledged: true,
262
- matchedCount: 0,
263
- modifiedCount: 0,
264
- upsertedId: result.insertedId,
265
- upsertedCount: 1,
266
- };
267
- }
268
- return {
269
- acknowledged: true,
270
- matchedCount: 0,
271
- modifiedCount: 0,
272
- };
273
- }
274
- // Update all matching documents
275
- const { updatedFields, removedFields } = this._extractUpdateChanges(update);
276
- for (const doc of docs) {
277
- const updatedDoc = this._applyUpdate(doc, update);
278
- this.documents.set(doc._id.toHexString(), updatedDoc);
279
- // Emit update change event for each document
280
- this._changeEventStore.addEvent({
281
- operationType: 'update',
282
- documentId: doc._id,
283
- updatedFields,
284
- removedFields,
285
- });
286
- }
287
- return {
288
- acknowledged: true,
289
- matchedCount: docs.length,
290
- modifiedCount: docs.length,
291
- };
292
- }
293
- /**
294
- * Replace a single document
295
- */
296
- async replaceOne(filter, replacement, options) {
297
- // Track collection in session for transaction rollback support
298
- this._trackInSession(options?.session);
299
- const docs = this._findDocuments(filter);
300
- if (docs.length === 0) {
301
- if (options?.upsert) {
302
- const result = await this.insertOne(replacement, options);
303
- return {
304
- acknowledged: true,
305
- matchedCount: 0,
306
- modifiedCount: 0,
307
- upsertedId: result.insertedId,
308
- upsertedCount: 1,
309
- };
310
- }
311
- return {
312
- acknowledged: true,
313
- matchedCount: 0,
314
- modifiedCount: 0,
315
- };
316
- }
317
- // Replace first matching document, preserving _id
318
- const doc = docs[0];
319
- if (doc === undefined) {
320
- return {
321
- acknowledged: true,
322
- matchedCount: 0,
323
- modifiedCount: 0,
324
- };
325
- }
326
- const replacedDoc = { ...replacement, _id: doc._id };
327
- this.documents.set(doc._id.toHexString(), replacedDoc);
328
- // Emit replace change event
329
- this._changeEventStore.addEvent({
330
- operationType: 'replace',
331
- documentId: doc._id,
332
- fullDocument: replacedDoc,
333
- });
334
- return {
335
- acknowledged: true,
336
- matchedCount: 1,
337
- modifiedCount: 1,
338
- };
339
- }
340
- /**
341
- * Delete a single document
342
- */
343
- async deleteOne(filter, options) {
344
- // Track collection in session for transaction rollback support
345
- this._trackInSession(options?.session);
346
- const docs = this._findDocuments(filter);
347
- if (docs.length === 0) {
348
- return {
349
- acknowledged: true,
350
- deletedCount: 0,
351
- };
352
- }
353
- // Delete first matching document
354
- const firstDoc = docs[0];
355
- if (firstDoc === undefined) {
356
- return {
357
- acknowledged: true,
358
- deletedCount: 0,
359
- };
360
- }
361
- const docId = firstDoc._id;
362
- this.documents.delete(docId.toHexString());
363
- // Emit delete change event
364
- this._changeEventStore.addEvent({
365
- operationType: 'delete',
366
- documentId: docId,
367
- });
368
- return {
369
- acknowledged: true,
370
- deletedCount: 1,
371
- };
372
- }
373
- /**
374
- * Delete multiple documents
375
- */
376
- async deleteMany(filter, options) {
377
- // Track collection in session for transaction rollback support
378
- this._trackInSession(options?.session);
379
- const docs = this._findDocuments(filter);
380
- // Delete all matching documents
381
- for (const doc of docs) {
382
- this.documents.delete(doc._id.toHexString());
383
- // Emit delete change event
384
- this._changeEventStore.addEvent({
385
- operationType: 'delete',
386
- documentId: doc._id,
387
- });
388
- }
389
- return {
390
- acknowledged: true,
391
- deletedCount: docs.length,
392
- };
393
- }
394
- /**
395
- * Count documents matching filter
396
- */
397
- async countDocuments(filter = {}) {
398
- const docs = this._findDocuments(filter);
399
- return docs.length;
400
- }
401
- /**
402
- * Find one and update
403
- */
404
- async findOneAndUpdate(filter, update, options) {
405
- const docs = this._findDocuments(filter, {
406
- ...(options?.sort !== undefined && { sort: options.sort })
407
- });
408
- if (docs.length === 0) {
409
- if (options?.upsert) {
410
- const newDoc = this._applyUpdate({}, update, filter);
411
- await this.insertOne(newDoc);
412
- if (options?.returnDocument === 'after') {
413
- return this.findOne(filter, {
414
- ...(options?.projection !== undefined && { projection: options.projection })
415
- });
416
- }
417
- return null;
418
- }
419
- return null;
420
- }
421
- const doc = docs[0];
422
- if (doc === undefined) {
423
- return null;
424
- }
425
- const originalDoc = { ...doc };
426
- // Update the document
427
- const updatedDoc = this._applyUpdate(doc, update);
428
- this.documents.set(doc._id.toHexString(), updatedDoc);
429
- // Return before or after based on options
430
- const result = options?.returnDocument === 'after' ? updatedDoc : originalDoc;
431
- return options?.projection ? this._applyProjection(result, options.projection) : result;
432
- }
433
- /**
434
- * Find one and delete
435
- */
436
- async findOneAndDelete(filter, options) {
437
- const docs = this._findDocuments(filter, {
438
- ...(options?.sort !== undefined && { sort: options.sort })
439
- });
440
- if (docs.length === 0) {
441
- return null;
442
- }
443
- const doc = docs[0];
444
- if (doc === undefined) {
445
- return null;
446
- }
447
- this.documents.delete(doc._id.toHexString());
448
- return options?.projection ? this._applyProjection(doc, options.projection) : doc;
449
- }
450
- /**
451
- * Find one and replace
452
- */
453
- async findOneAndReplace(filter, replacement, options) {
454
- const docs = this._findDocuments(filter, {
455
- ...(options?.sort !== undefined && { sort: options.sort })
456
- });
457
- if (docs.length === 0) {
458
- if (options?.upsert) {
459
- await this.insertOne(replacement);
460
- if (options?.returnDocument === 'after') {
461
- return this.findOne(filter, {
462
- ...(options?.projection !== undefined && { projection: options.projection })
463
- });
464
- }
465
- return null;
466
- }
467
- return null;
468
- }
469
- const doc = docs[0];
470
- if (doc === undefined) {
471
- return null;
472
- }
473
- const originalDoc = { ...doc };
474
- // Replace the document, preserving _id
475
- const replacedDoc = { ...replacement, _id: doc._id };
476
- this.documents.set(doc._id.toHexString(), replacedDoc);
477
- // Return before or after based on options
478
- const result = options?.returnDocument === 'after' ? replacedDoc : originalDoc;
479
- return options?.projection ? this._applyProjection(result, options.projection) : result;
480
- }
481
- /**
482
- * Execute multiple write operations in a single batch
483
- *
484
- * @param operations - Array of bulk write operations
485
- * @param options - Bulk write options
486
- * @returns BulkWriteResult with operation counts
487
- */
488
- async bulkWrite(operations, options = {}) {
489
- const ordered = options.ordered !== false; // Default to true
490
- // Initialize result
491
- const result = {
492
- acknowledged: true,
493
- insertedCount: 0,
494
- matchedCount: 0,
495
- modifiedCount: 0,
496
- deletedCount: 0,
497
- upsertedCount: 0,
498
- insertedIds: {},
499
- upsertedIds: {},
500
- };
501
- const writeErrors = [];
502
- // Process operations
503
- for (let i = 0; i < operations.length; i++) {
504
- const op = operations[i];
505
- if (op === undefined)
506
- continue;
507
- try {
508
- if (isInsertOneModel(op)) {
509
- const insertResult = await this.insertOne(op.insertOne.document);
510
- result.insertedCount++;
511
- result.insertedIds[i] = insertResult.insertedId;
512
- }
513
- else if (isUpdateOneModel(op)) {
514
- const updateResult = await this.updateOne(op.updateOne.filter, op.updateOne.update, {
515
- ...(op.updateOne.upsert !== undefined && { upsert: op.updateOne.upsert }),
516
- ...(op.updateOne.arrayFilters !== undefined && { arrayFilters: op.updateOne.arrayFilters })
517
- });
518
- result.matchedCount += updateResult.matchedCount;
519
- result.modifiedCount += updateResult.modifiedCount;
520
- if (updateResult.upsertedId) {
521
- result.upsertedCount++;
522
- result.upsertedIds[i] = updateResult.upsertedId;
523
- }
524
- }
525
- else if (isUpdateManyModel(op)) {
526
- const updateResult = await this.updateMany(op.updateMany.filter, op.updateMany.update, {
527
- ...(op.updateMany.upsert !== undefined && { upsert: op.updateMany.upsert }),
528
- ...(op.updateMany.arrayFilters !== undefined && { arrayFilters: op.updateMany.arrayFilters })
529
- });
530
- result.matchedCount += updateResult.matchedCount;
531
- result.modifiedCount += updateResult.modifiedCount;
532
- if (updateResult.upsertedId) {
533
- result.upsertedCount++;
534
- result.upsertedIds[i] = updateResult.upsertedId;
535
- }
536
- }
537
- else if (isReplaceOneModel(op)) {
538
- const replaceResult = await this.replaceOne(op.replaceOne.filter, op.replaceOne.replacement, {
539
- ...(op.replaceOne.upsert !== undefined && { upsert: op.replaceOne.upsert })
540
- });
541
- result.matchedCount += replaceResult.matchedCount;
542
- result.modifiedCount += replaceResult.modifiedCount;
543
- if (replaceResult.upsertedId) {
544
- result.upsertedCount++;
545
- result.upsertedIds[i] = replaceResult.upsertedId;
546
- }
547
- }
548
- else if (isDeleteOneModel(op)) {
549
- const deleteResult = await this.deleteOne(op.deleteOne.filter);
550
- result.deletedCount += deleteResult.deletedCount;
551
- }
552
- else if (isDeleteManyModel(op)) {
553
- const deleteResult = await this.deleteMany(op.deleteMany.filter);
554
- result.deletedCount += deleteResult.deletedCount;
555
- }
556
- }
557
- catch (error) {
558
- const bulkError = {
559
- index: i,
560
- code: 11000, // Default to duplicate key error code
561
- errmsg: error instanceof Error ? error.message : String(error),
562
- op,
563
- };
564
- writeErrors.push(bulkError);
565
- // For ordered operations, stop on first error
566
- if (ordered) {
567
- throw new BulkWriteException(`BulkWrite operation failed: ${bulkError.errmsg}`, result, writeErrors);
568
- }
569
- // For unordered, continue processing remaining operations
570
- }
571
- }
572
- // If there were errors in unordered mode, throw exception with partial results
573
- if (writeErrors.length > 0) {
574
- throw new BulkWriteException(`BulkWrite operation completed with ${writeErrors.length} error(s)`, result, writeErrors);
575
- }
576
- return result;
577
- }
578
- /**
579
- * Drop the collection
580
- */
581
- async drop() {
582
- this.documents.clear();
583
- return true;
584
- }
585
- /**
586
- * Watch for changes on this collection
587
- *
588
- * Creates a change stream that emits events for insert, update, replace, and delete operations.
589
- *
590
- * @param pipeline - Optional aggregation pipeline for filtering events (supports $match)
591
- * @param options - Change stream options
592
- * @returns A ChangeStream instance
593
- *
594
- * @example
595
- * ```typescript
596
- * const changeStream = collection.watch([
597
- * { $match: { operationType: 'insert' } }
598
- * ])
599
- *
600
- * for await (const event of changeStream) {
601
- * console.log('Change:', event.operationType, event.fullDocument)
602
- * }
603
- * ```
604
- */
605
- watch(pipeline = [], options = {}) {
606
- const changeStream = new ChangeStream(this.database.databaseName, this._collectionName, pipeline, options, {
607
- getDocumentById: async (id) => {
608
- const doc = this.documents.get(id.toHexString());
609
- return doc || null;
610
- },
611
- getChangeEvents: async (afterSequence) => {
612
- return this._changeEventStore.getEventsAfter(afterSequence);
613
- },
614
- getCurrentSequence: () => {
615
- return this._changeEventStore.getCurrentSequence();
616
- },
617
- onClose: () => {
618
- this._activeChangeStreams.delete(changeStream);
619
- },
620
- });
621
- this._activeChangeStreams.add(changeStream);
622
- return changeStream;
623
- }
624
- /**
625
- * Check if a document matches a filter
626
- * @internal
627
- */
628
- _matchesFilter(doc, filter) {
629
- const filterObj = filter;
630
- for (const [key, value] of Object.entries(filterObj)) {
631
- // Handle logical operators
632
- if (key === '$and') {
633
- const conditions = value;
634
- if (!conditions.every(cond => this._matchesFilter(doc, cond))) {
635
- return false;
636
- }
637
- continue;
638
- }
639
- if (key === '$or') {
640
- const conditions = value;
641
- if (!conditions.some(cond => this._matchesFilter(doc, cond))) {
642
- return false;
643
- }
644
- continue;
645
- }
646
- if (key === '$nor') {
647
- const conditions = value;
648
- if (conditions.some(cond => this._matchesFilter(doc, cond))) {
649
- return false;
650
- }
651
- continue;
652
- }
653
- // Get document value for comparison
654
- const docValue = this._getNestedValue(doc, key);
655
- // Handle operator objects
656
- if (value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof ObjectId)) {
657
- if (!this._matchesOperators(docValue, value)) {
658
- return false;
659
- }
660
- continue;
661
- }
662
- // Direct comparison
663
- if (!this._valuesEqual(docValue, value)) {
664
- return false;
665
- }
666
- }
667
- return true;
668
- }
669
- /**
670
- * Check if a value matches operator conditions
671
- */
672
- _matchesOperators(docValue, operators) {
673
- for (const [op, opValue] of Object.entries(operators)) {
674
- switch (op) {
675
- case '$eq':
676
- if (!this._valuesEqual(docValue, opValue))
677
- return false;
678
- break;
679
- case '$ne':
680
- if (this._valuesEqual(docValue, opValue))
681
- return false;
682
- break;
683
- case '$gt':
684
- if (typeof docValue !== 'number' || docValue <= opValue)
685
- return false;
686
- break;
687
- case '$gte':
688
- if (typeof docValue !== 'number' || docValue < opValue)
689
- return false;
690
- break;
691
- case '$lt':
692
- if (typeof docValue !== 'number' || docValue >= opValue)
693
- return false;
694
- break;
695
- case '$lte':
696
- if (typeof docValue !== 'number' || docValue > opValue)
697
- return false;
698
- break;
699
- case '$in':
700
- const inArray = opValue;
701
- if (!inArray.some(v => this._valuesEqual(docValue, v)))
702
- return false;
703
- break;
704
- case '$nin':
705
- const ninArray = opValue;
706
- if (ninArray.some(v => this._valuesEqual(docValue, v)))
707
- return false;
708
- break;
709
- case '$exists':
710
- const exists = docValue !== undefined;
711
- if (opValue !== exists)
712
- return false;
713
- break;
714
- case '$not':
715
- if (this._matchesOperators(docValue, opValue))
716
- return false;
717
- break;
718
- case '$regex':
719
- const regex = new RegExp(opValue);
720
- if (typeof docValue !== 'string' || !regex.test(docValue))
721
- return false;
722
- break;
723
- case '$type':
724
- if (typeof docValue !== opValue)
725
- return false;
726
- break;
727
- case '$elemMatch':
728
- if (!Array.isArray(docValue))
729
- return false;
730
- if (!docValue.some(elem => this._matchesFilter(elem, opValue)))
731
- return false;
732
- break;
733
- case '$size':
734
- if (!Array.isArray(docValue) || docValue.length !== opValue)
735
- return false;
736
- break;
737
- case '$all':
738
- if (!Array.isArray(docValue))
739
- return false;
740
- const allValues = opValue;
741
- if (!allValues.every(v => docValue.some(dv => this._valuesEqual(dv, v))))
742
- return false;
743
- break;
744
- }
745
- }
746
- return true;
747
- }
748
- /**
749
- * Compare two values for equality
750
- */
751
- _valuesEqual(a, b) {
752
- if (a instanceof ObjectId && b instanceof ObjectId) {
753
- return a.equals(b);
754
- }
755
- if (a instanceof ObjectId && typeof b === 'string') {
756
- return a.equals(b);
757
- }
758
- if (typeof a === 'string' && b instanceof ObjectId) {
759
- return b.equals(a);
760
- }
761
- if (Array.isArray(a) && Array.isArray(b)) {
762
- if (a.length !== b.length)
763
- return false;
764
- return a.every((val, idx) => this._valuesEqual(val, b[idx]));
765
- }
766
- if (a !== null && b !== null && typeof a === 'object' && typeof b === 'object') {
767
- const keysA = Object.keys(a);
768
- const keysB = Object.keys(b);
769
- if (keysA.length !== keysB.length)
770
- return false;
771
- return keysA.every(key => this._valuesEqual(a[key], b[key]));
772
- }
773
- return a === b;
774
- }
775
- /**
776
- * Get nested value from document using dot notation
777
- */
778
- _getNestedValue(doc, path) {
779
- const parts = path.split('.');
780
- let current = doc;
781
- for (const part of parts) {
782
- if (current === null || current === undefined) {
783
- return undefined;
784
- }
785
- current = current[part];
786
- }
787
- return current;
788
- }
789
- /**
790
- * Apply update operators to a document
791
- */
792
- _applyUpdate(doc, update, filter) {
793
- const updateObj = update;
794
- const result = { ...doc };
795
- // Preserve or generate _id
796
- if (!result._id) {
797
- result._id = new ObjectId();
798
- }
799
- // Apply filter fields for upsert
800
- if (filter) {
801
- const filterObj = filter;
802
- for (const [key, value] of Object.entries(filterObj)) {
803
- if (!key.startsWith('$') && typeof value !== 'object') {
804
- result[key] = value;
805
- }
806
- }
807
- }
808
- // Apply update operators
809
- for (const [op, fields] of Object.entries(updateObj)) {
810
- switch (op) {
811
- case '$set':
812
- for (const [key, value] of Object.entries(fields)) {
813
- this._setNestedValue(result, key, value);
814
- }
815
- break;
816
- case '$unset':
817
- for (const key of Object.keys(fields)) {
818
- this._deleteNestedValue(result, key);
819
- }
820
- break;
821
- case '$inc':
822
- for (const [key, value] of Object.entries(fields)) {
823
- const current = this._getNestedValue(result, key);
824
- const newValue = (typeof current === 'number' ? current : 0) + value;
825
- this._setNestedValue(result, key, newValue);
826
- }
827
- break;
828
- case '$mul':
829
- for (const [key, value] of Object.entries(fields)) {
830
- const current = this._getNestedValue(result, key);
831
- const newValue = (typeof current === 'number' ? current : 0) * value;
832
- this._setNestedValue(result, key, newValue);
833
- }
834
- break;
835
- case '$min':
836
- for (const [key, value] of Object.entries(fields)) {
837
- const current = this._getNestedValue(result, key);
838
- if (current === undefined || value < current) {
839
- this._setNestedValue(result, key, value);
840
- }
841
- }
842
- break;
843
- case '$max':
844
- for (const [key, value] of Object.entries(fields)) {
845
- const current = this._getNestedValue(result, key);
846
- if (current === undefined || value > current) {
847
- this._setNestedValue(result, key, value);
848
- }
849
- }
850
- break;
851
- case '$rename':
852
- for (const [oldKey, newKey] of Object.entries(fields)) {
853
- const value = this._getNestedValue(result, oldKey);
854
- this._deleteNestedValue(result, oldKey);
855
- this._setNestedValue(result, newKey, value);
856
- }
857
- break;
858
- case '$push':
859
- for (const [key, value] of Object.entries(fields)) {
860
- const current = this._getNestedValue(result, key);
861
- const array = Array.isArray(current) ? [...current] : [];
862
- if (typeof value === 'object' && value !== null && '$each' in value) {
863
- const eachValue = value;
864
- array.push(...eachValue.$each);
865
- }
866
- else {
867
- array.push(value);
868
- }
869
- this._setNestedValue(result, key, array);
870
- }
871
- break;
872
- case '$pull':
873
- for (const [key, value] of Object.entries(fields)) {
874
- const current = this._getNestedValue(result, key);
875
- if (Array.isArray(current)) {
876
- const newArray = current.filter(item => !this._valuesEqual(item, value));
877
- this._setNestedValue(result, key, newArray);
878
- }
879
- }
880
- break;
881
- case '$pop':
882
- for (const [key, value] of Object.entries(fields)) {
883
- const current = this._getNestedValue(result, key);
884
- if (Array.isArray(current)) {
885
- const newArray = [...current];
886
- if (value === 1) {
887
- newArray.pop();
888
- }
889
- else if (value === -1) {
890
- newArray.shift();
891
- }
892
- this._setNestedValue(result, key, newArray);
893
- }
894
- }
895
- break;
896
- case '$addToSet':
897
- for (const [key, value] of Object.entries(fields)) {
898
- const current = this._getNestedValue(result, key);
899
- const array = Array.isArray(current) ? [...current] : [];
900
- if (typeof value === 'object' && value !== null && '$each' in value) {
901
- const eachValue = value;
902
- for (const item of eachValue.$each) {
903
- if (!array.some(existing => this._valuesEqual(existing, item))) {
904
- array.push(item);
905
- }
906
- }
907
- }
908
- else if (!array.some(existing => this._valuesEqual(existing, value))) {
909
- array.push(value);
910
- }
911
- this._setNestedValue(result, key, array);
912
- }
913
- break;
914
- case '$currentDate':
915
- for (const [key, value] of Object.entries(fields)) {
916
- if (value === true || (typeof value === 'object' && value.$type === 'date')) {
917
- this._setNestedValue(result, key, new Date());
918
- }
919
- else if (typeof value === 'object' && value.$type === 'timestamp') {
920
- this._setNestedValue(result, key, Date.now());
921
- }
922
- }
923
- break;
924
- }
925
- }
926
- return result;
927
- }
928
- /**
929
- * Set a nested value in an object
930
- */
931
- _setNestedValue(obj, path, value) {
932
- const parts = path.split('.');
933
- let current = obj;
934
- for (let i = 0; i < parts.length - 1; i++) {
935
- const part = parts[i];
936
- if (part === undefined)
937
- continue;
938
- if (current[part] === undefined || current[part] === null) {
939
- current[part] = {};
940
- }
941
- current = current[part];
942
- }
943
- const lastPart = parts[parts.length - 1];
944
- if (lastPart !== undefined) {
945
- current[lastPart] = value;
946
- }
947
- }
948
- /**
949
- * Delete a nested value from an object
950
- */
951
- _deleteNestedValue(obj, path) {
952
- const parts = path.split('.');
953
- let current = obj;
954
- for (let i = 0; i < parts.length - 1; i++) {
955
- const part = parts[i];
956
- if (part === undefined)
957
- continue;
958
- if (current[part] === undefined || current[part] === null) {
959
- return;
960
- }
961
- current = current[part];
962
- }
963
- const lastPart = parts[parts.length - 1];
964
- if (lastPart !== undefined) {
965
- delete current[lastPart];
966
- }
967
- }
968
- /**
969
- * Sort documents by the given sort specification
970
- */
971
- _sortDocuments(docs, sort) {
972
- return [...docs].sort((a, b) => {
973
- for (const [key, direction] of Object.entries(sort)) {
974
- const aValue = this._getNestedValue(a, key);
975
- const bValue = this._getNestedValue(b, key);
976
- let comparison = 0;
977
- if (aValue === bValue) {
978
- comparison = 0;
979
- }
980
- else if (aValue === null || aValue === undefined) {
981
- comparison = -1;
982
- }
983
- else if (bValue === null || bValue === undefined) {
984
- comparison = 1;
985
- }
986
- else if (typeof aValue === 'string' && typeof bValue === 'string') {
987
- comparison = aValue.localeCompare(bValue);
988
- }
989
- else if (typeof aValue === 'number' && typeof bValue === 'number') {
990
- comparison = aValue - bValue;
991
- }
992
- else {
993
- comparison = String(aValue).localeCompare(String(bValue));
994
- }
995
- if (comparison !== 0) {
996
- return comparison * direction;
997
- }
998
- }
999
- return 0;
1000
- });
1001
- }
1002
- /**
1003
- * Apply projection to a document
1004
- * @internal
1005
- */
1006
- _applyProjection(doc, projection) {
1007
- const hasInclusions = Object.values(projection).some(v => v === 1);
1008
- const hasExclusions = Object.values(projection).some(v => v === 0);
1009
- // Cannot mix inclusions and exclusions (except for _id)
1010
- if (hasInclusions) {
1011
- const result = {};
1012
- // Always include _id unless explicitly excluded
1013
- if (projection._id !== 0) {
1014
- result._id = doc._id;
1015
- }
1016
- for (const [key, value] of Object.entries(projection)) {
1017
- if (value === 1 && key !== '_id') {
1018
- result[key] = this._getNestedValue(doc, key);
1019
- }
1020
- }
1021
- return result;
1022
- }
1023
- else if (hasExclusions) {
1024
- const result = { ...doc };
1025
- for (const [key, value] of Object.entries(projection)) {
1026
- if (value === 0) {
1027
- delete result[key];
1028
- }
1029
- }
1030
- return result;
1031
- }
1032
- return doc;
1033
- }
1034
- /**
1035
- * Extract updated and removed fields from an update object
1036
- * @internal
1037
- */
1038
- _extractUpdateChanges(update) {
1039
- const updateObj = update;
1040
- const updatedFields = {};
1041
- const removedFields = [];
1042
- // Extract fields from $set
1043
- if (updateObj.$set) {
1044
- Object.assign(updatedFields, updateObj.$set);
1045
- }
1046
- // Extract fields from $unset
1047
- if (updateObj.$unset) {
1048
- removedFields.push(...Object.keys(updateObj.$unset));
1049
- }
1050
- // Extract fields from $inc, $mul, $min, $max (these set values)
1051
- for (const op of ['$inc', '$mul', '$min', '$max']) {
1052
- if (updateObj[op]) {
1053
- for (const key of Object.keys(updateObj[op])) {
1054
- updatedFields[key] = updateObj[op][key];
1055
- }
1056
- }
1057
- }
1058
- // Handle $push (updated fields)
1059
- if (updateObj.$push) {
1060
- for (const key of Object.keys(updateObj.$push)) {
1061
- updatedFields[key] = updateObj.$push[key];
1062
- }
1063
- }
1064
- // Handle $pull (updated fields)
1065
- if (updateObj.$pull) {
1066
- for (const key of Object.keys(updateObj.$pull)) {
1067
- updatedFields[key] = updateObj.$pull[key];
1068
- }
1069
- }
1070
- // Handle $addToSet (updated fields)
1071
- if (updateObj.$addToSet) {
1072
- for (const key of Object.keys(updateObj.$addToSet)) {
1073
- updatedFields[key] = updateObj.$addToSet[key];
1074
- }
1075
- }
1076
- return { updatedFields, removedFields };
1077
- }
1078
- /**
1079
- * Execute an aggregation pipeline on the collection
1080
- *
1081
- * Returns an AggregationCursor that supports:
1082
- * - Async iteration with `for await (const doc of cursor)`
1083
- * - Converting to array with `await cursor.toArray()`
1084
- * - forEach iteration with `await cursor.forEach(callback)`
1085
- *
1086
- * Supports async stages like $function and $lookup with pipeline.
1087
- *
1088
- * @param pipeline - Array of aggregation pipeline stages
1089
- * @param options - Aggregation options
1090
- * @returns AggregationCursor for iterating over results
1091
- *
1092
- * @example
1093
- * ```typescript
1094
- * // Using toArray
1095
- * const results = await collection.aggregate([
1096
- * { $match: { status: 'active' } },
1097
- * { $group: { _id: '$category', count: { $sum: 1 } } }
1098
- * ]).toArray()
1099
- *
1100
- * // Using async iterator
1101
- * for await (const doc of collection.aggregate([
1102
- * { $match: { status: 'active' } }
1103
- * ])) {
1104
- * console.log(doc)
1105
- * }
1106
- * ```
1107
- */
1108
- aggregate(pipeline, options = {}) {
1109
- // Create execution context for async stages
1110
- const context = {
1111
- collectionName: this._collectionName,
1112
- lookupCollection: async (name) => {
1113
- // Get documents from another collection for $lookup
1114
- const targetCollection = this.database.collection(name);
1115
- return targetCollection._findDocuments({});
1116
- },
1117
- functionExecutor: async (fn, doc) => {
1118
- // Execute $function stage
1119
- return this._executeFunctionStage(fn, doc);
1120
- }
1121
- };
1122
- // Create fetch function that executes the pipeline
1123
- const fetchFn = async () => {
1124
- // Get all documents from collection
1125
- const allDocs = this._findDocuments({});
1126
- // Execute pipeline stages
1127
- return this._executeAggregationPipeline(allDocs, pipeline);
1128
- };
1129
- return new AggregationCursor(pipeline, fetchFn, options, undefined, // No custom async executor - we handle in fetch
1130
- context);
1131
- }
1132
- /**
1133
- * Execute $function stage on a document
1134
- * @internal
1135
- */
1136
- async _executeFunctionStage(fn, doc) {
1137
- let func;
1138
- if (typeof fn.body === 'string') {
1139
- // String function bodies require secure worker-loader execution
1140
- throw new Error('$function requires worker_loaders binding. ' +
1141
- 'Add to wrangler.jsonc: "worker_loaders": [{ "binding": "LOADER" }]');
1142
- }
1143
- else {
1144
- func = fn.body;
1145
- }
1146
- // Resolve args - replace field references with actual values
1147
- const resolvedArgs = fn.args.map(arg => {
1148
- if (typeof arg === 'string' && arg.startsWith('$')) {
1149
- return this._getNestedValue(doc, arg.slice(1));
1150
- }
1151
- return arg;
1152
- });
1153
- // Execute function
1154
- return func(...resolvedArgs);
1155
- }
1156
- /**
1157
- * Execute aggregation pipeline on documents (in-memory implementation)
1158
- * @internal
1159
- */
1160
- _executeAggregationPipeline(documents, pipeline) {
1161
- let results = documents.map(doc => ({ ...doc }));
1162
- for (const stage of pipeline) {
1163
- const stageType = Object.keys(stage)[0];
1164
- if (stageType === undefined)
1165
- continue;
1166
- const stageValue = stage[stageType];
1167
- switch (stageType) {
1168
- case '$match':
1169
- results = results.filter(doc => this._matchesFilter(doc, stageValue));
1170
- break;
1171
- case '$project':
1172
- results = this._executeProjectStage(results, stageValue);
1173
- break;
1174
- case '$group':
1175
- results = this._executeGroupStage(results, stageValue);
1176
- break;
1177
- case '$sort':
1178
- results = this._executeSortStage(results, stageValue);
1179
- break;
1180
- case '$limit':
1181
- results = results.slice(0, stageValue);
1182
- break;
1183
- case '$skip':
1184
- results = results.slice(stageValue);
1185
- break;
1186
- case '$count':
1187
- results = [{ [stageValue]: results.length }];
1188
- break;
1189
- case '$unwind':
1190
- results = this._executeUnwindStage(results, stageValue);
1191
- break;
1192
- case '$addFields':
1193
- case '$set':
1194
- results = this._executeAddFieldsStage(results, stageValue);
1195
- break;
1196
- case '$lookup':
1197
- results = this._executeLookupStage(results, stageValue);
1198
- break;
1199
- default:
1200
- // Unsupported stage - pass through
1201
- break;
1202
- }
1203
- }
1204
- return results;
1205
- }
1206
- /**
1207
- * Execute $project stage
1208
- * @internal
1209
- */
1210
- _executeProjectStage(documents, projection) {
1211
- // Check if we have inclusions or expressions (expressions count as inclusions)
1212
- const hasInclusion = Object.entries(projection).some(([key, v]) => {
1213
- if (key === '_id')
1214
- return false; // _id: 0 doesn't count
1215
- return v === 1 ||
1216
- (typeof v === 'string' && v.startsWith('$')) ||
1217
- (typeof v === 'object' && v !== null);
1218
- });
1219
- const excludeId = projection._id === 0;
1220
- return documents.map(doc => {
1221
- const result = {};
1222
- if (hasInclusion) {
1223
- // Inclusion mode
1224
- if (!excludeId && '_id' in doc) {
1225
- result._id = doc._id;
1226
- }
1227
- for (const [key, value] of Object.entries(projection)) {
1228
- if (key === '_id' && value === 0)
1229
- continue;
1230
- if (key === '_id' && value === 1) {
1231
- result._id = doc._id;
1232
- continue;
1233
- }
1234
- if (value === 1) {
1235
- result[key] = this._getNestedValue(doc, key);
1236
- }
1237
- else if (typeof value === 'string' && value.startsWith('$')) {
1238
- result[key] = this._getNestedValue(doc, value.slice(1));
1239
- }
1240
- else if (typeof value === 'object' && value !== null) {
1241
- result[key] = this._evaluateExpression(doc, value);
1242
- }
1243
- }
1244
- }
1245
- else {
1246
- // Exclusion mode
1247
- for (const [key, val] of Object.entries(doc)) {
1248
- if (projection[key] === 0)
1249
- continue;
1250
- result[key] = val;
1251
- }
1252
- }
1253
- return result;
1254
- });
1255
- }
1256
- /**
1257
- * Execute $group stage
1258
- * @internal
1259
- */
1260
- _executeGroupStage(documents, groupSpec) {
1261
- const groups = new Map();
1262
- for (const doc of documents) {
1263
- // Compute group key
1264
- let groupKey;
1265
- const idSpec = groupSpec._id;
1266
- if (idSpec === null) {
1267
- groupKey = '__all__';
1268
- }
1269
- else if (typeof idSpec === 'string' && idSpec.startsWith('$')) {
1270
- groupKey = String(this._getNestedValue(doc, idSpec.slice(1)));
1271
- }
1272
- else if (typeof idSpec === 'object' && idSpec !== null) {
1273
- const keyObj = {};
1274
- for (const [k, v] of Object.entries(idSpec)) {
1275
- if (typeof v === 'string' && v.startsWith('$')) {
1276
- keyObj[k] = this._getNestedValue(doc, v.slice(1));
1277
- }
1278
- else {
1279
- keyObj[k] = v;
1280
- }
1281
- }
1282
- groupKey = JSON.stringify(keyObj);
1283
- }
1284
- else {
1285
- groupKey = String(idSpec);
1286
- }
1287
- if (!groups.has(groupKey)) {
1288
- // Initialize group
1289
- let idValue;
1290
- if (idSpec === null) {
1291
- idValue = null;
1292
- }
1293
- else if (typeof idSpec === 'string' && idSpec.startsWith('$')) {
1294
- idValue = this._getNestedValue(doc, idSpec.slice(1));
1295
- }
1296
- else if (typeof idSpec === 'object' && idSpec !== null) {
1297
- idValue = {};
1298
- for (const [k, v] of Object.entries(idSpec)) {
1299
- if (typeof v === 'string' && v.startsWith('$')) {
1300
- idValue[k] = this._getNestedValue(doc, v.slice(1));
1301
- }
1302
- else {
1303
- idValue[k] = v;
1304
- }
1305
- }
1306
- }
1307
- else {
1308
- idValue = idSpec;
1309
- }
1310
- groups.set(groupKey, { docs: [], result: { _id: idValue } });
1311
- }
1312
- groups.get(groupKey).docs.push(doc);
1313
- }
1314
- // Apply accumulators
1315
- const results = [];
1316
- for (const { docs, result } of groups.values()) {
1317
- for (const [key, accumulator] of Object.entries(groupSpec)) {
1318
- if (key === '_id')
1319
- continue;
1320
- if (typeof accumulator === 'object' && accumulator !== null) {
1321
- const accObj = accumulator;
1322
- const accType = Object.keys(accObj)[0];
1323
- if (accType === undefined)
1324
- continue;
1325
- const accValue = accObj[accType];
1326
- switch (accType) {
1327
- case '$sum':
1328
- if (accValue === 1) {
1329
- result[key] = docs.length;
1330
- }
1331
- else if (typeof accValue === 'string' && accValue.startsWith('$')) {
1332
- result[key] = docs.reduce((sum, d) => {
1333
- const val = this._getNestedValue(d, accValue.slice(1));
1334
- return sum + (typeof val === 'number' ? val : 0);
1335
- }, 0);
1336
- }
1337
- break;
1338
- case '$avg':
1339
- if (typeof accValue === 'string' && accValue.startsWith('$')) {
1340
- const sum = docs.reduce((s, d) => {
1341
- const val = this._getNestedValue(d, accValue.slice(1));
1342
- return s + (typeof val === 'number' ? val : 0);
1343
- }, 0);
1344
- result[key] = docs.length > 0 ? sum / docs.length : null;
1345
- }
1346
- break;
1347
- case '$min':
1348
- if (typeof accValue === 'string' && accValue.startsWith('$')) {
1349
- const values = docs.map(d => this._getNestedValue(d, accValue.slice(1)));
1350
- result[key] = Math.min(...values.filter(v => typeof v === 'number'));
1351
- }
1352
- break;
1353
- case '$max':
1354
- if (typeof accValue === 'string' && accValue.startsWith('$')) {
1355
- const values = docs.map(d => this._getNestedValue(d, accValue.slice(1)));
1356
- result[key] = Math.max(...values.filter(v => typeof v === 'number'));
1357
- }
1358
- break;
1359
- case '$count':
1360
- result[key] = docs.length;
1361
- break;
1362
- case '$first':
1363
- if (typeof accValue === 'string' && accValue.startsWith('$')) {
1364
- const firstDoc = docs[0];
1365
- result[key] = firstDoc !== undefined ? this._getNestedValue(firstDoc, accValue.slice(1)) : null;
1366
- }
1367
- break;
1368
- case '$last':
1369
- if (typeof accValue === 'string' && accValue.startsWith('$')) {
1370
- const lastDoc = docs[docs.length - 1];
1371
- result[key] = lastDoc !== undefined ? this._getNestedValue(lastDoc, accValue.slice(1)) : null;
1372
- }
1373
- break;
1374
- case '$push':
1375
- if (typeof accValue === 'string' && accValue.startsWith('$')) {
1376
- result[key] = docs.map(d => this._getNestedValue(d, accValue.slice(1)));
1377
- }
1378
- break;
1379
- case '$addToSet':
1380
- if (typeof accValue === 'string' && accValue.startsWith('$')) {
1381
- const set = new Set();
1382
- for (const d of docs) {
1383
- set.add(JSON.stringify(this._getNestedValue(d, accValue.slice(1))));
1384
- }
1385
- result[key] = Array.from(set).map(s => JSON.parse(s));
1386
- }
1387
- break;
1388
- }
1389
- }
1390
- }
1391
- results.push(result);
1392
- }
1393
- return results;
1394
- }
1395
- /**
1396
- * Execute $sort stage
1397
- * @internal
1398
- */
1399
- _executeSortStage(documents, sortSpec) {
1400
- return [...documents].sort((a, b) => {
1401
- for (const [field, direction] of Object.entries(sortSpec)) {
1402
- const aVal = this._getNestedValue(a, field);
1403
- const bVal = this._getNestedValue(b, field);
1404
- let comparison = 0;
1405
- if (aVal === bVal) {
1406
- comparison = 0;
1407
- }
1408
- else if (aVal === null || aVal === undefined) {
1409
- comparison = -1;
1410
- }
1411
- else if (bVal === null || bVal === undefined) {
1412
- comparison = 1;
1413
- }
1414
- else if (typeof aVal === 'string' && typeof bVal === 'string') {
1415
- comparison = aVal.localeCompare(bVal);
1416
- }
1417
- else {
1418
- comparison = aVal - bVal;
1419
- }
1420
- if (comparison !== 0) {
1421
- return comparison * direction;
1422
- }
1423
- }
1424
- return 0;
1425
- });
1426
- }
1427
- /**
1428
- * Execute $unwind stage
1429
- * @internal
1430
- */
1431
- _executeUnwindStage(documents, unwindSpec) {
1432
- const path = typeof unwindSpec === 'string' ? unwindSpec : unwindSpec.path;
1433
- const preserveNull = typeof unwindSpec === 'object' && unwindSpec.preserveNullAndEmptyArrays === true;
1434
- const fieldPath = path.startsWith('$') ? path.slice(1) : path;
1435
- const results = [];
1436
- for (const doc of documents) {
1437
- const arrayValue = this._getNestedValue(doc, fieldPath);
1438
- if (Array.isArray(arrayValue) && arrayValue.length > 0) {
1439
- for (const item of arrayValue) {
1440
- const newDoc = { ...doc };
1441
- this._setNestedValue(newDoc, fieldPath, item);
1442
- results.push(newDoc);
1443
- }
1444
- }
1445
- else if (preserveNull) {
1446
- results.push({ ...doc });
1447
- }
1448
- }
1449
- return results;
1450
- }
1451
- /**
1452
- * Execute $addFields/$set stage
1453
- * @internal
1454
- */
1455
- _executeAddFieldsStage(documents, fieldsSpec) {
1456
- return documents.map(doc => {
1457
- const result = { ...doc };
1458
- for (const [field, value] of Object.entries(fieldsSpec)) {
1459
- if (typeof value === 'string' && value.startsWith('$')) {
1460
- result[field] = this._getNestedValue(doc, value.slice(1));
1461
- }
1462
- else if (typeof value === 'object' && value !== null) {
1463
- result[field] = this._evaluateExpression(doc, value);
1464
- }
1465
- else {
1466
- result[field] = value;
1467
- }
1468
- }
1469
- return result;
1470
- });
1471
- }
1472
- /**
1473
- * Execute $lookup stage
1474
- * @internal
1475
- */
1476
- _executeLookupStage(documents, lookupSpec) {
1477
- const targetCollection = this.database.collection(lookupSpec.from);
1478
- const targetDocs = targetCollection._findDocuments({});
1479
- return documents.map(doc => {
1480
- const result = { ...doc };
1481
- if (lookupSpec.localField && lookupSpec.foreignField) {
1482
- const localValue = this._getNestedValue(doc, lookupSpec.localField);
1483
- const matched = targetDocs.filter(targetDoc => {
1484
- const foreignValue = this._getNestedValue(targetDoc, lookupSpec.foreignField);
1485
- return this._valuesEqual(localValue, foreignValue);
1486
- });
1487
- result[lookupSpec.as] = matched;
1488
- }
1489
- else {
1490
- result[lookupSpec.as] = [];
1491
- }
1492
- return result;
1493
- });
1494
- }
1495
- /**
1496
- * Evaluate an expression (simplified)
1497
- * @internal
1498
- */
1499
- _evaluateExpression(doc, expr) {
1500
- if (expr === null || typeof expr !== 'object') {
1501
- return expr;
1502
- }
1503
- const exprObj = expr;
1504
- const operator = Object.keys(exprObj)[0];
1505
- if (operator === undefined)
1506
- return expr;
1507
- const operand = exprObj[operator];
1508
- switch (operator) {
1509
- case '$concat':
1510
- if (Array.isArray(operand)) {
1511
- return operand.map(item => {
1512
- if (typeof item === 'string' && item.startsWith('$')) {
1513
- return String(this._getNestedValue(doc, item.slice(1)) ?? '');
1514
- }
1515
- return String(item);
1516
- }).join('');
1517
- }
1518
- break;
1519
- case '$add':
1520
- if (Array.isArray(operand)) {
1521
- return operand.reduce((sum, item) => {
1522
- if (typeof item === 'string' && item.startsWith('$')) {
1523
- return sum + (Number(this._getNestedValue(doc, item.slice(1))) || 0);
1524
- }
1525
- return sum + (Number(item) || 0);
1526
- }, 0);
1527
- }
1528
- break;
1529
- case '$subtract':
1530
- if (Array.isArray(operand) && operand.length === 2) {
1531
- const a = typeof operand[0] === 'string' && operand[0].startsWith('$')
1532
- ? Number(this._getNestedValue(doc, operand[0].slice(1)))
1533
- : Number(operand[0]);
1534
- const b = typeof operand[1] === 'string' && operand[1].startsWith('$')
1535
- ? Number(this._getNestedValue(doc, operand[1].slice(1)))
1536
- : Number(operand[1]);
1537
- return a - b;
1538
- }
1539
- break;
1540
- case '$multiply':
1541
- if (Array.isArray(operand)) {
1542
- return operand.reduce((product, item) => {
1543
- if (typeof item === 'string' && item.startsWith('$')) {
1544
- return product * (Number(this._getNestedValue(doc, item.slice(1))) || 0);
1545
- }
1546
- return product * (Number(item) || 0);
1547
- }, 1);
1548
- }
1549
- break;
1550
- case '$divide':
1551
- if (Array.isArray(operand) && operand.length === 2) {
1552
- const a = typeof operand[0] === 'string' && operand[0].startsWith('$')
1553
- ? Number(this._getNestedValue(doc, operand[0].slice(1)))
1554
- : Number(operand[0]);
1555
- const b = typeof operand[1] === 'string' && operand[1].startsWith('$')
1556
- ? Number(this._getNestedValue(doc, operand[1].slice(1)))
1557
- : Number(operand[1]);
1558
- return b !== 0 ? a / b : null;
1559
- }
1560
- break;
1561
- case '$cond':
1562
- if (typeof operand === 'object' && operand !== null) {
1563
- const cond = operand;
1564
- const condition = this._evaluateCondition(doc, cond.if);
1565
- return condition
1566
- ? this._evaluateExpression(doc, cond.then)
1567
- : this._evaluateExpression(doc, cond.else);
1568
- }
1569
- break;
1570
- case '$ifNull':
1571
- if (Array.isArray(operand) && operand.length === 2) {
1572
- const value = typeof operand[0] === 'string' && operand[0].startsWith('$')
1573
- ? this._getNestedValue(doc, operand[0].slice(1))
1574
- : operand[0];
1575
- return value ?? operand[1];
1576
- }
1577
- break;
1578
- }
1579
- return expr;
1580
- }
1581
- /**
1582
- * Evaluate a condition
1583
- * @internal
1584
- */
1585
- _evaluateCondition(doc, condition) {
1586
- if (typeof condition !== 'object' || condition === null) {
1587
- return Boolean(condition);
1588
- }
1589
- const condObj = condition;
1590
- const operator = Object.keys(condObj)[0];
1591
- if (operator === undefined)
1592
- return true;
1593
- const operand = condObj[operator];
1594
- switch (operator) {
1595
- case '$eq':
1596
- return this._compareExprValues(doc, operand[0], operand[1]) === 0;
1597
- case '$ne':
1598
- return this._compareExprValues(doc, operand[0], operand[1]) !== 0;
1599
- case '$gt':
1600
- return this._compareExprValues(doc, operand[0], operand[1]) > 0;
1601
- case '$gte':
1602
- return this._compareExprValues(doc, operand[0], operand[1]) >= 0;
1603
- case '$lt':
1604
- return this._compareExprValues(doc, operand[0], operand[1]) < 0;
1605
- case '$lte':
1606
- return this._compareExprValues(doc, operand[0], operand[1]) <= 0;
1607
- case '$and':
1608
- return operand.every(c => this._evaluateCondition(doc, c));
1609
- case '$or':
1610
- return operand.some(c => this._evaluateCondition(doc, c));
1611
- default:
1612
- return true;
1613
- }
1614
- }
1615
- /**
1616
- * Compare two expression values
1617
- * @internal
1618
- */
1619
- _compareExprValues(doc, a, b) {
1620
- const resolveValue = (val) => {
1621
- if (typeof val === 'string' && val.startsWith('$')) {
1622
- return this._getNestedValue(doc, val.slice(1));
1623
- }
1624
- return val;
1625
- };
1626
- const aVal = resolveValue(a);
1627
- const bVal = resolveValue(b);
1628
- if (aVal === bVal)
1629
- return 0;
1630
- if (aVal === null || aVal === undefined)
1631
- return -1;
1632
- if (bVal === null || bVal === undefined)
1633
- return 1;
1634
- if (typeof aVal === 'number' && typeof bVal === 'number') {
1635
- return aVal - bVal;
1636
- }
1637
- return String(aVal).localeCompare(String(bVal));
1638
- }
1639
- }
1640
- export default MongoCollection;
1641
- //# sourceMappingURL=mongo-collection.js.map