@mongosh/service-provider-core 1.3.1 → 1.5.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/AUTHORS +1 -0
- package/lib/index.d.ts +1 -3
- package/lib/index.js +1 -3
- package/lib/index.js.map +1 -1
- package/lib/readable.d.ts +1 -3
- package/package.json +16 -10
- package/src/index.ts +0 -4
- package/src/readable.ts +0 -32
- package/lib/cli-options.d.ts +0 -43
- package/lib/cli-options.js +0 -3
- package/lib/cli-options.js.map +0 -1
- package/lib/uri-generator.d.ts +0 -8
- package/lib/uri-generator.js +0 -176
- package/lib/uri-generator.js.map +0 -1
- package/src/cli-options.ts +0 -49
- package/src/uri-generator.spec.ts +0 -481
- package/src/uri-generator.ts +0 -265
package/AUTHORS
CHANGED
package/lib/index.d.ts
CHANGED
|
@@ -2,8 +2,6 @@ import './textencoder-polyfill';
|
|
|
2
2
|
import ServiceProvider, { ServiceProviderCore } from './service-provider';
|
|
3
3
|
import getConnectInfo, { ConnectInfo } from './connect-info';
|
|
4
4
|
import { ReplPlatform } from './platform';
|
|
5
|
-
import CliOptions from './cli-options';
|
|
6
|
-
import generateUri from './uri-generator';
|
|
7
5
|
declare const DEFAULT_DB = "test";
|
|
8
6
|
import { ObjectId, DBRef, MaxKey, MinKey, Timestamp, BSONSymbol, Code, Decimal128, Int32, Long, Binary, calculateObjectSize, Double, EJSON, BSONRegExp } from 'bson';
|
|
9
7
|
import { bsonStringifiers } from './printable-bson';
|
|
@@ -28,4 +26,4 @@ declare const bson: {
|
|
|
28
26
|
EJSON: typeof EJSON;
|
|
29
27
|
BSONRegExp: typeof BSONRegExp;
|
|
30
28
|
};
|
|
31
|
-
export { ServiceProvider, ShellAuthOptions, getConnectInfo, ReplPlatform,
|
|
29
|
+
export { ServiceProvider, ShellAuthOptions, getConnectInfo, ReplPlatform, DEFAULT_DB, ServiceProviderCore, bson, bsonStringifiers, ConnectInfo };
|
package/lib/index.js
CHANGED
|
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.bsonStringifiers = exports.bson = exports.ServiceProviderCore = exports.DEFAULT_DB = exports.
|
|
20
|
+
exports.bsonStringifiers = exports.bson = exports.ServiceProviderCore = exports.DEFAULT_DB = exports.ReplPlatform = exports.getConnectInfo = void 0;
|
|
21
21
|
require("./textencoder-polyfill");
|
|
22
22
|
const service_provider_1 = require("./service-provider");
|
|
23
23
|
Object.defineProperty(exports, "ServiceProviderCore", { enumerable: true, get: function () { return service_provider_1.ServiceProviderCore; } });
|
|
@@ -25,8 +25,6 @@ const connect_info_1 = __importDefault(require("./connect-info"));
|
|
|
25
25
|
exports.getConnectInfo = connect_info_1.default;
|
|
26
26
|
const platform_1 = require("./platform");
|
|
27
27
|
Object.defineProperty(exports, "ReplPlatform", { enumerable: true, get: function () { return platform_1.ReplPlatform; } });
|
|
28
|
-
const uri_generator_1 = __importDefault(require("./uri-generator"));
|
|
29
|
-
exports.generateUri = uri_generator_1.default;
|
|
30
28
|
const DEFAULT_DB = 'test';
|
|
31
29
|
exports.DEFAULT_DB = DEFAULT_DB;
|
|
32
30
|
const bson_1 = require("bson");
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,kCAAgC;AAChC,yDAA0E;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,kCAAgC;AAChC,yDAA0E;AAoDxE,oGApDwB,sCAAmB,OAoDxB;AAnDrB,kEAA6D;AAgD3D,yBAhDK,sBAAc,CAgDL;AA/ChB,yCAA0C;AAgDxC,6FAhDO,uBAAY,OAgDP;AA/Cd,MAAM,UAAU,GAAG,MAAM,CAAC;AAgDxB,gCAAU;AA/CZ,+BAiBc;AACd,qDAAoD;AAgClD,iGAhCO,iCAAgB,OAgCP;AA9BlB,wDAAsC;AACtC,kDAAgC;AAEhC,MAAM,IAAI,GAAG;IACX,QAAQ,EAAR,eAAQ;IACR,KAAK,EAAL,YAAK;IACL,MAAM,EAAN,aAAM;IACN,MAAM,EAAN,aAAM;IACN,SAAS,EAAT,gBAAS;IACT,UAAU,EAAV,iBAAU;IACV,IAAI,EAAJ,WAAI;IACJ,UAAU,EAAV,iBAAU;IACV,KAAK,EAAL,YAAK;IACL,IAAI,EAAJ,WAAI;IACJ,MAAM,EAAN,aAAM;IACN,GAAG,EAAH,UAAG;IACH,mBAAmB,EAAnB,0BAAmB;IACnB,MAAM,EAAN,aAAM;IACN,KAAK,EAAL,YAAK;IACL,UAAU,EAAV,iBAAU;CACX,CAAC;AASA,oBAAI"}
|
package/lib/readable.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Document, AggregateOptions, CountOptions, CountDocumentsOptions, DistinctOptions, EstimatedDocumentCountOptions, FindOptions, ListCollectionsOptions,
|
|
1
|
+
import type { Document, AggregateOptions, CountOptions, CountDocumentsOptions, DistinctOptions, EstimatedDocumentCountOptions, FindOptions, ListCollectionsOptions, ListIndexesOptions, AggregationCursor, FindCursor, DbOptions, ReadPreferenceFromOptions, ReadPreferenceLike } from './all-transport-types';
|
|
2
2
|
import { ChangeStream, ChangeStreamOptions } from './all-transport-types';
|
|
3
3
|
export default interface Readable {
|
|
4
4
|
aggregate(database: string, collection: string, pipeline: Document[], options?: AggregateOptions, dbOptions?: DbOptions): AggregationCursor;
|
|
@@ -9,10 +9,8 @@ export default interface Readable {
|
|
|
9
9
|
estimatedDocumentCount(database: string, collection: string, options?: EstimatedDocumentCountOptions, dbOptions?: DbOptions): Promise<number>;
|
|
10
10
|
find(database: string, collection: string, filter?: Document, options?: FindOptions, dbOptions?: DbOptions): FindCursor;
|
|
11
11
|
getTopology(): any;
|
|
12
|
-
isCapped(database: string, collection: string, dbOptions?: DbOptions): Promise<boolean>;
|
|
13
12
|
getIndexes(database: string, collection: string, options: ListIndexesOptions, dbOptions?: DbOptions): Promise<Document[]>;
|
|
14
13
|
listCollections(database: string, filter?: Document, options?: ListCollectionsOptions, dbOptions?: DbOptions): Promise<Document[]>;
|
|
15
14
|
readPreferenceFromOptions(options?: Omit<ReadPreferenceFromOptions, 'session'>): ReadPreferenceLike | undefined;
|
|
16
|
-
stats(database: string, collection: string, options?: CollStatsOptions, dbOptions?: DbOptions): Promise<Document>;
|
|
17
15
|
watch(pipeline: Document[], options: ChangeStreamOptions, dbOptions?: DbOptions, db?: string, coll?: string): ChangeStream<Document>;
|
|
18
16
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mongosh/service-provider-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "MongoDB Shell Core Service Provider Package",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -24,21 +24,27 @@
|
|
|
24
24
|
"access": "public"
|
|
25
25
|
},
|
|
26
26
|
"engines": {
|
|
27
|
-
"node": ">=
|
|
27
|
+
"node": ">=14.15.1"
|
|
28
28
|
},
|
|
29
29
|
"mongosh": {
|
|
30
|
-
"unitTestsOnly": true
|
|
30
|
+
"unitTestsOnly": true,
|
|
31
|
+
"ciRequiredOptionalDependencies": {
|
|
32
|
+
"mongodb-client-encryption": [
|
|
33
|
+
"darwin",
|
|
34
|
+
"linux",
|
|
35
|
+
"win32"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
31
38
|
},
|
|
32
39
|
"dependencies": {
|
|
33
|
-
"@mongosh/errors": "1.
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"mongodb": "^4.4.0",
|
|
40
|
+
"@mongosh/errors": "1.5.0",
|
|
41
|
+
"bson": "^4.6.2",
|
|
42
|
+
"mongodb": "^4.6.0",
|
|
37
43
|
"mongodb-build-info": "^1.2.0",
|
|
38
|
-
"mongodb-
|
|
44
|
+
"mongodb-client-encryption": "^2.2.0-alpha.1"
|
|
39
45
|
},
|
|
40
46
|
"optionalDependencies": {
|
|
41
|
-
"mongodb-client-encryption": "^2.0.
|
|
47
|
+
"mongodb-client-encryption": "^2.2.0-alpha.1"
|
|
42
48
|
},
|
|
43
49
|
"dependency-check": {
|
|
44
50
|
"entries": [
|
|
@@ -51,5 +57,5 @@
|
|
|
51
57
|
"encoding"
|
|
52
58
|
]
|
|
53
59
|
},
|
|
54
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "78a16fa4cbd0c5d98ca8131aa2896be5845aa919"
|
|
55
61
|
}
|
package/src/index.ts
CHANGED
|
@@ -2,8 +2,6 @@ import './textencoder-polyfill'; // for mongodb-connection-string-url in the jav
|
|
|
2
2
|
import ServiceProvider, { ServiceProviderCore } from './service-provider';
|
|
3
3
|
import getConnectInfo, { ConnectInfo } from './connect-info';
|
|
4
4
|
import { ReplPlatform } from './platform';
|
|
5
|
-
import CliOptions from './cli-options';
|
|
6
|
-
import generateUri from './uri-generator';
|
|
7
5
|
const DEFAULT_DB = 'test';
|
|
8
6
|
import {
|
|
9
7
|
ObjectId,
|
|
@@ -52,8 +50,6 @@ export {
|
|
|
52
50
|
ShellAuthOptions,
|
|
53
51
|
getConnectInfo,
|
|
54
52
|
ReplPlatform,
|
|
55
|
-
CliOptions,
|
|
56
|
-
generateUri,
|
|
57
53
|
DEFAULT_DB,
|
|
58
54
|
ServiceProviderCore,
|
|
59
55
|
bson,
|
package/src/readable.ts
CHANGED
|
@@ -7,7 +7,6 @@ import type {
|
|
|
7
7
|
EstimatedDocumentCountOptions,
|
|
8
8
|
FindOptions,
|
|
9
9
|
ListCollectionsOptions,
|
|
10
|
-
CollStatsOptions,
|
|
11
10
|
ListIndexesOptions,
|
|
12
11
|
AggregationCursor,
|
|
13
12
|
FindCursor,
|
|
@@ -154,20 +153,6 @@ export default interface Readable {
|
|
|
154
153
|
*/
|
|
155
154
|
getTopology(): any;
|
|
156
155
|
|
|
157
|
-
/**
|
|
158
|
-
* Is the collection capped?
|
|
159
|
-
*
|
|
160
|
-
* @param {String} database - The database name.
|
|
161
|
-
* @param {String} collection - The collection name.
|
|
162
|
-
* @param {DbOptions} dbOptions - The database options
|
|
163
|
-
*
|
|
164
|
-
* @returns {Promise} The promise of the result.
|
|
165
|
-
*/
|
|
166
|
-
isCapped(
|
|
167
|
-
database: string,
|
|
168
|
-
collection: string,
|
|
169
|
-
dbOptions?: DbOptions): Promise<boolean>;
|
|
170
|
-
|
|
171
156
|
/**
|
|
172
157
|
* Returns an array that holds a list of documents that identify and
|
|
173
158
|
* describe the existing indexes on the collection.
|
|
@@ -206,23 +191,6 @@ export default interface Readable {
|
|
|
206
191
|
*/
|
|
207
192
|
readPreferenceFromOptions(options?: Omit<ReadPreferenceFromOptions, 'session'>): ReadPreferenceLike | undefined;
|
|
208
193
|
|
|
209
|
-
/**
|
|
210
|
-
* Get all the collection statistics.
|
|
211
|
-
*
|
|
212
|
-
* @param {String} database - The db name.
|
|
213
|
-
* @param {String} collection - The collection name.
|
|
214
|
-
* @param {Object} options - The count options.
|
|
215
|
-
* @param {DbOptions} dbOptions - The database options
|
|
216
|
-
*
|
|
217
|
-
* @return {Promise} returns Promise
|
|
218
|
-
*/
|
|
219
|
-
stats(
|
|
220
|
-
database: string,
|
|
221
|
-
collection: string,
|
|
222
|
-
options?: CollStatsOptions,
|
|
223
|
-
dbOptions?: DbOptions
|
|
224
|
-
): Promise<Document>;
|
|
225
|
-
|
|
226
194
|
/**
|
|
227
195
|
* Start a change stream cursor on either the client, db, or collection.
|
|
228
196
|
* @param pipeline
|
package/lib/cli-options.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
export default interface CliOptions {
|
|
2
|
-
connectionSpecifier?: string;
|
|
3
|
-
fileNames?: string[];
|
|
4
|
-
apiDeprecationErrors?: boolean;
|
|
5
|
-
apiStrict?: boolean;
|
|
6
|
-
apiVersion?: string;
|
|
7
|
-
authenticationDatabase?: string;
|
|
8
|
-
authenticationMechanism?: string;
|
|
9
|
-
awsAccessKeyId?: string;
|
|
10
|
-
awsIamSessionToken?: string;
|
|
11
|
-
awsSecretAccessKey?: string;
|
|
12
|
-
awsSessionToken?: string;
|
|
13
|
-
db?: string;
|
|
14
|
-
eval?: string;
|
|
15
|
-
gssapiServiceName?: string;
|
|
16
|
-
sspiHostnameCanonicalization?: string;
|
|
17
|
-
sspiRealmOverride?: string;
|
|
18
|
-
help?: boolean;
|
|
19
|
-
host?: string;
|
|
20
|
-
ipv6?: boolean;
|
|
21
|
-
keyVaultNamespace?: string;
|
|
22
|
-
kmsURL?: string;
|
|
23
|
-
nodb?: boolean;
|
|
24
|
-
norc?: boolean;
|
|
25
|
-
password?: string;
|
|
26
|
-
port?: string;
|
|
27
|
-
quiet?: boolean;
|
|
28
|
-
retryWrites?: boolean;
|
|
29
|
-
shell?: boolean;
|
|
30
|
-
tls?: boolean;
|
|
31
|
-
tlsAllowInvalidCertificates?: boolean;
|
|
32
|
-
tlsAllowInvalidHostnames?: boolean;
|
|
33
|
-
tlsCAFile?: string;
|
|
34
|
-
tlsCertificateKeyFile?: string;
|
|
35
|
-
tlsCertificateKeyFilePassword?: string;
|
|
36
|
-
tlsCertificateSelector?: string;
|
|
37
|
-
tlsCRLFile?: string;
|
|
38
|
-
tlsDisabledProtocols?: boolean;
|
|
39
|
-
tlsFIPSMode?: boolean;
|
|
40
|
-
username?: string;
|
|
41
|
-
verbose?: boolean;
|
|
42
|
-
version?: boolean;
|
|
43
|
-
}
|
package/lib/cli-options.js
DELETED
package/lib/cli-options.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli-options.js","sourceRoot":"","sources":["../src/cli-options.ts"],"names":[],"mappings":""}
|
package/lib/uri-generator.d.ts
DELETED
package/lib/uri-generator.js
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.Scheme = void 0;
|
|
30
|
-
const errors_1 = require("@mongosh/errors");
|
|
31
|
-
const i18n_1 = __importDefault(require("@mongosh/i18n"));
|
|
32
|
-
const mongodb_connection_string_url_1 = __importStar(require("mongodb-connection-string-url"));
|
|
33
|
-
const index_1 = require("./index");
|
|
34
|
-
var Scheme;
|
|
35
|
-
(function (Scheme) {
|
|
36
|
-
Scheme["Mongo"] = "mongodb://";
|
|
37
|
-
Scheme["MongoSrv"] = "mongodb+srv://";
|
|
38
|
-
})(Scheme || (Scheme = {}));
|
|
39
|
-
exports.Scheme = Scheme;
|
|
40
|
-
const DEFAULT_HOST = '127.0.0.1';
|
|
41
|
-
const DEFAULT_PORT = '27017';
|
|
42
|
-
const CONFLICT = 'cli-repl.uri-generator.no-host-port';
|
|
43
|
-
const INVALID_HOST = 'cli-repl.uri-generator.invalid-host';
|
|
44
|
-
const HOST_LIST_PORT_MISMATCH = 'cli-repl.uri-generator.host-list-port-mismatch';
|
|
45
|
-
const DIVERGING_SERVICE_NAME = 'cli-repl.uri-generator.diverging-service-name';
|
|
46
|
-
const GSSAPI_SERVICE_NAME_UNSUPPORTED = 'cli-repl.uri-generator.gssapi-service-name-unsupported';
|
|
47
|
-
function validateConflicts(options, connectionString) {
|
|
48
|
-
if (options.host || options.port) {
|
|
49
|
-
throw new errors_1.MongoshInvalidInputError(i18n_1.default.__(CONFLICT), errors_1.CommonErrors.InvalidArgument);
|
|
50
|
-
}
|
|
51
|
-
if (options.gssapiServiceName && (connectionString === null || connectionString === void 0 ? void 0 : connectionString.searchParams.has('authMechanismProperties'))) {
|
|
52
|
-
const authProperties = new mongodb_connection_string_url_1.CommaAndColonSeparatedRecord(connectionString.searchParams.get('authMechanismProperties'));
|
|
53
|
-
const serviceName = authProperties.get('SERVICE_NAME');
|
|
54
|
-
if (serviceName !== undefined && options.gssapiServiceName !== serviceName) {
|
|
55
|
-
throw new errors_1.MongoshInvalidInputError(i18n_1.default.__(DIVERGING_SERVICE_NAME), errors_1.CommonErrors.InvalidArgument);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
if (connectionString === null || connectionString === void 0 ? void 0 : connectionString.searchParams.has('gssapiServiceName')) {
|
|
59
|
-
throw new errors_1.MongoshInvalidInputError(i18n_1.default.__(GSSAPI_SERVICE_NAME_UNSUPPORTED), errors_1.CommonErrors.InvalidArgument);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
function validateHost(host) {
|
|
63
|
-
const invalidCharacter = host.match(/[^a-zA-Z0-9.:\[\]_-]/);
|
|
64
|
-
if (invalidCharacter) {
|
|
65
|
-
throw new errors_1.MongoshInvalidInputError(i18n_1.default.__(INVALID_HOST) + ': ' + invalidCharacter[0], errors_1.CommonErrors.InvalidArgument);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
function validateHostSeedList(hosts, fixedPort) {
|
|
69
|
-
const trimmedHosts = hosts.split(',').map(h => h.trim()).filter(h => !!h);
|
|
70
|
-
const hostList = [];
|
|
71
|
-
trimmedHosts.forEach(h => {
|
|
72
|
-
const [host, port] = h.split(':');
|
|
73
|
-
if (fixedPort && port !== undefined && port !== fixedPort) {
|
|
74
|
-
throw new errors_1.MongoshInvalidInputError(i18n_1.default.__(HOST_LIST_PORT_MISMATCH), errors_1.CommonErrors.InvalidArgument);
|
|
75
|
-
}
|
|
76
|
-
hostList.push(`${host}${(port || fixedPort) ? ':' + (port || fixedPort) : ''}`);
|
|
77
|
-
});
|
|
78
|
-
return hostList;
|
|
79
|
-
}
|
|
80
|
-
function generateHost(options) {
|
|
81
|
-
if (options.host) {
|
|
82
|
-
validateHost(options.host);
|
|
83
|
-
if (options.host.includes(':')) {
|
|
84
|
-
return options.host.split(':')[0];
|
|
85
|
-
}
|
|
86
|
-
return options.host;
|
|
87
|
-
}
|
|
88
|
-
return DEFAULT_HOST;
|
|
89
|
-
}
|
|
90
|
-
function generatePort(options) {
|
|
91
|
-
if (options.host && options.host.includes(':')) {
|
|
92
|
-
validateHost(options.host);
|
|
93
|
-
const port = options.host.split(':')[1];
|
|
94
|
-
if (!options.port || options.port === port) {
|
|
95
|
-
return port;
|
|
96
|
-
}
|
|
97
|
-
throw new errors_1.MongoshInvalidInputError(i18n_1.default.__(CONFLICT), errors_1.CommonErrors.InvalidArgument);
|
|
98
|
-
}
|
|
99
|
-
return options.port ? options.port : DEFAULT_PORT;
|
|
100
|
-
}
|
|
101
|
-
function generateUri(options) {
|
|
102
|
-
if (options.nodb) {
|
|
103
|
-
return '';
|
|
104
|
-
}
|
|
105
|
-
const connectionString = generateUriNormalized(options);
|
|
106
|
-
if (connectionString.hosts.every(host => ['localhost', '127.0.0.1'].includes(host.split(':')[0]))) {
|
|
107
|
-
const params = connectionString.searchParams;
|
|
108
|
-
if (!params.has('serverSelectionTimeoutMS')) {
|
|
109
|
-
params.set('serverSelectionTimeoutMS', '2000');
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return connectionString.toString();
|
|
113
|
-
}
|
|
114
|
-
function generateUriNormalized(options) {
|
|
115
|
-
var _a, _b, _c;
|
|
116
|
-
const uri = options.connectionSpecifier;
|
|
117
|
-
const replSetHostMatch = ((_a = options.host) !== null && _a !== void 0 ? _a : '').match(/^(?<replSetName>[^/]+)\/(?<hosts>([A-Za-z0-9._-]+(:\d+)?,?)+)$/);
|
|
118
|
-
if (replSetHostMatch) {
|
|
119
|
-
const { replSetName, hosts } = replSetHostMatch.groups;
|
|
120
|
-
const connectionString = new mongodb_connection_string_url_1.default(`${Scheme.Mongo}replacemeHost/${encodeURIComponent(uri || '')}`);
|
|
121
|
-
connectionString.hosts = validateHostSeedList(hosts, options.port);
|
|
122
|
-
connectionString.searchParams.set('replicaSet', replSetName);
|
|
123
|
-
return addShellConnectionStringParameters(connectionString);
|
|
124
|
-
}
|
|
125
|
-
const seedList = ((_b = options.host) !== null && _b !== void 0 ? _b : '').match(/^(?<hosts>([A-Za-z0-9._-]+(:\d+)?,?)+)$/);
|
|
126
|
-
if (seedList && ((_c = options.host) === null || _c === void 0 ? void 0 : _c.includes(','))) {
|
|
127
|
-
const { hosts } = seedList.groups;
|
|
128
|
-
const connectionString = new mongodb_connection_string_url_1.default(`${Scheme.Mongo}replacemeHost/${encodeURIComponent(uri || '')}`);
|
|
129
|
-
connectionString.hosts = validateHostSeedList(hosts, options.port);
|
|
130
|
-
return addShellConnectionStringParameters(connectionString);
|
|
131
|
-
}
|
|
132
|
-
if (!uri) {
|
|
133
|
-
return new mongodb_connection_string_url_1.default(`${Scheme.Mongo}${generateHost(options)}:${generatePort(options)}/?directConnection=true`);
|
|
134
|
-
}
|
|
135
|
-
if (uri.startsWith(Scheme.MongoSrv)) {
|
|
136
|
-
const connectionString = new mongodb_connection_string_url_1.default(uri);
|
|
137
|
-
validateConflicts(options, connectionString);
|
|
138
|
-
return connectionString;
|
|
139
|
-
}
|
|
140
|
-
else if (uri.startsWith(Scheme.Mongo)) {
|
|
141
|
-
const connectionString = new mongodb_connection_string_url_1.default(uri);
|
|
142
|
-
validateConflicts(options, connectionString);
|
|
143
|
-
return addShellConnectionStringParameters(connectionString);
|
|
144
|
-
}
|
|
145
|
-
const uriMatch = /^([A-Za-z0-9][A-Za-z0-9._-]+):?(\d+)?(?:\/(\S*))?$/gi;
|
|
146
|
-
let parts = uriMatch.exec(uri);
|
|
147
|
-
if (parts === null) {
|
|
148
|
-
if (/[/\\. "$]/.test(uri)) {
|
|
149
|
-
throw new errors_1.MongoshInvalidInputError(`Invalid URI: ${uri}`, errors_1.CommonErrors.InvalidArgument);
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
parts = [uri, uri];
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
let host = parts === null || parts === void 0 ? void 0 : parts[1];
|
|
156
|
-
const port = parts === null || parts === void 0 ? void 0 : parts[2];
|
|
157
|
-
let dbAndQueryString = parts === null || parts === void 0 ? void 0 : parts[3];
|
|
158
|
-
if (!port && !dbAndQueryString && host.indexOf('.') < 0) {
|
|
159
|
-
dbAndQueryString = host;
|
|
160
|
-
host = undefined;
|
|
161
|
-
}
|
|
162
|
-
if (host || port) {
|
|
163
|
-
validateConflicts(options);
|
|
164
|
-
}
|
|
165
|
-
return addShellConnectionStringParameters(new mongodb_connection_string_url_1.default(`${Scheme.Mongo}${host || generateHost(options)}:${port || generatePort(options)}/${encodeURIComponent(dbAndQueryString || index_1.DEFAULT_DB)}`));
|
|
166
|
-
}
|
|
167
|
-
function addShellConnectionStringParameters(uri) {
|
|
168
|
-
uri = uri.clone();
|
|
169
|
-
const params = uri.searchParams;
|
|
170
|
-
if (!params.has('replicaSet') && !params.has('directConnection') && !params.has('loadBalanced') && uri.hosts.length === 1) {
|
|
171
|
-
params.set('directConnection', 'true');
|
|
172
|
-
}
|
|
173
|
-
return uri;
|
|
174
|
-
}
|
|
175
|
-
exports.default = generateUri;
|
|
176
|
-
//# sourceMappingURL=uri-generator.js.map
|
package/lib/uri-generator.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"uri-generator.js","sourceRoot":"","sources":["../src/uri-generator.ts"],"names":[],"mappings":"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"}
|
package/src/cli-options.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Valid options that can be parsed from the command line.
|
|
3
|
-
*/
|
|
4
|
-
export default interface CliOptions {
|
|
5
|
-
// Positional arguments:
|
|
6
|
-
connectionSpecifier?: string;
|
|
7
|
-
fileNames?: string[];
|
|
8
|
-
|
|
9
|
-
// Non-positional arguments:
|
|
10
|
-
apiDeprecationErrors?: boolean;
|
|
11
|
-
apiStrict?: boolean;
|
|
12
|
-
apiVersion?: string;
|
|
13
|
-
authenticationDatabase?: string;
|
|
14
|
-
authenticationMechanism?: string;
|
|
15
|
-
awsAccessKeyId?: string;
|
|
16
|
-
awsIamSessionToken?: string;
|
|
17
|
-
awsSecretAccessKey?: string;
|
|
18
|
-
awsSessionToken?: string;
|
|
19
|
-
db?: string;
|
|
20
|
-
eval?: string;
|
|
21
|
-
gssapiServiceName?: string;
|
|
22
|
-
sspiHostnameCanonicalization?: string;
|
|
23
|
-
sspiRealmOverride?: string;
|
|
24
|
-
help?: boolean;
|
|
25
|
-
host?: string;
|
|
26
|
-
ipv6?: boolean;
|
|
27
|
-
keyVaultNamespace?: string;
|
|
28
|
-
kmsURL?: string;
|
|
29
|
-
nodb?: boolean;
|
|
30
|
-
norc?: boolean;
|
|
31
|
-
password?: string;
|
|
32
|
-
port?: string;
|
|
33
|
-
quiet?: boolean;
|
|
34
|
-
retryWrites?: boolean;
|
|
35
|
-
shell?: boolean;
|
|
36
|
-
tls?: boolean;
|
|
37
|
-
tlsAllowInvalidCertificates?: boolean;
|
|
38
|
-
tlsAllowInvalidHostnames?: boolean;
|
|
39
|
-
tlsCAFile?: string;
|
|
40
|
-
tlsCertificateKeyFile?: string;
|
|
41
|
-
tlsCertificateKeyFilePassword?: string;
|
|
42
|
-
tlsCertificateSelector?: string;
|
|
43
|
-
tlsCRLFile?: string;
|
|
44
|
-
tlsDisabledProtocols?: boolean;
|
|
45
|
-
tlsFIPSMode?: boolean;
|
|
46
|
-
username?: string;
|
|
47
|
-
verbose?: boolean;
|
|
48
|
-
version?: boolean;
|
|
49
|
-
}
|
|
@@ -1,481 +0,0 @@
|
|
|
1
|
-
import { CommonErrors, MongoshInvalidInputError } from '@mongosh/errors';
|
|
2
|
-
import { expect } from 'chai';
|
|
3
|
-
import CliOptions from './cli-options';
|
|
4
|
-
import generateUri from './uri-generator';
|
|
5
|
-
|
|
6
|
-
describe('uri-generator.generate-uri', () => {
|
|
7
|
-
context('when no arguments are provided', () => {
|
|
8
|
-
const options = { connectionSpecifier: undefined };
|
|
9
|
-
|
|
10
|
-
it('returns the default uri', () => {
|
|
11
|
-
expect(generateUri(options)).to.equal('mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000');
|
|
12
|
-
});
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
context('when no URI is provided', () => {
|
|
16
|
-
it('handles host', () => {
|
|
17
|
-
expect(generateUri({ connectionSpecifier: undefined, host: 'localhost' })).to.equal('mongodb://localhost:27017/?directConnection=true&serverSelectionTimeoutMS=2000');
|
|
18
|
-
});
|
|
19
|
-
it('handles port', () => {
|
|
20
|
-
expect(generateUri({ connectionSpecifier: undefined, port: '27018' })).to.equal('mongodb://127.0.0.1:27018/?directConnection=true&serverSelectionTimeoutMS=2000');
|
|
21
|
-
});
|
|
22
|
-
it('handles both host and port', () => {
|
|
23
|
-
expect(generateUri({ connectionSpecifier: undefined, host: 'localhost', port: '27018' })).to.equal('mongodb://localhost:27018/?directConnection=true&serverSelectionTimeoutMS=2000');
|
|
24
|
-
});
|
|
25
|
-
it('handles host with port included', () => {
|
|
26
|
-
expect(generateUri({ connectionSpecifier: undefined, host: 'localhost:27018' })).to.equal('mongodb://localhost:27018/?directConnection=true&serverSelectionTimeoutMS=2000');
|
|
27
|
-
});
|
|
28
|
-
it('handles host with an underscore', () => {
|
|
29
|
-
expect(generateUri({ connectionSpecifier: undefined, host: 'some_host' })).to.equal('mongodb://some_host:27017/?directConnection=true');
|
|
30
|
-
});
|
|
31
|
-
it('throws if host has port AND port set to other value', () => {
|
|
32
|
-
try {
|
|
33
|
-
generateUri({ connectionSpecifier: undefined, host: 'localhost:27018', port: '27019' });
|
|
34
|
-
expect.fail('expected error');
|
|
35
|
-
} catch (e: any) {
|
|
36
|
-
expect(e).to.be.instanceOf(MongoshInvalidInputError);
|
|
37
|
-
expect(e.code).to.equal(CommonErrors.InvalidArgument);
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
it('handles host has port AND port set to equal value', () => {
|
|
41
|
-
expect(generateUri({ connectionSpecifier: undefined, host: 'localhost:27018', port: '27018' })).to.equal('mongodb://localhost:27018/?directConnection=true&serverSelectionTimeoutMS=2000');
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
context('when a full URI is provided', () => {
|
|
46
|
-
context('when no additional options are provided', () => {
|
|
47
|
-
const options = { connectionSpecifier: 'mongodb://192.0.0.1:27018/foo' };
|
|
48
|
-
|
|
49
|
-
it('returns the uri', () => {
|
|
50
|
-
expect(generateUri(options)).to.equal('mongodb://192.0.0.1:27018/foo?directConnection=true');
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
context('when additional options are provided', () => {
|
|
55
|
-
context('when providing host with URI', () => {
|
|
56
|
-
const uri = 'mongodb://192.0.0.1:27018/foo';
|
|
57
|
-
const options = { connectionSpecifier: uri, host: '127.0.0.1' };
|
|
58
|
-
|
|
59
|
-
it('throws an exception', () => {
|
|
60
|
-
try {
|
|
61
|
-
generateUri(options);
|
|
62
|
-
expect.fail('expected error');
|
|
63
|
-
} catch (e: any) {
|
|
64
|
-
expect(e).to.be.instanceOf(MongoshInvalidInputError);
|
|
65
|
-
expect(e.code).to.equal(CommonErrors.InvalidArgument);
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
context('when providing port with URI', () => {
|
|
71
|
-
const uri = 'mongodb://192.0.0.1:27018/foo';
|
|
72
|
-
const options = { connectionSpecifier: uri, port: '27018' };
|
|
73
|
-
|
|
74
|
-
it('throws an exception', () => {
|
|
75
|
-
try {
|
|
76
|
-
generateUri(options);
|
|
77
|
-
expect.fail('expected error');
|
|
78
|
-
} catch (e: any) {
|
|
79
|
-
expect(e.name).to.equal('MongoshInvalidInputError');
|
|
80
|
-
expect(e.code).to.equal(CommonErrors.InvalidArgument);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
context('when providing gssapiServiceName', () => {
|
|
86
|
-
context('and the URI does not include SERVICE_NAME in authMechanismProperties', () => {
|
|
87
|
-
const uri = 'mongodb+srv://some.host/foo';
|
|
88
|
-
const options: CliOptions = { connectionSpecifier: uri, gssapiServiceName: 'alternate' };
|
|
89
|
-
|
|
90
|
-
it('does not throw an error', () => {
|
|
91
|
-
expect(generateUri(options)).to.equal('mongodb+srv://some.host/foo');
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
context('and the URI includes SERVICE_NAME in authMechanismProperties', () => {
|
|
96
|
-
const uri = 'mongodb+srv://some.host/foo?authMechanismProperties=SERVICE_NAME:whatever';
|
|
97
|
-
const options: CliOptions = { connectionSpecifier: uri, gssapiServiceName: 'alternate' };
|
|
98
|
-
|
|
99
|
-
it('throws an error', () => {
|
|
100
|
-
try {
|
|
101
|
-
generateUri(options);
|
|
102
|
-
} catch (e: any) {
|
|
103
|
-
expect(e.name).to.equal('MongoshInvalidInputError');
|
|
104
|
-
expect(e.code).to.equal(CommonErrors.InvalidArgument);
|
|
105
|
-
expect(e.message).to.contain('--gssapiServiceName parameter or the SERVICE_NAME');
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
expect.fail('expected error');
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
context('when providing a URI with query parameters', () => {
|
|
115
|
-
context('that do not conflict with directConnection', () => {
|
|
116
|
-
const uri = 'mongodb://192.0.0.1:27018?readPreference=primary';
|
|
117
|
-
const options = { connectionSpecifier: uri };
|
|
118
|
-
it('still includes directConnection', () => {
|
|
119
|
-
expect(generateUri(options)).to.equal('mongodb://192.0.0.1:27018/?readPreference=primary&directConnection=true');
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
context('including replicaSet', () => {
|
|
124
|
-
const uri = 'mongodb://192.0.0.1:27018/db?replicaSet=replicaset';
|
|
125
|
-
const options = { connectionSpecifier: uri };
|
|
126
|
-
it('does not add the directConnection parameter', () => {
|
|
127
|
-
expect(generateUri(options)).to.equal(uri);
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
context('including loadBalanced', () => {
|
|
132
|
-
const uri = 'mongodb://192.0.0.1:27018/db?loadBalanced=true';
|
|
133
|
-
const options = { connectionSpecifier: uri };
|
|
134
|
-
it('does not add the directConnection parameter', () => {
|
|
135
|
-
expect(generateUri(options)).to.equal(uri);
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
context('including explicit directConnection', () => {
|
|
140
|
-
const uri = 'mongodb://192.0.0.1:27018/db?directConnection=false';
|
|
141
|
-
const options = { connectionSpecifier: uri };
|
|
142
|
-
it('does not change the directConnection parameter', () => {
|
|
143
|
-
expect(generateUri(options)).to.equal(uri);
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
context('when providing a URI with SRV record', () => {
|
|
149
|
-
const uri = 'mongodb+srv://somehost/?readPreference=primary';
|
|
150
|
-
const options = { connectionSpecifier: uri };
|
|
151
|
-
it('no directConnection is added', () => {
|
|
152
|
-
expect(generateUri(options)).to.equal(uri);
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
context('when providing a URI with multiple seeds', () => {
|
|
157
|
-
const uri = 'mongodb://192.42.42.42:27017,192.0.0.1:27018/db?readPreference=primary';
|
|
158
|
-
const options = { connectionSpecifier: uri };
|
|
159
|
-
it('no directConnection is added', () => {
|
|
160
|
-
expect(generateUri(options)).to.equal(uri);
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
context('when providing a URI with the legacy gssapiServiceName query parameter', () => {
|
|
165
|
-
const uri = 'mongodb://192.42.42.42:27017,192.0.0.1:27018/db?gssapiServiceName=primary';
|
|
166
|
-
const options = { connectionSpecifier: uri };
|
|
167
|
-
|
|
168
|
-
it('throws an error', () => {
|
|
169
|
-
try {
|
|
170
|
-
generateUri(options);
|
|
171
|
-
} catch (e: any) {
|
|
172
|
-
expect(e.name).to.equal('MongoshInvalidInputError');
|
|
173
|
-
expect(e.code).to.equal(CommonErrors.InvalidArgument);
|
|
174
|
-
expect(e.message).to.contain('gssapiServiceName query parameter is not supported');
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
expect.fail('expected error');
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
context('when a URI is provided without a scheme', () => {
|
|
183
|
-
context('when providing host', () => {
|
|
184
|
-
const uri = '192.0.0.1';
|
|
185
|
-
const options = { connectionSpecifier: uri };
|
|
186
|
-
|
|
187
|
-
it('returns the uri with the scheme', () => {
|
|
188
|
-
expect(generateUri(options)).to.equal(`mongodb://${uri}:27017/test?directConnection=true`);
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
context('when providing host:port', () => {
|
|
193
|
-
const uri = '192.0.0.1:27018';
|
|
194
|
-
const options = { connectionSpecifier: uri };
|
|
195
|
-
|
|
196
|
-
it('returns the uri with the scheme', () => {
|
|
197
|
-
expect(generateUri(options)).to.equal(`mongodb://${uri}/test?directConnection=true`);
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
context('when proving host + port option', () => {
|
|
202
|
-
const uri = '192.0.0.1';
|
|
203
|
-
const options = { connectionSpecifier: uri, port: '27018' };
|
|
204
|
-
|
|
205
|
-
it('throws an exception', () => {
|
|
206
|
-
try {
|
|
207
|
-
generateUri(options);
|
|
208
|
-
expect.fail('expected error');
|
|
209
|
-
} catch (e: any) {
|
|
210
|
-
expect(e).to.be.instanceOf(MongoshInvalidInputError);
|
|
211
|
-
expect(e.code).to.equal(CommonErrors.InvalidArgument);
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
context('when no additional options are provided without db', () => {
|
|
217
|
-
const uri = '192.0.0.1:27018';
|
|
218
|
-
const options = { connectionSpecifier: uri };
|
|
219
|
-
|
|
220
|
-
it('returns the uri with the scheme', () => {
|
|
221
|
-
expect(generateUri(options)).to.equal(`mongodb://${uri}/test?directConnection=true`);
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
context('when no additional options are provided with empty db', () => {
|
|
226
|
-
const uri = '192.0.0.1:27018/';
|
|
227
|
-
const options = { connectionSpecifier: uri };
|
|
228
|
-
|
|
229
|
-
it('returns the uri with the scheme', () => {
|
|
230
|
-
expect(generateUri(options)).to.equal(`mongodb://${uri}test?directConnection=true`);
|
|
231
|
-
});
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
context('when no additional options are provided with db', () => {
|
|
235
|
-
const uri = '192.0.0.1:27018/foo';
|
|
236
|
-
const options = { connectionSpecifier: uri };
|
|
237
|
-
|
|
238
|
-
it('returns the uri with the scheme', () => {
|
|
239
|
-
expect(generateUri(options)).to.equal(`mongodb://${uri}?directConnection=true`);
|
|
240
|
-
});
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
context('when no additional options are provided with db with special characters', () => {
|
|
244
|
-
const uri = '192.0.0.1:27018/föö-:?%ab💙,\'_.c';
|
|
245
|
-
const options = { connectionSpecifier: uri };
|
|
246
|
-
|
|
247
|
-
it('returns the uri with the scheme', () => {
|
|
248
|
-
expect(generateUri(options)).to.equal('mongodb://192.0.0.1:27018/f%C3%B6%C3%B6-%3A%3F%25ab%F0%9F%92%99%2C\'_.c?directConnection=true');
|
|
249
|
-
});
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
context('when the db part does not start with a slash', () => {
|
|
253
|
-
const uri = '192.0.0.1:27018?foo=bar';
|
|
254
|
-
const options = { connectionSpecifier: uri };
|
|
255
|
-
|
|
256
|
-
it('throws an exception', () => {
|
|
257
|
-
try {
|
|
258
|
-
generateUri(options);
|
|
259
|
-
expect.fail('expected error');
|
|
260
|
-
} catch (e: any) {
|
|
261
|
-
expect(e).to.be.instanceOf(MongoshInvalidInputError);
|
|
262
|
-
expect(e.code).to.equal(CommonErrors.InvalidArgument);
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
context('when additional options are provided', () => {
|
|
268
|
-
context('when providing host with URI', () => {
|
|
269
|
-
const uri = '192.0.0.1:27018/foo';
|
|
270
|
-
const options = { connectionSpecifier: uri, host: '127.0.0.1' };
|
|
271
|
-
|
|
272
|
-
it('throws an exception', () => {
|
|
273
|
-
try {
|
|
274
|
-
generateUri(options);
|
|
275
|
-
expect.fail('expected error');
|
|
276
|
-
} catch (e: any) {
|
|
277
|
-
expect(e).to.be.instanceOf(MongoshInvalidInputError);
|
|
278
|
-
expect(e.code).to.equal(CommonErrors.InvalidArgument);
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
context('when providing host with db', () => {
|
|
284
|
-
const uri = 'foo';
|
|
285
|
-
const options = { connectionSpecifier: uri, host: '127.0.0.2' };
|
|
286
|
-
|
|
287
|
-
it('uses the provided host with default port', () => {
|
|
288
|
-
expect(generateUri(options)).to.equal('mongodb://127.0.0.2:27017/foo?directConnection=true');
|
|
289
|
-
});
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
context('when providing port with URI', () => {
|
|
293
|
-
const uri = '192.0.0.1:27018/foo';
|
|
294
|
-
const options = { connectionSpecifier: uri, port: '27018' };
|
|
295
|
-
|
|
296
|
-
it('throws an exception', () => {
|
|
297
|
-
try {
|
|
298
|
-
generateUri(options);
|
|
299
|
-
expect.fail('expected error');
|
|
300
|
-
} catch (e: any) {
|
|
301
|
-
expect(e).to.be.instanceOf(MongoshInvalidInputError);
|
|
302
|
-
expect(e.code).to.equal(CommonErrors.InvalidArgument);
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
context('when providing port with db', () => {
|
|
308
|
-
const uri = 'foo';
|
|
309
|
-
const options = { connectionSpecifier: uri, port: '27018' };
|
|
310
|
-
|
|
311
|
-
it('uses the provided host with default port', () => {
|
|
312
|
-
expect(generateUri(options)).to.equal('mongodb://127.0.0.1:27018/foo?directConnection=true&serverSelectionTimeoutMS=2000');
|
|
313
|
-
});
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
context('when providing port with only a host URI', () => {
|
|
317
|
-
const uri = '127.0.0.2/foo';
|
|
318
|
-
const options = { connectionSpecifier: uri, port: '27018' };
|
|
319
|
-
|
|
320
|
-
it('throws an exception', () => {
|
|
321
|
-
try {
|
|
322
|
-
generateUri(options);
|
|
323
|
-
expect.fail('expected error');
|
|
324
|
-
} catch (e: any) {
|
|
325
|
-
expect(e).to.be.instanceOf(MongoshInvalidInputError);
|
|
326
|
-
expect(e.code).to.equal(CommonErrors.InvalidArgument);
|
|
327
|
-
}
|
|
328
|
-
});
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
context('when providing nodb', () => {
|
|
332
|
-
const uri = 'mongodb://127.0.0.2/foo';
|
|
333
|
-
const options = { connectionSpecifier: uri, nodb: true };
|
|
334
|
-
|
|
335
|
-
it('returns an empty string', () => {
|
|
336
|
-
expect(generateUri(options)).to.equal('');
|
|
337
|
-
});
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
context('when providing explicit serverSelectionTimeoutMS', () => {
|
|
341
|
-
const uri = 'mongodb://127.0.0.2/foo?serverSelectionTimeoutMS=10';
|
|
342
|
-
const options = { connectionSpecifier: uri };
|
|
343
|
-
|
|
344
|
-
it('does not override the existing value', () => {
|
|
345
|
-
expect(generateUri(options)).to.equal('mongodb://127.0.0.2/foo?serverSelectionTimeoutMS=10&directConnection=true');
|
|
346
|
-
});
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
context('when providing explicit serverSelectionTimeoutMS (different case)', () => {
|
|
350
|
-
const uri = 'mongodb://127.0.0.2/foo?SERVERSELECTIONTIMEOUTMS=10';
|
|
351
|
-
const options = { connectionSpecifier: uri };
|
|
352
|
-
|
|
353
|
-
it('does not override the existing value', () => {
|
|
354
|
-
expect(generateUri(options)).to.equal('mongodb://127.0.0.2/foo?SERVERSELECTIONTIMEOUTMS=10&directConnection=true');
|
|
355
|
-
});
|
|
356
|
-
});
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
context('when providing a URI with query parameters', () => {
|
|
360
|
-
context('that do not conflict with directConnection', () => {
|
|
361
|
-
const uri = 'mongodb://192.0.0.1:27018/?readPreference=primary';
|
|
362
|
-
const options = { connectionSpecifier: uri };
|
|
363
|
-
it('still includes directConnection', () => {
|
|
364
|
-
expect(generateUri(options)).to.equal('mongodb://192.0.0.1:27018/?readPreference=primary&directConnection=true');
|
|
365
|
-
});
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
context('including replicaSet', () => {
|
|
369
|
-
const uri = 'mongodb://192.0.0.1:27018/db?replicaSet=replicaset';
|
|
370
|
-
const options = { connectionSpecifier: uri };
|
|
371
|
-
it('does not add the directConnection parameter', () => {
|
|
372
|
-
expect(generateUri(options)).to.equal(uri);
|
|
373
|
-
});
|
|
374
|
-
});
|
|
375
|
-
|
|
376
|
-
context('including explicit directConnection', () => {
|
|
377
|
-
const uri = 'mongodb://192.0.0.1:27018/?directConnection=false';
|
|
378
|
-
const options = { connectionSpecifier: uri };
|
|
379
|
-
it('does not change the directConnection parameter', () => {
|
|
380
|
-
expect(generateUri(options)).to.equal('mongodb://192.0.0.1:27018/?directConnection=false');
|
|
381
|
-
});
|
|
382
|
-
});
|
|
383
|
-
});
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
context('when an invalid URI is provided', () => {
|
|
388
|
-
const uri = '/x';
|
|
389
|
-
const options = { connectionSpecifier: uri };
|
|
390
|
-
|
|
391
|
-
it('returns the uri', () => {
|
|
392
|
-
try {
|
|
393
|
-
generateUri(options);
|
|
394
|
-
} catch (e: any) {
|
|
395
|
-
expect(e.message).to.contain('Invalid URI: /x');
|
|
396
|
-
expect(e).to.be.instanceOf(MongoshInvalidInputError);
|
|
397
|
-
expect(e.code).to.equal(CommonErrors.InvalidArgument);
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
expect.fail('expected error');
|
|
401
|
-
});
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
context('when the --host option contains invalid characters', () => {
|
|
405
|
-
const options = { host: 'a$b,c' };
|
|
406
|
-
|
|
407
|
-
it('returns the uri', () => {
|
|
408
|
-
try {
|
|
409
|
-
generateUri(options);
|
|
410
|
-
} catch (e: any) {
|
|
411
|
-
expect(e.message).to.contain('The --host argument contains an invalid character: $');
|
|
412
|
-
expect(e).to.be.instanceOf(MongoshInvalidInputError);
|
|
413
|
-
expect(e.code).to.equal(CommonErrors.InvalidArgument);
|
|
414
|
-
return;
|
|
415
|
-
}
|
|
416
|
-
expect.fail('expected error');
|
|
417
|
-
});
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
context('when the --host option contains a seed list', () => {
|
|
421
|
-
context('without a replica set', () => {
|
|
422
|
-
it('returns a URI for the hosts and ports specified in --host', () => {
|
|
423
|
-
const options = { host: 'host1:123,host2,host3:456,' };
|
|
424
|
-
expect(generateUri(options)).to.equal('mongodb://host1:123,host2,host3:456/');
|
|
425
|
-
});
|
|
426
|
-
|
|
427
|
-
it('returns a URI for the hosts and ports specified in --host and database name', () => {
|
|
428
|
-
const options = {
|
|
429
|
-
host: 'host1:123,host_2,host3:456,',
|
|
430
|
-
connectionSpecifier: 'admin'
|
|
431
|
-
};
|
|
432
|
-
expect(generateUri(options)).to.equal('mongodb://host1:123,host_2,host3:456/admin');
|
|
433
|
-
});
|
|
434
|
-
|
|
435
|
-
it('returns a URI for the hosts in --host and fixed --port', () => {
|
|
436
|
-
const options = {
|
|
437
|
-
host: 'host1:1234,host_2',
|
|
438
|
-
port: '1234',
|
|
439
|
-
connectionSpecifier: 'admin'
|
|
440
|
-
};
|
|
441
|
-
expect(generateUri(options)).to.equal('mongodb://host1:1234,host_2:1234/admin');
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
it('throws an error if seed list in --host contains port mismatches from fixed --port', () => {
|
|
445
|
-
const options = {
|
|
446
|
-
host: 'host1,host_2:123',
|
|
447
|
-
port: '1234',
|
|
448
|
-
connectionSpecifier: 'admin'
|
|
449
|
-
};
|
|
450
|
-
expect(() => generateUri(options)).to.throw('The host list contains different ports than provided by --port');
|
|
451
|
-
});
|
|
452
|
-
});
|
|
453
|
-
|
|
454
|
-
context('with a replica set', () => {
|
|
455
|
-
it('returns a URI for the hosts and ports specified in --host', () => {
|
|
456
|
-
const options = { host: 'replsetname/host1:123,host2,host3:456,' };
|
|
457
|
-
expect(generateUri(options)).to.equal('mongodb://host1:123,host2,host3:456/?replicaSet=replsetname');
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
it('returns a URI for the hosts and ports specified in --host and database name', () => {
|
|
461
|
-
const options = { host: 'replsetname/host1:123,host2,host3:456', connectionSpecifier: 'admin' };
|
|
462
|
-
expect(generateUri(options)).to.equal('mongodb://host1:123,host2,host3:456/admin?replicaSet=replsetname');
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
it('returns a URI for the hosts and ports specified in --host and database name with escaped chars', () => {
|
|
466
|
-
const options = { host: 'replsetname/host1:123,host2,host3:456', connectionSpecifier: 'admin?foo=bar' };
|
|
467
|
-
expect(generateUri(options)).to.equal('mongodb://host1:123,host2,host3:456/admin%3Ffoo%3Dbar?replicaSet=replsetname');
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
it('returns a URI for the hosts specified in --host and explicit --port', () => {
|
|
471
|
-
const options = { host: 'replsetname/host1:123,host2,', port: '123' };
|
|
472
|
-
expect(generateUri(options)).to.equal('mongodb://host1:123,host2:123/?replicaSet=replsetname');
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
it('throws an error if the hosts contain ports that mismatch from --port', () => {
|
|
476
|
-
const options = { host: 'replsetname/host1:1234,host2,', port: '123' };
|
|
477
|
-
expect(() => generateUri(options)).to.throw('The host list contains different ports than provided by --port');
|
|
478
|
-
});
|
|
479
|
-
});
|
|
480
|
-
});
|
|
481
|
-
});
|
package/src/uri-generator.ts
DELETED
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
/* eslint complexity: 0*/
|
|
2
|
-
|
|
3
|
-
import { CommonErrors, MongoshInvalidInputError } from '@mongosh/errors';
|
|
4
|
-
import i18n from '@mongosh/i18n';
|
|
5
|
-
import CliOptions from './cli-options';
|
|
6
|
-
import ConnectionString, { CommaAndColonSeparatedRecord } from 'mongodb-connection-string-url';
|
|
7
|
-
import { DEFAULT_DB } from './index';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* URI schemes.
|
|
11
|
-
*/
|
|
12
|
-
enum Scheme {
|
|
13
|
-
Mongo = 'mongodb://',
|
|
14
|
-
MongoSrv = 'mongodb+srv://'
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* The default host.
|
|
19
|
-
*/
|
|
20
|
-
const DEFAULT_HOST = '127.0.0.1';
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* The default port.
|
|
24
|
-
*/
|
|
25
|
-
const DEFAULT_PORT = '27017';
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Conflicting host/port message.
|
|
29
|
-
*/
|
|
30
|
-
const CONFLICT = 'cli-repl.uri-generator.no-host-port';
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Invalid host message.
|
|
34
|
-
*/
|
|
35
|
-
const INVALID_HOST = 'cli-repl.uri-generator.invalid-host';
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Host seed list contains a port that mismatches an explicit --port.
|
|
39
|
-
*/
|
|
40
|
-
const HOST_LIST_PORT_MISMATCH = 'cli-repl.uri-generator.host-list-port-mismatch';
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Diverging gssapiServiceName and SERVICE_NAME mechanism property
|
|
44
|
-
*/
|
|
45
|
-
const DIVERGING_SERVICE_NAME = 'cli-repl.uri-generator.diverging-service-name';
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Usage of unsupported gssapiServiceName query parameter
|
|
49
|
-
*/
|
|
50
|
-
const GSSAPI_SERVICE_NAME_UNSUPPORTED = 'cli-repl.uri-generator.gssapi-service-name-unsupported';
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Validate conflicts in the options.
|
|
54
|
-
*/
|
|
55
|
-
function validateConflicts(options: CliOptions, connectionString?: ConnectionString): void {
|
|
56
|
-
if (options.host || options.port) {
|
|
57
|
-
throw new MongoshInvalidInputError(i18n.__(CONFLICT), CommonErrors.InvalidArgument);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (options.gssapiServiceName && connectionString?.searchParams.has('authMechanismProperties')) {
|
|
61
|
-
const authProperties = new CommaAndColonSeparatedRecord(
|
|
62
|
-
connectionString.searchParams.get('authMechanismProperties'));
|
|
63
|
-
const serviceName = authProperties.get('SERVICE_NAME');
|
|
64
|
-
if (serviceName !== undefined && options.gssapiServiceName !== serviceName) {
|
|
65
|
-
throw new MongoshInvalidInputError(i18n.__(DIVERGING_SERVICE_NAME), CommonErrors.InvalidArgument);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (connectionString?.searchParams.has('gssapiServiceName')) {
|
|
70
|
-
throw new MongoshInvalidInputError(i18n.__(GSSAPI_SERVICE_NAME_UNSUPPORTED), CommonErrors.InvalidArgument);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Perform basic validation of the --host option.
|
|
76
|
-
*
|
|
77
|
-
* @param {string} host - The value of the --host option.
|
|
78
|
-
*/
|
|
79
|
-
function validateHost(host: string): void {
|
|
80
|
-
const invalidCharacter = host.match(/[^a-zA-Z0-9.:\[\]_-]/);
|
|
81
|
-
if (invalidCharacter) {
|
|
82
|
-
throw new MongoshInvalidInputError(
|
|
83
|
-
i18n.__(INVALID_HOST) + ': ' + invalidCharacter[0],
|
|
84
|
-
CommonErrors.InvalidArgument);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Validates a host seed list against a specified fixed port and
|
|
90
|
-
* returns an individual `<host>:<port>` array.
|
|
91
|
-
*/
|
|
92
|
-
function validateHostSeedList(hosts: string, fixedPort: string | undefined): string[] {
|
|
93
|
-
const trimmedHosts = hosts.split(',').map(h => h.trim()).filter(h => !!h);
|
|
94
|
-
const hostList: string[] = [];
|
|
95
|
-
trimmedHosts.forEach(h => {
|
|
96
|
-
const [host, port] = h.split(':');
|
|
97
|
-
if (fixedPort && port !== undefined && port !== fixedPort) {
|
|
98
|
-
throw new MongoshInvalidInputError(
|
|
99
|
-
i18n.__(HOST_LIST_PORT_MISMATCH),
|
|
100
|
-
CommonErrors.InvalidArgument
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
hostList.push(`${host}${(port || fixedPort) ? ':' + (port || fixedPort) : ''}`);
|
|
104
|
-
});
|
|
105
|
-
return hostList;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Generate the host from the options or default.
|
|
110
|
-
*
|
|
111
|
-
* @param {CliOptions} options - The options.
|
|
112
|
-
*
|
|
113
|
-
* @returns {string} The host.
|
|
114
|
-
*/
|
|
115
|
-
function generateHost(options: CliOptions): string {
|
|
116
|
-
if (options.host) {
|
|
117
|
-
validateHost(options.host);
|
|
118
|
-
if (options.host.includes(':')) {
|
|
119
|
-
return options.host.split(':')[0];
|
|
120
|
-
}
|
|
121
|
-
return options.host;
|
|
122
|
-
}
|
|
123
|
-
return DEFAULT_HOST;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Generate the port from the options or default.
|
|
128
|
-
*
|
|
129
|
-
* @param {CliOptions} options - The options.
|
|
130
|
-
*
|
|
131
|
-
* @returns {string} The port.
|
|
132
|
-
*/
|
|
133
|
-
function generatePort(options: CliOptions): string {
|
|
134
|
-
if (options.host && options.host.includes(':')) {
|
|
135
|
-
validateHost(options.host);
|
|
136
|
-
const port = options.host.split(':')[1];
|
|
137
|
-
if (!options.port || options.port === port) {
|
|
138
|
-
return port;
|
|
139
|
-
}
|
|
140
|
-
throw new MongoshInvalidInputError(i18n.__(CONFLICT), CommonErrors.InvalidArgument);
|
|
141
|
-
}
|
|
142
|
-
return options.port ? options.port : DEFAULT_PORT;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Generate a URI from the provided CLI options.
|
|
147
|
-
*
|
|
148
|
-
* If a full URI is provided, you cannot also specify --host or --port
|
|
149
|
-
*
|
|
150
|
-
* Rules from the existing Shell code:
|
|
151
|
-
*
|
|
152
|
-
* if nodb is set then all positional parameters are files
|
|
153
|
-
* otherwise the first positional parameter might be a dbaddress, but
|
|
154
|
-
* only if one of these conditions is met:
|
|
155
|
-
* - it contains no '.' after the last appearance of '\' or '/'
|
|
156
|
-
* - it doesn't end in '.js' and it doesn't specify a path to an existing file
|
|
157
|
-
*/
|
|
158
|
-
function generateUri(options: CliOptions): string {
|
|
159
|
-
if (options.nodb) {
|
|
160
|
-
return '';
|
|
161
|
-
}
|
|
162
|
-
const connectionString = generateUriNormalized(options);
|
|
163
|
-
if (connectionString.hosts.every(host =>
|
|
164
|
-
['localhost', '127.0.0.1'].includes(host.split(':')[0]))) {
|
|
165
|
-
const params = connectionString.searchParams;
|
|
166
|
-
if (!params.has('serverSelectionTimeoutMS')) {
|
|
167
|
-
params.set('serverSelectionTimeoutMS', '2000');
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
return connectionString.toString();
|
|
171
|
-
}
|
|
172
|
-
function generateUriNormalized(options: CliOptions): ConnectionString {
|
|
173
|
-
const uri = options.connectionSpecifier;
|
|
174
|
-
|
|
175
|
-
// If the --host argument contains /, it has the format
|
|
176
|
-
// <replSetName>/<hostname1><:port>,<hostname2><:port>,<...>
|
|
177
|
-
const replSetHostMatch = (options.host ?? '').match(
|
|
178
|
-
/^(?<replSetName>[^/]+)\/(?<hosts>([A-Za-z0-9._-]+(:\d+)?,?)+)$/
|
|
179
|
-
);
|
|
180
|
-
if (replSetHostMatch) {
|
|
181
|
-
const { replSetName, hosts } = replSetHostMatch.groups as { replSetName: string, hosts: string };
|
|
182
|
-
const connectionString = new ConnectionString(`${Scheme.Mongo}replacemeHost/${encodeURIComponent(uri || '')}`);
|
|
183
|
-
connectionString.hosts = validateHostSeedList(hosts, options.port);
|
|
184
|
-
connectionString.searchParams.set('replicaSet', replSetName);
|
|
185
|
-
return addShellConnectionStringParameters(connectionString);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// If the --host argument contains multiple hosts as a seed list
|
|
189
|
-
// we directly do not do additional host/port parsing
|
|
190
|
-
const seedList = (options.host ?? '').match(
|
|
191
|
-
/^(?<hosts>([A-Za-z0-9._-]+(:\d+)?,?)+)$/
|
|
192
|
-
);
|
|
193
|
-
if (seedList && options.host?.includes(',')) {
|
|
194
|
-
const { hosts } = seedList.groups as { hosts: string };
|
|
195
|
-
const connectionString = new ConnectionString(`${Scheme.Mongo}replacemeHost/${encodeURIComponent(uri || '')}`);
|
|
196
|
-
connectionString.hosts = validateHostSeedList(hosts, options.port);
|
|
197
|
-
return addShellConnectionStringParameters(connectionString);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// There is no URI provided, use default 127.0.0.1:27017
|
|
201
|
-
if (!uri) {
|
|
202
|
-
return new ConnectionString(`${Scheme.Mongo}${generateHost(options)}:${generatePort(options)}/?directConnection=true`);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// mongodb+srv:// URI is provided, treat as correct and immediately return
|
|
206
|
-
if (uri.startsWith(Scheme.MongoSrv)) {
|
|
207
|
-
const connectionString = new ConnectionString(uri);
|
|
208
|
-
validateConflicts(options, connectionString);
|
|
209
|
-
return connectionString;
|
|
210
|
-
} else if (uri.startsWith(Scheme.Mongo)) {
|
|
211
|
-
// we need to figure out if we have to add the directConnection query parameter
|
|
212
|
-
const connectionString = new ConnectionString(uri);
|
|
213
|
-
validateConflicts(options, connectionString);
|
|
214
|
-
return addShellConnectionStringParameters(connectionString);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// Capture host, port and db from the string and generate a URI from
|
|
218
|
-
// the parts. If there is a db part, it *must* start with /.
|
|
219
|
-
const uriMatch = /^([A-Za-z0-9][A-Za-z0-9._-]+):?(\d+)?(?:\/(\S*))?$/gi;
|
|
220
|
-
let parts: string[] | null = uriMatch.exec(uri);
|
|
221
|
-
|
|
222
|
-
if (parts === null) {
|
|
223
|
-
if (/[/\\. "$]/.test(uri)) {
|
|
224
|
-
// This cannot be a database name because 'uri' contains characters invalid in a database.
|
|
225
|
-
throw new MongoshInvalidInputError(`Invalid URI: ${uri}`, CommonErrors.InvalidArgument);
|
|
226
|
-
} else {
|
|
227
|
-
parts = [ uri, uri ];
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
let host: string | undefined = parts?.[1];
|
|
232
|
-
const port = parts?.[2];
|
|
233
|
-
let dbAndQueryString = parts?.[3];
|
|
234
|
-
|
|
235
|
-
// If there is no port and db, host becomes db if there is no
|
|
236
|
-
// '.' in the string. (legacy shell behaviour)
|
|
237
|
-
if (!port && !dbAndQueryString && host.indexOf('.') < 0) {
|
|
238
|
-
dbAndQueryString = host;
|
|
239
|
-
host = undefined;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// If we have a host or port, validate that the options don't also
|
|
243
|
-
// have a host or port in them.
|
|
244
|
-
if (host || port) {
|
|
245
|
-
validateConflicts(options);
|
|
246
|
-
}
|
|
247
|
-
return addShellConnectionStringParameters(new ConnectionString(
|
|
248
|
-
`${Scheme.Mongo}${host || generateHost(options)}:${port || generatePort(options)}/${encodeURIComponent(dbAndQueryString || DEFAULT_DB)}`));
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Adds the `directConnection=true` query parameter if required.
|
|
253
|
-
* @param uri mongodb:// connection string
|
|
254
|
-
*/
|
|
255
|
-
function addShellConnectionStringParameters(uri: ConnectionString): ConnectionString {
|
|
256
|
-
uri = uri.clone();
|
|
257
|
-
const params = uri.searchParams;
|
|
258
|
-
if (!params.has('replicaSet') && !params.has('directConnection') && !params.has('loadBalanced') && uri.hosts.length === 1) {
|
|
259
|
-
params.set('directConnection', 'true');
|
|
260
|
-
}
|
|
261
|
-
return uri;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
export default generateUri;
|
|
265
|
-
export { Scheme };
|