@push.rocks/smartmongo 2.2.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/index.d.ts +1 -1
  3. package/dist_ts/index.js +3 -3
  4. package/dist_ts/tsmdb/engine/AggregationEngine.js +189 -0
  5. package/dist_ts/{congodb → tsmdb}/engine/IndexEngine.d.ts +23 -3
  6. package/dist_ts/tsmdb/engine/IndexEngine.js +678 -0
  7. package/dist_ts/tsmdb/engine/QueryEngine.js +271 -0
  8. package/dist_ts/tsmdb/engine/QueryPlanner.d.ts +64 -0
  9. package/dist_ts/tsmdb/engine/QueryPlanner.js +308 -0
  10. package/dist_ts/tsmdb/engine/SessionEngine.d.ts +117 -0
  11. package/dist_ts/tsmdb/engine/SessionEngine.js +232 -0
  12. package/dist_ts/{congodb → tsmdb}/engine/TransactionEngine.d.ts +1 -1
  13. package/dist_ts/tsmdb/engine/TransactionEngine.js +287 -0
  14. package/dist_ts/tsmdb/engine/UpdateEngine.js +461 -0
  15. package/dist_ts/{congodb/errors/CongoErrors.d.ts → tsmdb/errors/TsmdbErrors.d.ts} +16 -16
  16. package/dist_ts/tsmdb/errors/TsmdbErrors.js +155 -0
  17. package/dist_ts/{congodb → tsmdb}/index.d.ts +11 -4
  18. package/dist_ts/tsmdb/index.js +31 -0
  19. package/dist_ts/tsmdb/server/CommandRouter.d.ts +87 -0
  20. package/dist_ts/tsmdb/server/CommandRouter.js +222 -0
  21. package/dist_ts/{congodb/server/CongoServer.d.ts → tsmdb/server/TsmdbServer.d.ts} +6 -6
  22. package/dist_ts/tsmdb/server/TsmdbServer.js +229 -0
  23. package/dist_ts/{congodb → tsmdb}/server/WireProtocol.d.ts +1 -1
  24. package/dist_ts/tsmdb/server/WireProtocol.js +298 -0
  25. package/dist_ts/{congodb → tsmdb}/server/handlers/AdminHandler.d.ts +1 -1
  26. package/dist_ts/tsmdb/server/handlers/AdminHandler.js +668 -0
  27. package/dist_ts/{congodb → tsmdb}/server/handlers/AggregateHandler.d.ts +1 -1
  28. package/dist_ts/tsmdb/server/handlers/AggregateHandler.js +277 -0
  29. package/dist_ts/{congodb → tsmdb}/server/handlers/DeleteHandler.d.ts +1 -1
  30. package/dist_ts/tsmdb/server/handlers/DeleteHandler.js +95 -0
  31. package/dist_ts/{congodb → tsmdb}/server/handlers/FindHandler.d.ts +1 -1
  32. package/dist_ts/tsmdb/server/handlers/FindHandler.js +291 -0
  33. package/dist_ts/{congodb → tsmdb}/server/handlers/HelloHandler.d.ts +1 -1
  34. package/dist_ts/{congodb → tsmdb}/server/handlers/HelloHandler.js +2 -2
  35. package/dist_ts/{congodb → tsmdb}/server/handlers/IndexHandler.d.ts +1 -1
  36. package/dist_ts/tsmdb/server/handlers/IndexHandler.js +183 -0
  37. package/dist_ts/{congodb → tsmdb}/server/handlers/InsertHandler.d.ts +1 -1
  38. package/dist_ts/tsmdb/server/handlers/InsertHandler.js +79 -0
  39. package/dist_ts/{congodb → tsmdb}/server/handlers/UpdateHandler.d.ts +1 -1
  40. package/dist_ts/tsmdb/server/handlers/UpdateHandler.js +296 -0
  41. package/dist_ts/tsmdb/server/handlers/index.js +10 -0
  42. package/dist_ts/{congodb → tsmdb}/server/index.d.ts +2 -2
  43. package/dist_ts/tsmdb/server/index.js +7 -0
  44. package/dist_ts/{congodb → tsmdb}/storage/FileStorageAdapter.d.ts +27 -3
  45. package/dist_ts/tsmdb/storage/FileStorageAdapter.js +465 -0
  46. package/dist_ts/{congodb → tsmdb}/storage/IStorageAdapter.d.ts +7 -2
  47. package/dist_ts/{congodb → tsmdb}/storage/IStorageAdapter.js +1 -1
  48. package/dist_ts/{congodb → tsmdb}/storage/MemoryStorageAdapter.d.ts +3 -2
  49. package/dist_ts/tsmdb/storage/MemoryStorageAdapter.js +378 -0
  50. package/dist_ts/{congodb → tsmdb}/storage/OpLog.d.ts +1 -1
  51. package/dist_ts/tsmdb/storage/OpLog.js +221 -0
  52. package/dist_ts/tsmdb/storage/WAL.d.ts +117 -0
  53. package/dist_ts/tsmdb/storage/WAL.js +286 -0
  54. package/dist_ts/tsmdb/tsmdb.plugins.js +14 -0
  55. package/dist_ts/{congodb → tsmdb}/types/interfaces.d.ts +3 -3
  56. package/dist_ts/{congodb → tsmdb}/types/interfaces.js +1 -1
  57. package/dist_ts/tsmdb/utils/checksum.d.ts +30 -0
  58. package/dist_ts/tsmdb/utils/checksum.js +77 -0
  59. package/dist_ts/tsmdb/utils/index.d.ts +1 -0
  60. package/dist_ts/tsmdb/utils/index.js +2 -0
  61. package/package.json +1 -1
  62. package/readme.hints.md +7 -12
  63. package/readme.md +25 -25
  64. package/ts/00_commitinfo_data.ts +1 -1
  65. package/ts/index.ts +2 -2
  66. package/ts/{congodb → tsmdb}/engine/AggregationEngine.ts +1 -1
  67. package/ts/tsmdb/engine/IndexEngine.ts +798 -0
  68. package/ts/{congodb → tsmdb}/engine/QueryEngine.ts +1 -1
  69. package/ts/tsmdb/engine/QueryPlanner.ts +393 -0
  70. package/ts/tsmdb/engine/SessionEngine.ts +292 -0
  71. package/ts/{congodb → tsmdb}/engine/TransactionEngine.ts +12 -12
  72. package/ts/{congodb → tsmdb}/engine/UpdateEngine.ts +1 -1
  73. package/ts/{congodb/errors/CongoErrors.ts → tsmdb/errors/TsmdbErrors.ts} +34 -34
  74. package/ts/{congodb → tsmdb}/index.ts +16 -7
  75. package/ts/{congodb → tsmdb}/server/CommandRouter.ts +114 -5
  76. package/ts/{congodb/server/CongoServer.ts → tsmdb/server/TsmdbServer.ts} +11 -8
  77. package/ts/{congodb → tsmdb}/server/WireProtocol.ts +1 -1
  78. package/ts/{congodb → tsmdb}/server/handlers/AdminHandler.ts +116 -11
  79. package/ts/{congodb → tsmdb}/server/handlers/AggregateHandler.ts +1 -1
  80. package/ts/{congodb → tsmdb}/server/handlers/DeleteHandler.ts +18 -3
  81. package/ts/{congodb → tsmdb}/server/handlers/FindHandler.ts +43 -14
  82. package/ts/{congodb → tsmdb}/server/handlers/HelloHandler.ts +1 -1
  83. package/ts/{congodb → tsmdb}/server/handlers/IndexHandler.ts +1 -1
  84. package/ts/{congodb → tsmdb}/server/handlers/InsertHandler.ts +7 -1
  85. package/ts/{congodb → tsmdb}/server/handlers/UpdateHandler.ts +34 -5
  86. package/ts/{congodb → tsmdb}/server/index.ts +2 -2
  87. package/ts/{congodb → tsmdb}/storage/FileStorageAdapter.ts +90 -7
  88. package/ts/{congodb → tsmdb}/storage/IStorageAdapter.ts +8 -2
  89. package/ts/{congodb → tsmdb}/storage/MemoryStorageAdapter.ts +14 -2
  90. package/ts/{congodb → tsmdb}/storage/OpLog.ts +1 -1
  91. package/ts/tsmdb/storage/WAL.ts +375 -0
  92. package/ts/{congodb → tsmdb}/types/interfaces.ts +3 -3
  93. package/ts/tsmdb/utils/checksum.ts +88 -0
  94. package/ts/tsmdb/utils/index.ts +1 -0
  95. package/dist_ts/congodb/congodb.plugins.js +0 -14
  96. package/dist_ts/congodb/engine/AggregationEngine.js +0 -189
  97. package/dist_ts/congodb/engine/IndexEngine.js +0 -376
  98. package/dist_ts/congodb/engine/QueryEngine.js +0 -271
  99. package/dist_ts/congodb/engine/TransactionEngine.js +0 -287
  100. package/dist_ts/congodb/engine/UpdateEngine.js +0 -461
  101. package/dist_ts/congodb/errors/CongoErrors.js +0 -155
  102. package/dist_ts/congodb/index.js +0 -26
  103. package/dist_ts/congodb/server/CommandRouter.d.ts +0 -51
  104. package/dist_ts/congodb/server/CommandRouter.js +0 -132
  105. package/dist_ts/congodb/server/CongoServer.js +0 -227
  106. package/dist_ts/congodb/server/WireProtocol.js +0 -298
  107. package/dist_ts/congodb/server/handlers/AdminHandler.js +0 -568
  108. package/dist_ts/congodb/server/handlers/AggregateHandler.js +0 -277
  109. package/dist_ts/congodb/server/handlers/DeleteHandler.js +0 -83
  110. package/dist_ts/congodb/server/handlers/FindHandler.js +0 -261
  111. package/dist_ts/congodb/server/handlers/IndexHandler.js +0 -183
  112. package/dist_ts/congodb/server/handlers/InsertHandler.js +0 -76
  113. package/dist_ts/congodb/server/handlers/UpdateHandler.js +0 -270
  114. package/dist_ts/congodb/server/handlers/index.js +0 -10
  115. package/dist_ts/congodb/server/index.js +0 -7
  116. package/dist_ts/congodb/storage/FileStorageAdapter.js +0 -396
  117. package/dist_ts/congodb/storage/MemoryStorageAdapter.js +0 -367
  118. package/dist_ts/congodb/storage/OpLog.js +0 -221
  119. package/ts/congodb/engine/IndexEngine.ts +0 -479
  120. /package/dist_ts/{congodb → tsmdb}/engine/AggregationEngine.d.ts +0 -0
  121. /package/dist_ts/{congodb → tsmdb}/engine/QueryEngine.d.ts +0 -0
  122. /package/dist_ts/{congodb → tsmdb}/engine/UpdateEngine.d.ts +0 -0
  123. /package/dist_ts/{congodb → tsmdb}/server/handlers/index.d.ts +0 -0
  124. /package/dist_ts/{congodb/congodb.plugins.d.ts → tsmdb/tsmdb.plugins.d.ts} +0 -0
  125. /package/ts/{congodb → tsmdb}/server/handlers/index.ts +0 -0
  126. /package/ts/{congodb/congodb.plugins.ts → tsmdb/tsmdb.plugins.ts} +0 -0
@@ -0,0 +1,229 @@
1
+ import * as net from 'net';
2
+ import * as plugins from '../tsmdb.plugins.js';
3
+ import { WireProtocol, OP_QUERY } from './WireProtocol.js';
4
+ import { CommandRouter } from './CommandRouter.js';
5
+ import { MemoryStorageAdapter } from '../storage/MemoryStorageAdapter.js';
6
+ import { FileStorageAdapter } from '../storage/FileStorageAdapter.js';
7
+ /**
8
+ * TsmdbServer - MongoDB Wire Protocol compatible server
9
+ *
10
+ * This server implements the MongoDB wire protocol (OP_MSG) to allow
11
+ * official MongoDB drivers to connect and perform operations.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { TsmdbServer } from '@push.rocks/smartmongo/tsmdb';
16
+ * import { MongoClient } from 'mongodb';
17
+ *
18
+ * const server = new TsmdbServer({ port: 27017 });
19
+ * await server.start();
20
+ *
21
+ * const client = new MongoClient('mongodb://127.0.0.1:27017');
22
+ * await client.connect();
23
+ * ```
24
+ */
25
+ export class TsmdbServer {
26
+ options;
27
+ server = null;
28
+ storage;
29
+ commandRouter;
30
+ connections = new Map();
31
+ connectionIdCounter = 0;
32
+ isRunning = false;
33
+ startTime = new Date();
34
+ constructor(options = {}) {
35
+ this.options = {
36
+ port: options.port ?? 27017,
37
+ host: options.host ?? '127.0.0.1',
38
+ storage: options.storage ?? 'memory',
39
+ storagePath: options.storagePath ?? './data',
40
+ persistPath: options.persistPath ?? '',
41
+ persistIntervalMs: options.persistIntervalMs ?? 60000,
42
+ };
43
+ // Create storage adapter
44
+ if (this.options.storage === 'file') {
45
+ this.storage = new FileStorageAdapter(this.options.storagePath);
46
+ }
47
+ else {
48
+ this.storage = new MemoryStorageAdapter({
49
+ persistPath: this.options.persistPath || undefined,
50
+ persistIntervalMs: this.options.persistPath ? this.options.persistIntervalMs : undefined,
51
+ });
52
+ }
53
+ // Create command router
54
+ this.commandRouter = new CommandRouter(this.storage, this);
55
+ }
56
+ /**
57
+ * Get the storage adapter (for testing/debugging)
58
+ */
59
+ getStorage() {
60
+ return this.storage;
61
+ }
62
+ /**
63
+ * Get server uptime in seconds
64
+ */
65
+ getUptime() {
66
+ return Math.floor((Date.now() - this.startTime.getTime()) / 1000);
67
+ }
68
+ /**
69
+ * Get current connection count
70
+ */
71
+ getConnectionCount() {
72
+ return this.connections.size;
73
+ }
74
+ /**
75
+ * Start the server
76
+ */
77
+ async start() {
78
+ if (this.isRunning) {
79
+ throw new Error('Server is already running');
80
+ }
81
+ // Initialize storage
82
+ await this.storage.initialize();
83
+ return new Promise((resolve, reject) => {
84
+ this.server = net.createServer((socket) => {
85
+ this.handleConnection(socket);
86
+ });
87
+ this.server.on('error', (err) => {
88
+ if (!this.isRunning) {
89
+ reject(err);
90
+ }
91
+ else {
92
+ console.error('Server error:', err);
93
+ }
94
+ });
95
+ this.server.listen(this.options.port, this.options.host, () => {
96
+ this.isRunning = true;
97
+ this.startTime = new Date();
98
+ resolve();
99
+ });
100
+ });
101
+ }
102
+ /**
103
+ * Stop the server
104
+ */
105
+ async stop() {
106
+ if (!this.isRunning || !this.server) {
107
+ return;
108
+ }
109
+ // Close all connections
110
+ for (const conn of this.connections.values()) {
111
+ conn.socket.destroy();
112
+ }
113
+ this.connections.clear();
114
+ // Close command router (cleans up session engine, cursors, etc.)
115
+ this.commandRouter.close();
116
+ // Close storage
117
+ await this.storage.close();
118
+ return new Promise((resolve) => {
119
+ this.server.close(() => {
120
+ this.isRunning = false;
121
+ this.server = null;
122
+ resolve();
123
+ });
124
+ });
125
+ }
126
+ /**
127
+ * Handle a new client connection
128
+ */
129
+ handleConnection(socket) {
130
+ const connectionId = ++this.connectionIdCounter;
131
+ const state = {
132
+ id: connectionId,
133
+ socket,
134
+ buffer: Buffer.alloc(0),
135
+ authenticated: true, // No auth required for now
136
+ database: 'test',
137
+ };
138
+ this.connections.set(connectionId, state);
139
+ socket.on('data', (data) => {
140
+ this.handleData(state, Buffer.isBuffer(data) ? data : Buffer.from(data));
141
+ });
142
+ socket.on('close', () => {
143
+ this.connections.delete(connectionId);
144
+ });
145
+ socket.on('error', (err) => {
146
+ // Connection errors are expected when clients disconnect
147
+ this.connections.delete(connectionId);
148
+ });
149
+ }
150
+ /**
151
+ * Handle incoming data from a client
152
+ */
153
+ handleData(state, data) {
154
+ // Append new data to buffer
155
+ state.buffer = Buffer.concat([state.buffer, data]);
156
+ // Process messages from buffer
157
+ this.processMessages(state);
158
+ }
159
+ /**
160
+ * Process complete messages from the buffer
161
+ */
162
+ async processMessages(state) {
163
+ while (state.buffer.length >= 16) {
164
+ try {
165
+ const result = WireProtocol.parseMessage(state.buffer);
166
+ if (!result) {
167
+ // Not enough data for a complete message
168
+ break;
169
+ }
170
+ const { command, bytesConsumed } = result;
171
+ // Remove processed bytes from buffer
172
+ state.buffer = state.buffer.subarray(bytesConsumed);
173
+ // Process the command
174
+ const response = await this.commandRouter.route(command);
175
+ // Encode and send response
176
+ let responseBuffer;
177
+ if (command.opCode === OP_QUERY) {
178
+ // Legacy OP_QUERY gets OP_REPLY response
179
+ responseBuffer = WireProtocol.encodeOpReplyResponse(command.requestID, [response]);
180
+ }
181
+ else {
182
+ // OP_MSG gets OP_MSG response
183
+ responseBuffer = WireProtocol.encodeOpMsgResponse(command.requestID, response);
184
+ }
185
+ if (!state.socket.destroyed) {
186
+ state.socket.write(responseBuffer);
187
+ }
188
+ }
189
+ catch (error) {
190
+ // Send error response
191
+ const errorResponse = WireProtocol.encodeErrorResponse(0, // We don't have the requestID at this point
192
+ 1, error.message || 'Internal error');
193
+ if (!state.socket.destroyed) {
194
+ state.socket.write(errorResponse);
195
+ }
196
+ // Clear buffer on parse errors to avoid infinite loops
197
+ if (error.message?.includes('opCode') || error.message?.includes('section')) {
198
+ state.buffer = Buffer.alloc(0);
199
+ }
200
+ break;
201
+ }
202
+ }
203
+ }
204
+ /**
205
+ * Get the connection URI for this server
206
+ */
207
+ getConnectionUri() {
208
+ return `mongodb://${this.options.host}:${this.options.port}`;
209
+ }
210
+ /**
211
+ * Check if the server is running
212
+ */
213
+ get running() {
214
+ return this.isRunning;
215
+ }
216
+ /**
217
+ * Get the port the server is listening on
218
+ */
219
+ get port() {
220
+ return this.options.port;
221
+ }
222
+ /**
223
+ * Get the host the server is bound to
224
+ */
225
+ get host() {
226
+ return this.options.host;
227
+ }
228
+ }
229
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHNtZGJTZXJ2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy90c21kYi9zZXJ2ZXIvVHNtZGJTZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEdBQUcsTUFBTSxLQUFLLENBQUM7QUFDM0IsT0FBTyxLQUFLLE9BQU8sTUFBTSxxQkFBcUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzNELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNuRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUMxRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQWdDdEU7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBQ0gsTUFBTSxPQUFPLFdBQVc7SUFDZCxPQUFPLENBQWdDO0lBQ3ZDLE1BQU0sR0FBc0IsSUFBSSxDQUFDO0lBQ2pDLE9BQU8sQ0FBa0I7SUFDekIsYUFBYSxDQUFnQjtJQUM3QixXQUFXLEdBQWtDLElBQUksR0FBRyxFQUFFLENBQUM7SUFDdkQsbUJBQW1CLEdBQUcsQ0FBQyxDQUFDO0lBQ3hCLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFDbEIsU0FBUyxHQUFTLElBQUksSUFBSSxFQUFFLENBQUM7SUFFckMsWUFBWSxVQUErQixFQUFFO1FBQzNDLElBQUksQ0FBQyxPQUFPLEdBQUc7WUFDYixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxLQUFLO1lBQzNCLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxJQUFJLFdBQVc7WUFDakMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPLElBQUksUUFBUTtZQUNwQyxXQUFXLEVBQUUsT0FBTyxDQUFDLFdBQVcsSUFBSSxRQUFRO1lBQzVDLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVyxJQUFJLEVBQUU7WUFDdEMs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
@@ -1,4 +1,4 @@
1
- import * as plugins from '../congodb.plugins.js';
1
+ import * as plugins from '../tsmdb.plugins.js';
2
2
  /**
3
3
  * MongoDB Wire Protocol Implementation
4
4
  * Handles parsing and encoding of MongoDB wire protocol messages (OP_MSG primarily)
@@ -0,0 +1,298 @@
1
+ import * as plugins from '../tsmdb.plugins.js';
2
+ /**
3
+ * MongoDB Wire Protocol Implementation
4
+ * Handles parsing and encoding of MongoDB wire protocol messages (OP_MSG primarily)
5
+ *
6
+ * Wire Protocol Message Format:
7
+ * - Header (16 bytes): messageLength (4), requestID (4), responseTo (4), opCode (4)
8
+ * - OP_MSG: flagBits (4), sections[], optional checksum (4)
9
+ *
10
+ * References:
11
+ * - https://www.mongodb.com/docs/manual/reference/mongodb-wire-protocol/
12
+ */
13
+ // OpCodes
14
+ export const OP_REPLY = 1; // Legacy reply
15
+ export const OP_UPDATE = 2001; // Legacy update
16
+ export const OP_INSERT = 2002; // Legacy insert
17
+ export const OP_QUERY = 2004; // Legacy query (still used for initial handshake)
18
+ export const OP_GET_MORE = 2005; // Legacy getMore
19
+ export const OP_DELETE = 2006; // Legacy delete
20
+ export const OP_KILL_CURSORS = 2007; // Legacy kill cursors
21
+ export const OP_COMPRESSED = 2012; // Compressed message
22
+ export const OP_MSG = 2013; // Modern protocol (MongoDB 3.6+)
23
+ // OP_MSG Section Types
24
+ export const SECTION_BODY = 0; // Single BSON document
25
+ export const SECTION_DOCUMENT_SEQUENCE = 1; // Document sequence for bulk operations
26
+ // OP_MSG Flag Bits
27
+ export const MSG_FLAG_CHECKSUM_PRESENT = 1 << 0;
28
+ export const MSG_FLAG_MORE_TO_COME = 1 << 1;
29
+ export const MSG_FLAG_EXHAUST_ALLOWED = 1 << 16;
30
+ /**
31
+ * Wire Protocol parser and encoder
32
+ */
33
+ export class WireProtocol {
34
+ /**
35
+ * Parse a complete message from a buffer
36
+ * Returns the parsed command and the number of bytes consumed
37
+ */
38
+ static parseMessage(buffer) {
39
+ if (buffer.length < 16) {
40
+ return null; // Not enough data for header
41
+ }
42
+ const header = this.parseHeader(buffer);
43
+ if (buffer.length < header.messageLength) {
44
+ return null; // Not enough data for complete message
45
+ }
46
+ const messageBuffer = buffer.subarray(0, header.messageLength);
47
+ switch (header.opCode) {
48
+ case OP_MSG:
49
+ return this.parseOpMsg(messageBuffer, header);
50
+ case OP_QUERY:
51
+ return this.parseOpQuery(messageBuffer, header);
52
+ default:
53
+ throw new Error(`Unsupported opCode: ${header.opCode}`);
54
+ }
55
+ }
56
+ /**
57
+ * Parse message header (16 bytes)
58
+ */
59
+ static parseHeader(buffer) {
60
+ return {
61
+ messageLength: buffer.readInt32LE(0),
62
+ requestID: buffer.readInt32LE(4),
63
+ responseTo: buffer.readInt32LE(8),
64
+ opCode: buffer.readInt32LE(12),
65
+ };
66
+ }
67
+ /**
68
+ * Parse OP_MSG message
69
+ */
70
+ static parseOpMsg(buffer, header) {
71
+ let offset = 16; // Skip header
72
+ const flagBits = buffer.readUInt32LE(offset);
73
+ offset += 4;
74
+ const sections = [];
75
+ const documentSequences = new Map();
76
+ // Parse sections until we reach the end (or checksum)
77
+ const messageEnd = (flagBits & MSG_FLAG_CHECKSUM_PRESENT)
78
+ ? header.messageLength - 4
79
+ : header.messageLength;
80
+ while (offset < messageEnd) {
81
+ const sectionType = buffer.readUInt8(offset);
82
+ offset += 1;
83
+ if (sectionType === SECTION_BODY) {
84
+ // Single BSON document
85
+ const docSize = buffer.readInt32LE(offset);
86
+ const docBuffer = buffer.subarray(offset, offset + docSize);
87
+ const doc = plugins.bson.deserialize(docBuffer);
88
+ sections.push({ type: SECTION_BODY, payload: doc });
89
+ offset += docSize;
90
+ }
91
+ else if (sectionType === SECTION_DOCUMENT_SEQUENCE) {
92
+ // Document sequence
93
+ const sectionSize = buffer.readInt32LE(offset);
94
+ const sectionEnd = offset + sectionSize;
95
+ offset += 4;
96
+ // Read sequence identifier (C string)
97
+ let identifierEnd = offset;
98
+ while (buffer[identifierEnd] !== 0 && identifierEnd < sectionEnd) {
99
+ identifierEnd++;
100
+ }
101
+ const identifier = buffer.subarray(offset, identifierEnd).toString('utf8');
102
+ offset = identifierEnd + 1; // Skip null terminator
103
+ // Read documents
104
+ const documents = [];
105
+ while (offset < sectionEnd) {
106
+ const docSize = buffer.readInt32LE(offset);
107
+ const docBuffer = buffer.subarray(offset, offset + docSize);
108
+ documents.push(plugins.bson.deserialize(docBuffer));
109
+ offset += docSize;
110
+ }
111
+ sections.push({
112
+ type: SECTION_DOCUMENT_SEQUENCE,
113
+ payload: {},
114
+ sequenceIdentifier: identifier,
115
+ documents
116
+ });
117
+ documentSequences.set(identifier, documents);
118
+ }
119
+ else {
120
+ throw new Error(`Unknown section type: ${sectionType}`);
121
+ }
122
+ }
123
+ // The first section body contains the command
124
+ const commandSection = sections.find(s => s.type === SECTION_BODY);
125
+ if (!commandSection) {
126
+ throw new Error('OP_MSG missing command body section');
127
+ }
128
+ const command = commandSection.payload;
129
+ const commandName = Object.keys(command)[0];
130
+ const database = command.$db || 'admin';
131
+ return {
132
+ command: {
133
+ commandName,
134
+ command,
135
+ database,
136
+ requestID: header.requestID,
137
+ opCode: header.opCode,
138
+ documentSequences: documentSequences.size > 0 ? documentSequences : undefined,
139
+ },
140
+ bytesConsumed: header.messageLength,
141
+ };
142
+ }
143
+ /**
144
+ * Parse OP_QUERY message (legacy, used for initial handshake)
145
+ */
146
+ static parseOpQuery(buffer, header) {
147
+ let offset = 16; // Skip header
148
+ const flags = buffer.readInt32LE(offset);
149
+ offset += 4;
150
+ // Read full collection name (C string)
151
+ let nameEnd = offset;
152
+ while (buffer[nameEnd] !== 0 && nameEnd < buffer.length) {
153
+ nameEnd++;
154
+ }
155
+ const fullCollectionName = buffer.subarray(offset, nameEnd).toString('utf8');
156
+ offset = nameEnd + 1;
157
+ const numberToSkip = buffer.readInt32LE(offset);
158
+ offset += 4;
159
+ const numberToReturn = buffer.readInt32LE(offset);
160
+ offset += 4;
161
+ // Read query document
162
+ const querySize = buffer.readInt32LE(offset);
163
+ const queryBuffer = buffer.subarray(offset, offset + querySize);
164
+ const query = plugins.bson.deserialize(queryBuffer);
165
+ offset += querySize;
166
+ // Extract database from collection name (format: "dbname.$cmd" or "dbname.collection")
167
+ const parts = fullCollectionName.split('.');
168
+ const database = parts[0];
169
+ // For OP_QUERY to .$cmd, the query IS the command
170
+ let commandName = 'find';
171
+ let command = query;
172
+ if (parts[1] === '$cmd') {
173
+ // This is a command
174
+ commandName = Object.keys(query)[0];
175
+ // Handle special commands like isMaster, hello
176
+ if (commandName === 'isMaster' || commandName === 'ismaster') {
177
+ commandName = 'hello';
178
+ }
179
+ }
180
+ return {
181
+ command: {
182
+ commandName,
183
+ command,
184
+ database,
185
+ requestID: header.requestID,
186
+ opCode: header.opCode,
187
+ },
188
+ bytesConsumed: header.messageLength,
189
+ };
190
+ }
191
+ /**
192
+ * Encode a response as OP_MSG
193
+ */
194
+ static encodeOpMsgResponse(responseTo, response, requestID = Math.floor(Math.random() * 0x7FFFFFFF)) {
195
+ // Add $db if not present (optional in response)
196
+ const responseDoc = { ...response };
197
+ // Serialize the response document
198
+ const bodyBson = plugins.bson.serialize(responseDoc);
199
+ // Calculate message length
200
+ // Header (16) + flagBits (4) + section type (1) + body BSON
201
+ const messageLength = 16 + 4 + 1 + bodyBson.length;
202
+ const buffer = Buffer.alloc(messageLength);
203
+ let offset = 0;
204
+ // Write header
205
+ buffer.writeInt32LE(messageLength, offset); // messageLength
206
+ offset += 4;
207
+ buffer.writeInt32LE(requestID, offset); // requestID
208
+ offset += 4;
209
+ buffer.writeInt32LE(responseTo, offset); // responseTo
210
+ offset += 4;
211
+ buffer.writeInt32LE(OP_MSG, offset); // opCode
212
+ offset += 4;
213
+ // Write flagBits (0 = no flags)
214
+ buffer.writeUInt32LE(0, offset);
215
+ offset += 4;
216
+ // Write section type 0 (body)
217
+ buffer.writeUInt8(SECTION_BODY, offset);
218
+ offset += 1;
219
+ // Write body BSON
220
+ Buffer.from(bodyBson).copy(buffer, offset);
221
+ return buffer;
222
+ }
223
+ /**
224
+ * Encode a response as OP_REPLY (legacy, for OP_QUERY responses)
225
+ */
226
+ static encodeOpReplyResponse(responseTo, documents, requestID = Math.floor(Math.random() * 0x7FFFFFFF), cursorId = BigInt(0)) {
227
+ // Serialize all documents
228
+ const docBuffers = documents.map(doc => plugins.bson.serialize(doc));
229
+ const totalDocsSize = docBuffers.reduce((sum, buf) => sum + buf.length, 0);
230
+ // Message format:
231
+ // Header (16) + responseFlags (4) + cursorID (8) + startingFrom (4) + numberReturned (4) + documents
232
+ const messageLength = 16 + 4 + 8 + 4 + 4 + totalDocsSize;
233
+ const buffer = Buffer.alloc(messageLength);
234
+ let offset = 0;
235
+ // Write header
236
+ buffer.writeInt32LE(messageLength, offset); // messageLength
237
+ offset += 4;
238
+ buffer.writeInt32LE(requestID, offset); // requestID
239
+ offset += 4;
240
+ buffer.writeInt32LE(responseTo, offset); // responseTo
241
+ offset += 4;
242
+ buffer.writeInt32LE(OP_REPLY, offset); // opCode
243
+ offset += 4;
244
+ // Write OP_REPLY fields
245
+ buffer.writeInt32LE(0, offset); // responseFlags (0 = no errors)
246
+ offset += 4;
247
+ buffer.writeBigInt64LE(cursorId, offset); // cursorID
248
+ offset += 8;
249
+ buffer.writeInt32LE(0, offset); // startingFrom
250
+ offset += 4;
251
+ buffer.writeInt32LE(documents.length, offset); // numberReturned
252
+ offset += 4;
253
+ // Write documents
254
+ for (const docBuffer of docBuffers) {
255
+ Buffer.from(docBuffer).copy(buffer, offset);
256
+ offset += docBuffer.length;
257
+ }
258
+ return buffer;
259
+ }
260
+ /**
261
+ * Encode an error response
262
+ */
263
+ static encodeErrorResponse(responseTo, errorCode, errorMessage, commandName) {
264
+ const response = {
265
+ ok: 0,
266
+ errmsg: errorMessage,
267
+ code: errorCode,
268
+ codeName: this.getErrorCodeName(errorCode),
269
+ };
270
+ return this.encodeOpMsgResponse(responseTo, response);
271
+ }
272
+ /**
273
+ * Get error code name from error code
274
+ */
275
+ static getErrorCodeName(code) {
276
+ const errorNames = {
277
+ 0: 'OK',
278
+ 1: 'InternalError',
279
+ 2: 'BadValue',
280
+ 11000: 'DuplicateKey',
281
+ 11001: 'DuplicateKeyValue',
282
+ 13: 'Unauthorized',
283
+ 26: 'NamespaceNotFound',
284
+ 27: 'IndexNotFound',
285
+ 48: 'NamespaceExists',
286
+ 59: 'CommandNotFound',
287
+ 66: 'ImmutableField',
288
+ 73: 'InvalidNamespace',
289
+ 85: 'IndexOptionsConflict',
290
+ 112: 'WriteConflict',
291
+ 121: 'DocumentValidationFailure',
292
+ 211: 'KeyNotFound',
293
+ 251: 'NoSuchTransaction',
294
+ };
295
+ return errorNames[code] || 'UnknownError';
296
+ }
297
+ }
298
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiV2lyZVByb3RvY29sLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvdHNtZGIvc2VydmVyL1dpcmVQcm90b2NvbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLHFCQUFxQixDQUFDO0FBRS9DOzs7Ozs7Ozs7O0dBVUc7QUFFSCxVQUFVO0FBQ1YsTUFBTSxDQUFDLE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBQyxDQUFRLGVBQWU7QUFDakQsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxDQUFJLGdCQUFnQjtBQUNsRCxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLENBQUksZ0JBQWdCO0FBQ2xELE1BQU0sQ0FBQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsQ0FBSyxrREFBa0Q7QUFDcEYsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxDQUFFLGlCQUFpQjtBQUNuRCxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLENBQUksZ0JBQWdCO0FBQ2xELE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsQ0FBQyxzQkFBc0I7QUFDM0QsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxDQUFHLHFCQUFxQjtBQUMxRCxNQUFNLENBQUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLENBQU8saUNBQWlDO0FBRW5FLHVCQUF1QjtBQUN2QixNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsQ0FBQyxDQUFDLENBQVcsdUJBQXVCO0FBQ2hFLE1BQU0sQ0FBQyxNQUFNLHlCQUF5QixHQUFHLENBQUMsQ0FBQyxDQUFDLHdDQUF3QztBQUVwRixtQkFBbUI7QUFDbkIsTUFBTSxDQUFDLE1BQU0seUJBQXlCLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNoRCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLElB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
@@ -1,4 +1,4 @@
1
- import * as plugins from '../../congodb.plugins.js';
1
+ import * as plugins from '../../tsmdb.plugins.js';
2
2
  import type { ICommandHandler, IHandlerContext } from '../CommandRouter.js';
3
3
  /**
4
4
  * AdminHandler - Handles administrative commands