@lossless.org/nosqldb 8.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.
- package/.smartconfig.json +107 -0
- package/dist_rust/rustdb_linux_amd64 +0 -0
- package/dist_rust/rustdb_linux_amd64.tsrust-build.json +14 -0
- package/dist_rust/rustdb_linux_arm64 +0 -0
- package/dist_rust/rustdb_linux_arm64.tsrust-build.json +14 -0
- package/dist_rust/rustdb_macos_amd64 +0 -0
- package/dist_rust/rustdb_macos_amd64.tsrust-build.json +14 -0
- package/dist_rust/rustdb_macos_arm64 +0 -0
- package/dist_rust/rustdb_macos_arm64.tsrust-build.json +14 -0
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/index.d.ts +8 -0
- package/dist_ts/index.js +10 -0
- package/dist_ts/ts_local/classes.localnosqldb.d.ts +119 -0
- package/dist_ts/ts_local/classes.localnosqldb.js +386 -0
- package/dist_ts/ts_local/index.d.ts +5 -0
- package/dist_ts/ts_local/index.js +3 -0
- package/dist_ts/ts_local/plugins.d.ts +1 -0
- package/dist_ts/ts_local/plugins.js +3 -0
- package/dist_ts/ts_nosqldb/classes.storagerehearsal.d.ts +19 -0
- package/dist_ts/ts_nosqldb/classes.storagerehearsal.js +122 -0
- package/dist_ts/ts_nosqldb/file-storage-options.d.ts +13 -0
- package/dist_ts/ts_nosqldb/file-storage-options.js +24 -0
- package/dist_ts/ts_nosqldb/file-storage-startup.d.ts +3 -0
- package/dist_ts/ts_nosqldb/file-storage-startup.js +6 -0
- package/dist_ts/ts_nosqldb/index.d.ts +14 -0
- package/dist_ts/ts_nosqldb/index.js +11 -0
- package/dist_ts/ts_nosqldb/offline-inspection.d.ts +72 -0
- package/dist_ts/ts_nosqldb/offline-inspection.js +282 -0
- package/dist_ts/ts_nosqldb/plugins.d.ts +7 -0
- package/dist_ts/ts_nosqldb/plugins.js +10 -0
- package/dist_ts/ts_nosqldb/resource-fencing.d.ts +39 -0
- package/dist_ts/ts_nosqldb/resource-fencing.js +271 -0
- package/dist_ts/ts_nosqldb/rust-db-bridge.d.ts +213 -0
- package/dist_ts/ts_nosqldb/rust-db-bridge.js +439 -0
- package/dist_ts/ts_nosqldb/server/classes.nosqldbserver.d.ts +204 -0
- package/dist_ts/ts_nosqldb/server/classes.nosqldbserver.js +456 -0
- package/dist_ts/ts_nosqldb/server/index.d.ts +3 -0
- package/dist_ts/ts_nosqldb/server/index.js +3 -0
- package/dist_ts/ts_nosqldb/service-types.d.ts +341 -0
- package/dist_ts/ts_nosqldb/service-types.js +62 -0
- package/dist_ts/ts_nosqldb/storage-rehearsal.d.ts +103 -0
- package/dist_ts/ts_nosqldb/storage-rehearsal.js +131 -0
- package/dist_ts/ts_nosqldb/storage-root-relocation.d.ts +27 -0
- package/dist_ts/ts_nosqldb/storage-root-relocation.js +211 -0
- package/dist_ts_debugserver/bundled.d.ts +4 -0
- package/dist_ts_debugserver/bundled.js +16 -0
- package/dist_ts_debugserver/classes.debugserver.d.ts +36 -0
- package/dist_ts_debugserver/classes.debugserver.js +95 -0
- package/dist_ts_debugserver/index.d.ts +2 -0
- package/dist_ts_debugserver/index.js +2 -0
- package/dist_ts_debugserver/plugins.d.ts +2 -0
- package/dist_ts_debugserver/plugins.js +3 -0
- package/dist_ts_debugui/index.d.ts +2 -0
- package/dist_ts_debugui/index.js +2 -0
- package/dist_ts_debugui/nosqldb-debugui.d.ts +62 -0
- package/dist_ts_debugui/nosqldb-debugui.js +1132 -0
- package/dist_ts_debugui/plugins.d.ts +1 -0
- package/dist_ts_debugui/plugins.js +2 -0
- package/license +21 -0
- package/package.json +82 -0
- package/readme.md +1733 -0
- package/third-party-notices.md +925 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/index.ts +85 -0
- package/ts/ts_local/classes.localnosqldb.ts +500 -0
- package/ts/ts_local/index.ts +19 -0
- package/ts/ts_local/plugins.ts +1 -0
- package/ts/ts_nosqldb/classes.storagerehearsal.ts +109 -0
- package/ts/ts_nosqldb/file-storage-options.ts +33 -0
- package/ts/ts_nosqldb/file-storage-startup.ts +9 -0
- package/ts/ts_nosqldb/index.ts +104 -0
- package/ts/ts_nosqldb/offline-inspection.ts +375 -0
- package/ts/ts_nosqldb/plugins.ts +12 -0
- package/ts/ts_nosqldb/resource-fencing.ts +368 -0
- package/ts/ts_nosqldb/rust-db-bridge.ts +964 -0
- package/ts/ts_nosqldb/server/classes.nosqldbserver.ts +696 -0
- package/ts/ts_nosqldb/server/index.ts +4 -0
- package/ts/ts_nosqldb/service-types.ts +484 -0
- package/ts/ts_nosqldb/storage-rehearsal.ts +215 -0
- package/ts/ts_nosqldb/storage-root-relocation.ts +277 -0
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
import { RustDbBridge, NoSqlDbManagementOperationTerminationError, } from '../rust-db-bridge.js';
|
|
2
|
+
import { validateNoSqlDbManagementOperationOptions } from '../offline-inspection.js';
|
|
3
|
+
import { validateNoSqlDbStorageRehearsalStartup } from '../storage-rehearsal.js';
|
|
4
|
+
import { assertNoLocalNoSqlDbStorageRootRelocationWorkspace } from '../storage-root-relocation.js';
|
|
5
|
+
import {} from '../file-storage-startup.js';
|
|
6
|
+
import { normalizeNoSqlDbFileStorageOptions, } from '../file-storage-options.js';
|
|
7
|
+
/**
|
|
8
|
+
* NoSqlDbServer - Wire protocol compatible database server backed by Rust
|
|
9
|
+
*
|
|
10
|
+
* This server implements the wire protocol to allow official drivers to
|
|
11
|
+
* connect and perform operations. The core engine runs as a Rust sidecar
|
|
12
|
+
* binary managed via @push.rocks/smartrust IPC.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { NoSqlDbServer } from '@lossless.org/nosqldb';
|
|
17
|
+
* import { MongoClient } from 'mongodb';
|
|
18
|
+
*
|
|
19
|
+
* const server = new NoSqlDbServer({ port: 27017 });
|
|
20
|
+
* await server.start();
|
|
21
|
+
*
|
|
22
|
+
* const client = new MongoClient(server.getConnectionUri());
|
|
23
|
+
* await client.connect();
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export class NoSqlDbServer {
|
|
27
|
+
constructor(options = {}) {
|
|
28
|
+
this.bridgeOwned = false;
|
|
29
|
+
this.startInProgress = false;
|
|
30
|
+
this.startCompletionPromise = null;
|
|
31
|
+
this.isRunning = false;
|
|
32
|
+
this.resolvedConnectionUri = '';
|
|
33
|
+
validateNoSqlDbStorageRehearsalStartup(options);
|
|
34
|
+
const fileStorage = normalizeNoSqlDbFileStorageOptions(options);
|
|
35
|
+
this.options = {
|
|
36
|
+
binaryPath: options.binaryPath,
|
|
37
|
+
storageRehearsalId: options.storageRehearsalId,
|
|
38
|
+
...fileStorage,
|
|
39
|
+
port: options.port ?? 27017,
|
|
40
|
+
host: options.host ?? '127.0.0.1',
|
|
41
|
+
socketPath: options.socketPath,
|
|
42
|
+
storage: options.storage ?? 'memory',
|
|
43
|
+
storagePath: options.storagePath ?? './data',
|
|
44
|
+
auth: options.auth,
|
|
45
|
+
tls: options.tls,
|
|
46
|
+
oplog: options.oplog,
|
|
47
|
+
query: options.query,
|
|
48
|
+
};
|
|
49
|
+
this.bridge = new RustDbBridge({ binaryPath: this.options.binaryPath });
|
|
50
|
+
this.bridge.on('exit', (code, signal) => {
|
|
51
|
+
const exitedUnexpectedly = this.isRunning;
|
|
52
|
+
this.isRunning = false;
|
|
53
|
+
this.bridgeOwned = false;
|
|
54
|
+
this.resolvedConnectionUri = '';
|
|
55
|
+
this.resolvedPort = undefined;
|
|
56
|
+
if (exitedUnexpectedly) {
|
|
57
|
+
console.error(`nosqldb Rust process exited unexpectedly (code=${code}, signal=${signal})`);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Start the server
|
|
63
|
+
*/
|
|
64
|
+
async start(optionsArg) {
|
|
65
|
+
validateNoSqlDbManagementOperationOptions(optionsArg);
|
|
66
|
+
optionsArg?.signal?.throwIfAborted();
|
|
67
|
+
if (this.isRunning || this.startInProgress || this.bridgeOwned) {
|
|
68
|
+
throw new Error('Server is already running or still owns a Rust bridge');
|
|
69
|
+
}
|
|
70
|
+
const startupStartedAt = Date.now();
|
|
71
|
+
const startupDeadline = optionsArg?.timeoutMs === undefined
|
|
72
|
+
? undefined
|
|
73
|
+
: startupStartedAt + optionsArg.timeoutMs;
|
|
74
|
+
const timeoutError = new DOMException(optionsArg?.timeoutMs === undefined
|
|
75
|
+
? 'NoSQLDB startup timed out'
|
|
76
|
+
: `NoSQLDB startup timed out after ${optionsArg.timeoutMs}ms`, 'TimeoutError');
|
|
77
|
+
const startupAbortController = new AbortController();
|
|
78
|
+
let startupTimeout;
|
|
79
|
+
let externalAbortHandler;
|
|
80
|
+
if (optionsArg?.signal) {
|
|
81
|
+
externalAbortHandler = () => {
|
|
82
|
+
startupAbortController.abort(optionsArg.signal.reason);
|
|
83
|
+
};
|
|
84
|
+
optionsArg.signal.addEventListener('abort', externalAbortHandler, { once: true });
|
|
85
|
+
}
|
|
86
|
+
if (optionsArg?.timeoutMs !== undefined) {
|
|
87
|
+
startupTimeout = setTimeout(() => {
|
|
88
|
+
startupAbortController.abort(timeoutError);
|
|
89
|
+
}, optionsArg.timeoutMs);
|
|
90
|
+
}
|
|
91
|
+
const checkpoint = () => {
|
|
92
|
+
if (startupDeadline !== undefined
|
|
93
|
+
&& Date.now() >= startupDeadline
|
|
94
|
+
&& !startupAbortController.signal.aborted) {
|
|
95
|
+
startupAbortController.abort(timeoutError);
|
|
96
|
+
}
|
|
97
|
+
startupAbortController.signal.throwIfAborted();
|
|
98
|
+
};
|
|
99
|
+
const getBridgeOperationOptions = () => {
|
|
100
|
+
checkpoint();
|
|
101
|
+
const remainingTimeoutMs = startupDeadline === undefined
|
|
102
|
+
? undefined
|
|
103
|
+
: startupDeadline - Date.now();
|
|
104
|
+
if (remainingTimeoutMs !== undefined && remainingTimeoutMs <= 0) {
|
|
105
|
+
startupAbortController.abort(timeoutError);
|
|
106
|
+
checkpoint();
|
|
107
|
+
}
|
|
108
|
+
if (!optionsArg?.signal && remainingTimeoutMs === undefined)
|
|
109
|
+
return undefined;
|
|
110
|
+
return {
|
|
111
|
+
...(optionsArg?.signal ? { signal: optionsArg.signal } : {}),
|
|
112
|
+
...(remainingTimeoutMs === undefined ? {} : { timeoutMs: remainingTimeoutMs }),
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
this.startInProgress = true;
|
|
116
|
+
let resolveStartCompletion;
|
|
117
|
+
const startCompletionPromise = new Promise((resolveArg) => {
|
|
118
|
+
resolveStartCompletion = resolveArg;
|
|
119
|
+
});
|
|
120
|
+
this.startCompletionPromise = startCompletionPromise;
|
|
121
|
+
try {
|
|
122
|
+
checkpoint();
|
|
123
|
+
// Relocation workspace admission is read-only; the native owner alone
|
|
124
|
+
// classifies and initializes storage after acquiring its root lease.
|
|
125
|
+
if (this.options.storage === 'file' && this.options.storagePath) {
|
|
126
|
+
await assertNoLocalNoSqlDbStorageRootRelocationWorkspace(this.options.storagePath);
|
|
127
|
+
checkpoint();
|
|
128
|
+
}
|
|
129
|
+
// Ownership starts before spawn because a rejected spawn can still have
|
|
130
|
+
// created a child whose termination must be confirmed.
|
|
131
|
+
this.bridgeOwned = true;
|
|
132
|
+
const spawned = await this.bridge.spawn(getBridgeOperationOptions());
|
|
133
|
+
checkpoint();
|
|
134
|
+
if (!spawned) {
|
|
135
|
+
throw new Error('nosqldb Rust binary not found. Set NOSQLDB_RUST_BINARY env var, ' +
|
|
136
|
+
'install the platform package, or build locally with `tsrust`.');
|
|
137
|
+
}
|
|
138
|
+
// Send config, get back connectionUri
|
|
139
|
+
const result = await this.bridge.startDb({
|
|
140
|
+
port: this.options.port,
|
|
141
|
+
host: this.options.host,
|
|
142
|
+
socketPath: this.options.socketPath,
|
|
143
|
+
storage: this.options.storage ?? 'memory',
|
|
144
|
+
storagePath: this.options.storagePath,
|
|
145
|
+
storageRehearsalId: this.options.storageRehearsalId,
|
|
146
|
+
auth: this.options.auth,
|
|
147
|
+
tls: this.options.tls,
|
|
148
|
+
oplog: this.options.oplog,
|
|
149
|
+
query: this.options.query,
|
|
150
|
+
}, getBridgeOperationOptions());
|
|
151
|
+
checkpoint();
|
|
152
|
+
if (!this.bridgeOwned || !this.bridge.running) {
|
|
153
|
+
throw new Error('nosqldb Rust process exited during startup');
|
|
154
|
+
}
|
|
155
|
+
if (!this.options.socketPath) {
|
|
156
|
+
const connectionUrl = new URL(result.connectionUri);
|
|
157
|
+
const resolvedPort = Number(connectionUrl.port);
|
|
158
|
+
if (connectionUrl.protocol !== 'mongodb:'
|
|
159
|
+
|| !connectionUrl.hostname
|
|
160
|
+
|| !Number.isInteger(resolvedPort)
|
|
161
|
+
|| resolvedPort < 1
|
|
162
|
+
|| resolvedPort > 65_535) {
|
|
163
|
+
throw new Error(`nosqldb returned an invalid TCP connection URI: ${result.connectionUri}`);
|
|
164
|
+
}
|
|
165
|
+
this.resolvedPort = resolvedPort;
|
|
166
|
+
}
|
|
167
|
+
this.resolvedConnectionUri = result.connectionUri;
|
|
168
|
+
checkpoint();
|
|
169
|
+
this.isRunning = true;
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
const startupError = error instanceof NoSqlDbManagementOperationTerminationError
|
|
173
|
+
? error
|
|
174
|
+
: optionsArg?.signal?.aborted
|
|
175
|
+
? optionsArg.signal.reason
|
|
176
|
+
: startupAbortController.signal.aborted || (startupDeadline !== undefined && Date.now() >= startupDeadline)
|
|
177
|
+
? timeoutError
|
|
178
|
+
: error;
|
|
179
|
+
this.isRunning = false;
|
|
180
|
+
this.resolvedConnectionUri = '';
|
|
181
|
+
this.resolvedPort = undefined;
|
|
182
|
+
if (this.bridgeOwned) {
|
|
183
|
+
try {
|
|
184
|
+
await this.bridge.terminate();
|
|
185
|
+
this.bridgeOwned = false;
|
|
186
|
+
}
|
|
187
|
+
catch (cleanupError) {
|
|
188
|
+
throw new AggregateError([startupError, cleanupError], 'NoSQLDB startup failed and Rust bridge cleanup was incomplete', { cause: startupError });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
throw startupError;
|
|
192
|
+
}
|
|
193
|
+
finally {
|
|
194
|
+
if (startupTimeout)
|
|
195
|
+
clearTimeout(startupTimeout);
|
|
196
|
+
if (externalAbortHandler && optionsArg?.signal) {
|
|
197
|
+
optionsArg.signal.removeEventListener('abort', externalAbortHandler);
|
|
198
|
+
}
|
|
199
|
+
this.startInProgress = false;
|
|
200
|
+
resolveStartCompletion();
|
|
201
|
+
if (this.startCompletionPromise === startCompletionPromise) {
|
|
202
|
+
this.startCompletionPromise = null;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Stop the server
|
|
208
|
+
*/
|
|
209
|
+
async stop() {
|
|
210
|
+
const startCompletionPromise = this.startCompletionPromise;
|
|
211
|
+
if (startCompletionPromise) {
|
|
212
|
+
await startCompletionPromise;
|
|
213
|
+
}
|
|
214
|
+
if (!this.isRunning && !this.bridgeOwned) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const requestGracefulStop = this.isRunning && this.bridge.running;
|
|
218
|
+
this.isRunning = false;
|
|
219
|
+
this.resolvedConnectionUri = '';
|
|
220
|
+
this.resolvedPort = undefined;
|
|
221
|
+
if (requestGracefulStop) {
|
|
222
|
+
try {
|
|
223
|
+
await this.bridge.stopDb();
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
// Confirmed bridge termination below still releases the owned process.
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
await this.bridge.terminate();
|
|
230
|
+
this.bridgeOwned = false;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Get the connection URI for this server
|
|
234
|
+
*/
|
|
235
|
+
getConnectionUri() {
|
|
236
|
+
if (this.resolvedConnectionUri) {
|
|
237
|
+
return this.resolvedConnectionUri;
|
|
238
|
+
}
|
|
239
|
+
// Fallback: compute from options
|
|
240
|
+
if (this.options.socketPath) {
|
|
241
|
+
const encodedPath = encodeURIComponent(this.options.socketPath);
|
|
242
|
+
return `mongodb://${encodedPath}`;
|
|
243
|
+
}
|
|
244
|
+
const baseUri = `mongodb://${this.options.host ?? '127.0.0.1'}:${this.options.port ?? 27017}`;
|
|
245
|
+
return this.options.tls?.enabled ? `${baseUri}/?tls=true` : baseUri;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Get the socket path (if using Unix socket mode)
|
|
249
|
+
*/
|
|
250
|
+
get socketPath() {
|
|
251
|
+
return this.options.socketPath;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Check if the server is running
|
|
255
|
+
*/
|
|
256
|
+
/** Process id of the spawned Rust engine, when it runs as a child process. */
|
|
257
|
+
get processId() {
|
|
258
|
+
return this.bridge.processId;
|
|
259
|
+
}
|
|
260
|
+
get running() {
|
|
261
|
+
return this.isRunning;
|
|
262
|
+
}
|
|
263
|
+
async runDatabaseManagementOperation(operationArg) {
|
|
264
|
+
try {
|
|
265
|
+
return await operationArg();
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
if (!this.bridge.running
|
|
269
|
+
|| error instanceof NoSqlDbManagementOperationTerminationError) {
|
|
270
|
+
this.isRunning = false;
|
|
271
|
+
this.resolvedConnectionUri = '';
|
|
272
|
+
this.resolvedPort = undefined;
|
|
273
|
+
if (this.bridge.ownershipReleased) {
|
|
274
|
+
this.bridgeOwned = false;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
throw error;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Get the port the server is listening on
|
|
282
|
+
*/
|
|
283
|
+
get port() {
|
|
284
|
+
return this.resolvedPort ?? this.options.port ?? 27017;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Get the host the server is bound to
|
|
288
|
+
*/
|
|
289
|
+
get host() {
|
|
290
|
+
return this.options.host ?? '127.0.0.1';
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Create an isolated database/user pair for an application tenant.
|
|
294
|
+
*/
|
|
295
|
+
async createDatabaseTenant(params) {
|
|
296
|
+
const descriptor = await this.bridge.createDatabaseTenant(params);
|
|
297
|
+
return this.withTenantMongoUri(descriptor, params.password);
|
|
298
|
+
}
|
|
299
|
+
/** Authoritatively allocate an absent, fenced database tenant. */
|
|
300
|
+
async allocateDatabaseTenant(params, optionsArg) {
|
|
301
|
+
const descriptor = await this.runDatabaseManagementOperation(() => this.bridge.allocateDatabaseTenant(params, optionsArg));
|
|
302
|
+
return this.withTenantMongoUri(descriptor, params.password);
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Idempotently provision or rotate one exclusively owned database tenant.
|
|
306
|
+
*/
|
|
307
|
+
async ensureDatabaseTenant(params, optionsArg) {
|
|
308
|
+
const descriptor = await this.runDatabaseManagementOperation(() => this.bridge.ensureDatabaseTenant(params, optionsArg));
|
|
309
|
+
return this.withTenantMongoUri(descriptor, params.password);
|
|
310
|
+
}
|
|
311
|
+
/** Verify an exact tenant credential without changing provider state. */
|
|
312
|
+
async attestDatabaseTenant(params, optionsArg) {
|
|
313
|
+
return this.runDatabaseManagementOperation(() => this.bridge.attestDatabaseTenant(params, optionsArg));
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Delete a tenant database and its tenant user(s).
|
|
317
|
+
*/
|
|
318
|
+
async deleteDatabaseTenant(params, optionsArg) {
|
|
319
|
+
return this.runDatabaseManagementOperation(() => this.bridge.deleteDatabaseTenant(params, optionsArg));
|
|
320
|
+
}
|
|
321
|
+
/** Issue one fixed-expiry read grant bound to an exact active allocation. */
|
|
322
|
+
async issueDatabaseAllocationReadAccessGrant(params, optionsArg) {
|
|
323
|
+
const descriptor = await this.runDatabaseManagementOperation(() => this.bridge.issueDatabaseAllocationReadAccessGrant(params, optionsArg));
|
|
324
|
+
return this.withTenantMongoUri(descriptor, params.password);
|
|
325
|
+
}
|
|
326
|
+
/** Idempotently revoke one allocation read grant without returning a secret. */
|
|
327
|
+
async revokeDatabaseAllocationReadAccessGrant(params, optionsArg) {
|
|
328
|
+
return this.runDatabaseManagementOperation(() => this.bridge.revokeDatabaseAllocationReadAccessGrant(params, optionsArg));
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Rotate a tenant user's password without restarting the server.
|
|
332
|
+
*/
|
|
333
|
+
async rotateDatabaseTenantPassword(params) {
|
|
334
|
+
const descriptor = await this.bridge.rotateDatabaseTenantPassword(params);
|
|
335
|
+
return this.withTenantMongoUri(descriptor, params.password);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* List known database tenants.
|
|
339
|
+
*/
|
|
340
|
+
async listDatabaseTenants() {
|
|
341
|
+
return this.bridge.listDatabaseTenants();
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Get a tenant descriptor without exposing a password.
|
|
345
|
+
*/
|
|
346
|
+
async getDatabaseTenantDescriptor(params) {
|
|
347
|
+
return this.bridge.getDatabaseTenantDescriptor(params);
|
|
348
|
+
}
|
|
349
|
+
/** Inspect the durable high-water mark without exposing mutation receipts. */
|
|
350
|
+
async getDatabaseResourceFenceState(params, optionsArg) {
|
|
351
|
+
return this.runDatabaseManagementOperation(() => this.bridge.getDatabaseResourceFenceState(params, optionsArg));
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Export one database as an Extended JSON snapshot.
|
|
355
|
+
*/
|
|
356
|
+
async exportDatabase(params, optionsArg) {
|
|
357
|
+
return this.runDatabaseManagementOperation(() => this.bridge.exportDatabase(params, optionsArg));
|
|
358
|
+
}
|
|
359
|
+
/** Compute a bounded, database-name-independent digest of logical database content. */
|
|
360
|
+
async getDatabaseContentDigest(params, optionsArg) {
|
|
361
|
+
return this.runDatabaseManagementOperation(() => this.bridge.getDatabaseContentDigest(params, optionsArg));
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Replace one database with a previously exported snapshot.
|
|
365
|
+
*/
|
|
366
|
+
async importDatabase(params, optionsArg) {
|
|
367
|
+
return this.runDatabaseManagementOperation(() => this.bridge.importDatabase(params, optionsArg));
|
|
368
|
+
}
|
|
369
|
+
/** Release an exact held database publication after downstream fsync. */
|
|
370
|
+
async commitDatabasePublication(params, optionsArg) {
|
|
371
|
+
return this.runDatabaseManagementOperation(() => this.bridge.commitDatabasePublication(params, optionsArg));
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Get readiness/health details for long-running service use.
|
|
375
|
+
*/
|
|
376
|
+
async getHealth(optionsArg) {
|
|
377
|
+
if (!this.isRunning) {
|
|
378
|
+
return {
|
|
379
|
+
running: false,
|
|
380
|
+
storage: this.options.storage,
|
|
381
|
+
storagePath: this.options.storage === 'file' ? this.options.storagePath : undefined,
|
|
382
|
+
resourceFencingVersion: this.options.storage === 'file' ? 1 : undefined,
|
|
383
|
+
resourceFencingSupported: this.options.storage === 'file' ? false : undefined,
|
|
384
|
+
resourceFencingRequiresDrain: this.options.storage === 'file' ? true : undefined,
|
|
385
|
+
allocationFencingVersion: this.options.storage === 'file' ? 1 : undefined,
|
|
386
|
+
allocationFencingSupported: this.options.storage === 'file' ? false : undefined,
|
|
387
|
+
allocationFencingRequiresDrain: this.options.storage === 'file' ? true : undefined,
|
|
388
|
+
publicationHoldVersion: 1,
|
|
389
|
+
publicationHoldSupported: false,
|
|
390
|
+
publicationHoldRequiresExternalDrain: false,
|
|
391
|
+
authEnabled: Boolean(this.options.auth?.enabled),
|
|
392
|
+
authUsers: this.options.auth?.users?.length ?? 0,
|
|
393
|
+
usersPathConfigured: false,
|
|
394
|
+
databaseCount: 0,
|
|
395
|
+
collectionCount: 0,
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
return this.runDatabaseManagementOperation(() => this.bridge.getHealth(optionsArg));
|
|
399
|
+
}
|
|
400
|
+
// --- OpLog / Debug API ---
|
|
401
|
+
/**
|
|
402
|
+
* Get oplog entries, optionally filtered.
|
|
403
|
+
*/
|
|
404
|
+
async getOpLog(params = {}) {
|
|
405
|
+
return this.bridge.getOpLog(params);
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Get aggregate oplog statistics.
|
|
409
|
+
*/
|
|
410
|
+
async getOpLogStats() {
|
|
411
|
+
return this.bridge.getOpLogStats();
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Revert database state to a specific oplog sequence number.
|
|
415
|
+
* Use dryRun=true to preview which entries would be reverted.
|
|
416
|
+
*/
|
|
417
|
+
async revertToSeq(seq, dryRun = false) {
|
|
418
|
+
return this.bridge.revertToSeq(seq, dryRun);
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* List all collections across all databases, with document counts.
|
|
422
|
+
*/
|
|
423
|
+
async getCollections(db) {
|
|
424
|
+
return this.bridge.getCollections(db);
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Get documents from a collection with pagination.
|
|
428
|
+
*/
|
|
429
|
+
async getDocuments(db, collection, limit = 50, skip = 0) {
|
|
430
|
+
return this.bridge.getDocuments(db, collection, limit, skip);
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Get server metrics including database/collection counts and oplog info.
|
|
434
|
+
*/
|
|
435
|
+
async getMetrics() {
|
|
436
|
+
return this.bridge.getMetrics();
|
|
437
|
+
}
|
|
438
|
+
withTenantMongoUri(descriptor, password) {
|
|
439
|
+
return {
|
|
440
|
+
...descriptor,
|
|
441
|
+
mongodbUri: this.buildTenantMongoUri(descriptor.databaseName, descriptor.username, password),
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
buildTenantMongoUri(databaseName, username, password) {
|
|
445
|
+
const host = this.options.socketPath
|
|
446
|
+
? encodeURIComponent(this.options.socketPath)
|
|
447
|
+
: `${this.options.host ?? '127.0.0.1'}:${this.options.port ?? 27017}`;
|
|
448
|
+
const auth = `${encodeURIComponent(username)}:${encodeURIComponent(password)}@`;
|
|
449
|
+
const query = new URLSearchParams({ authSource: databaseName });
|
|
450
|
+
if (this.options.tls?.enabled) {
|
|
451
|
+
query.set('tls', 'true');
|
|
452
|
+
}
|
|
453
|
+
return `mongodb://${auth}${host}/${encodeURIComponent(databaseName)}?${query.toString()}`;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5ub3NxbGRic2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvdHNfbm9zcWxkYi9zZXJ2ZXIvY2xhc3Nlcy5ub3NxbGRic2VydmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxZQUFZLEVBQ1osMENBQTBDLEdBQzNDLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUFFLHlDQUF5QyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckYsT0FBTyxFQUFFLHNDQUFzQyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDakYsT0FBTyxFQUFFLGtEQUFrRCxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDbkcsT0FBTyxFQUVOLE1BQU0sNEJBQTRCLENBQUM7QUFDcEMsT0FBTyxFQUNMLGtDQUFrQyxHQUNuQyxNQUFNLDRCQUE0QixDQUFDO0FBa0dwQzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBQ0gsTUFBTSxPQUFPLGFBQWE7SUFVeEIsWUFBWSxVQUFpQyxFQUFFO1FBUHZDLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1FBQ3BCLG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLDJCQUFzQixHQUF5QixJQUFJLENBQUM7UUFDcEQsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNsQiwwQkFBcUIsR0FBRyxFQUFFLENBQUM7UUFJakMsc0NBQXNDLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDaEQsTUFBTSxXQUFXLEdBQUcsa0NBQWtDLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLE9BQU8sR0FBRztZQUNiLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVTtZQUM5QixrQkFBa0IsRUFBRSxPQUFPLENBQUMsa0JBQWtCO1lBQzlDLEdBQUcsV0FBVztZQUNkLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxJQUFJLEtBQUs7WUFDM0IsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJLElBQUksV0FB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
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Server module exports
|
|
2
|
+
export { NoSqlDbServer } from './classes.nosqldbserver.js';
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy90c19ub3NxbGRiL3NlcnZlci9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx3QkFBd0I7QUFDeEIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDIn0=
|