@mongosh/service-provider-node-driver 2.3.3
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/.depcheckrc +20 -0
- package/.eslintignore +2 -0
- package/.eslintrc.js +10 -0
- package/.prettierignore +6 -0
- package/.prettierrc.json +1 -0
- package/AUTHORS +3 -0
- package/LICENSE +201 -0
- package/lib/compass/compass-service-provider.d.ts +11 -0
- package/lib/compass/compass-service-provider.js +12 -0
- package/lib/compass/compass-service-provider.js.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.js +8 -0
- package/lib/index.js.map +1 -0
- package/lib/mongodb-patches.d.ts +4 -0
- package/lib/mongodb-patches.js +18 -0
- package/lib/mongodb-patches.js.map +1 -0
- package/lib/node-driver-service-provider.d.ts +107 -0
- package/lib/node-driver-service-provider.js +622 -0
- package/lib/node-driver-service-provider.js.map +1 -0
- package/package.json +76 -0
- package/src/compass/compass-service-provider.ts +30 -0
- package/src/index.ts +4 -0
- package/src/mongodb-patches.spec.ts +67 -0
- package/src/mongodb-patches.ts +25 -0
- package/src/node-driver-provider.integration.spec.ts +841 -0
- package/src/node-driver-service-provider.spec.ts +1302 -0
- package/src/node-driver-service-provider.ts +1536 -0
- package/tsconfig-lint.json +5 -0
- package/tsconfig.json +8 -0
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mongosh/service-provider-node-driver",
|
|
3
|
+
"version": "2.3.3",
|
|
4
|
+
"description": "MongoDB Shell Server Service Provider Package",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
|
+
"config": {
|
|
8
|
+
"unsafe-perm": true
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git://github.com/mongodb-js/mongosh.git"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"compile": "tsc -p tsconfig.json",
|
|
16
|
+
"test": "mocha -r \"../../scripts/import-expansions.js\" --timeout 60000 -r ts-node/register --reporter \"../../configs/mocha-config-mongosh/reporter.ts\" \"./src/**/*.spec.ts\"",
|
|
17
|
+
"test-ci": "node ../../scripts/run-if-package-requested.js npm test",
|
|
18
|
+
"test-coverage": "nyc --no-clean --cwd ../.. --reporter=none npm run test",
|
|
19
|
+
"test-ci-coverage": "nyc --no-clean --cwd ../.. --reporter=none npm run test-ci",
|
|
20
|
+
"prepublish": "npm run compile",
|
|
21
|
+
"eslint": "eslint",
|
|
22
|
+
"lint": "npm run eslint . && npm run prettier -- --check .",
|
|
23
|
+
"check": "npm run lint && npm run depcheck",
|
|
24
|
+
"depcheck": "depcheck",
|
|
25
|
+
"prettier": "prettier",
|
|
26
|
+
"reformat": "npm run prettier -- --write . && npm run eslint --fix"
|
|
27
|
+
},
|
|
28
|
+
"license": "Apache-2.0",
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=14.15.1"
|
|
34
|
+
},
|
|
35
|
+
"mongosh": {
|
|
36
|
+
"ciRequiredOptionalDependencies": {
|
|
37
|
+
"mongodb-client-encryption": [
|
|
38
|
+
"darwin",
|
|
39
|
+
"linux",
|
|
40
|
+
"win32"
|
|
41
|
+
],
|
|
42
|
+
"kerberos": [
|
|
43
|
+
"darwin",
|
|
44
|
+
"linux",
|
|
45
|
+
"win32"
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@mongodb-js/devtools-connect": "^3.3.0",
|
|
51
|
+
"@mongodb-js/oidc-plugin": "^1.1.1",
|
|
52
|
+
"@mongosh/errors": "2.3.3",
|
|
53
|
+
"@mongosh/service-provider-core": "2.3.3",
|
|
54
|
+
"@mongosh/types": "2.3.3",
|
|
55
|
+
"aws4": "^1.12.0",
|
|
56
|
+
"kerberos": "2.1.0",
|
|
57
|
+
"mongodb": "^6.10.0",
|
|
58
|
+
"mongodb-client-encryption": "^6.1.0",
|
|
59
|
+
"mongodb-connection-string-url": "^3.0.1",
|
|
60
|
+
"socks": "^2.8.3"
|
|
61
|
+
},
|
|
62
|
+
"optionalDependencies": {
|
|
63
|
+
"kerberos": "2.1.0",
|
|
64
|
+
"mongodb-client-encryption": "^6.1.0"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@mongodb-js/eslint-config-mongosh": "2.3.3",
|
|
68
|
+
"@mongodb-js/prettier-config-devtools": "^1.0.1",
|
|
69
|
+
"@mongodb-js/tsconfig-mongosh": "2.3.3",
|
|
70
|
+
"@types/sinon-chai": "^3.2.4",
|
|
71
|
+
"depcheck": "^1.4.7",
|
|
72
|
+
"eslint": "^7.25.0",
|
|
73
|
+
"prettier": "^2.8.8"
|
|
74
|
+
},
|
|
75
|
+
"gitHead": "e78998f6c73b2aefa47cecd09860ff23c49d1971"
|
|
76
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { DevtoolsConnectOptions } from '../node-driver-service-provider';
|
|
2
|
+
import { NodeDriverServiceProvider } from '../node-driver-service-provider';
|
|
3
|
+
import type { MongoClient } from 'mongodb';
|
|
4
|
+
import type { ReplPlatform } from '@mongosh/service-provider-core';
|
|
5
|
+
import type ConnectionString from 'mongodb-connection-string-url';
|
|
6
|
+
import type { EventEmitter } from 'events';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A service provider that is meant to be used in compass.
|
|
10
|
+
*/
|
|
11
|
+
export class CompassServiceProvider extends NodeDriverServiceProvider {
|
|
12
|
+
public readonly platform: ReplPlatform;
|
|
13
|
+
/**
|
|
14
|
+
* Instantiate a new CompassServiceProvider with the data-service's connected
|
|
15
|
+
* MongoClient instance.
|
|
16
|
+
*
|
|
17
|
+
* @param {MongoClient} mongoClient - The Node drivers' MongoClient instance.
|
|
18
|
+
* @param {MongoClientOptions} driverOptions
|
|
19
|
+
* @param {string} uri - optional URI for telemetry.
|
|
20
|
+
*/
|
|
21
|
+
constructor(
|
|
22
|
+
mongoClient: MongoClient,
|
|
23
|
+
bus: EventEmitter,
|
|
24
|
+
driverOptions: DevtoolsConnectOptions,
|
|
25
|
+
uri?: ConnectionString
|
|
26
|
+
) {
|
|
27
|
+
super(mongoClient, bus, driverOptions, uri);
|
|
28
|
+
this.platform = 'Compass';
|
|
29
|
+
}
|
|
30
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { NodeDriverServiceProvider } from './node-driver-service-provider';
|
|
2
|
+
import { CompassServiceProvider } from './compass/compass-service-provider';
|
|
3
|
+
export type { DevtoolsConnectOptions } from '@mongodb-js/devtools-connect';
|
|
4
|
+
export { NodeDriverServiceProvider, CompassServiceProvider };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { MongoClient } from 'mongodb';
|
|
3
|
+
import {
|
|
4
|
+
skipIfServerVersion,
|
|
5
|
+
startSharedTestServer,
|
|
6
|
+
} from '../../../testing/integration-testing-hooks';
|
|
7
|
+
import { forceCloseMongoClient } from './mongodb-patches';
|
|
8
|
+
import { promisify } from 'util';
|
|
9
|
+
|
|
10
|
+
const delay = promisify(setTimeout);
|
|
11
|
+
|
|
12
|
+
describe('forceCloseMongoClient [integration]', function () {
|
|
13
|
+
const testServer = startSharedTestServer();
|
|
14
|
+
|
|
15
|
+
context('for server >= 4.1', function () {
|
|
16
|
+
skipIfServerVersion(testServer, '< 4.1');
|
|
17
|
+
|
|
18
|
+
it('force-closes connections that are currently checked out', async function () {
|
|
19
|
+
if (process.env.MONGOSH_TEST_FORCE_API_STRICT) {
|
|
20
|
+
return this.skip(); // $currentOp is unversioned
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let client = await MongoClient.connect(
|
|
24
|
+
await testServer.connectionString()
|
|
25
|
+
);
|
|
26
|
+
const testDbName = `test-db-${Date.now()}`;
|
|
27
|
+
const testDb = client.db(testDbName);
|
|
28
|
+
|
|
29
|
+
await testDb.collection('ctrlc').insertOne({});
|
|
30
|
+
let err: any;
|
|
31
|
+
testDb
|
|
32
|
+
.collection('ctrlc')
|
|
33
|
+
.find({
|
|
34
|
+
$where: 'while(true) { /* loop1 */ }',
|
|
35
|
+
})
|
|
36
|
+
.toArray()
|
|
37
|
+
.catch((e) => {
|
|
38
|
+
err = e;
|
|
39
|
+
});
|
|
40
|
+
await delay(100);
|
|
41
|
+
const result = await forceCloseMongoClient(client);
|
|
42
|
+
expect(result.forceClosedConnections).to.equal(1);
|
|
43
|
+
await delay(1);
|
|
44
|
+
expect(err.message).to.include('Topology is closed');
|
|
45
|
+
|
|
46
|
+
client = await MongoClient.connect(await testServer.connectionString());
|
|
47
|
+
for (let i = 0; ; i++) {
|
|
48
|
+
const [out] = await client
|
|
49
|
+
.db('admin')
|
|
50
|
+
.aggregate([
|
|
51
|
+
{ $currentOp: {} },
|
|
52
|
+
{ $match: { 'command.find': 'ctrlc' } },
|
|
53
|
+
{ $count: 'waitingCommands' },
|
|
54
|
+
])
|
|
55
|
+
.toArray();
|
|
56
|
+
if (i === 100 || !out?.waitingCommands) {
|
|
57
|
+
expect(out?.waitingCommands || 0).to.equal(0);
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
await delay(100);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
await client.db(testDbName).dropDatabase();
|
|
64
|
+
await client.close();
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { MongoClient } from 'mongodb';
|
|
2
|
+
|
|
3
|
+
// Close a MongoClient + abort currently ongoing operations.
|
|
4
|
+
export function forceCloseMongoClient(
|
|
5
|
+
client: MongoClient
|
|
6
|
+
): Promise<{ forceClosedConnections: number }> {
|
|
7
|
+
let forceClosedConnections = 0;
|
|
8
|
+
for (const server of (client as any).topology?.s?.servers?.values()) {
|
|
9
|
+
const checkedOutConnections = server?.pool?.checkedOutConnections;
|
|
10
|
+
for (const connection of checkedOutConnections ?? []) {
|
|
11
|
+
forceClosedConnections++;
|
|
12
|
+
connection.destroy({ force: true });
|
|
13
|
+
// Immediately after destroying, act as if the close had happened,
|
|
14
|
+
// but *not* as an actual 'close' event on the socket itself --
|
|
15
|
+
// a close on the socket is communicated as a network error, which
|
|
16
|
+
// is considered an retryable error by operations which are currently
|
|
17
|
+
// running on this connection, but the whole point here is that these
|
|
18
|
+
// operations should *not* be retried. So, we just act as if something
|
|
19
|
+
// had happened that interrupts all ongoing operations and also is
|
|
20
|
+
// supposed to destroy the connection (which is a no-op at this point).
|
|
21
|
+
connection.onError(new Error('connection canceled by force close'));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return client.close(true).then(() => ({ forceClosedConnections }));
|
|
25
|
+
}
|