diff --git a/package-lock.json b/package-lock.json index 4adfcc4bd3..505e4a45b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -312,16 +312,16 @@ "dev": true }, "@microsoft/api-extractor": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.11.2.tgz", - "integrity": "sha512-iZPv22j9K02cbwIDblOgF1MxZG+KWovp3CQpWCD6UC/+YYO4DfLxX5uZYVNzfgT4vU8fN0rugJmGm85rHX6Ouw==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.12.0.tgz", + "integrity": "sha512-YDd7AUkIayPLooMasDyV4vle1TLUQhFp2v/tGdRU+WAVbnyVUDXXa20WEfbPEZ4QVlgN+77EX6f2K6GyKd713A==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.10.8", + "@microsoft/api-extractor-model": "7.12.0", "@microsoft/tsdoc": "0.12.19", - "@rushstack/node-core-library": "3.34.7", - "@rushstack/rig-package": "0.2.7", - "@rushstack/ts-command-line": "4.7.6", + "@rushstack/node-core-library": "3.35.1", + "@rushstack/rig-package": "0.2.8", + "@rushstack/ts-command-line": "4.7.7", "colors": "~1.2.1", "lodash": "~4.17.15", "resolve": "~1.17.0", @@ -335,23 +335,17 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true - }, - "typescript": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz", - "integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==", - "dev": true } } }, "@microsoft/api-extractor-model": { - "version": "7.10.8", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.10.8.tgz", - "integrity": "sha512-9TfiCTPnkUeLaYywZeg9rYbVPX9Tj6AAkO6ThnjSE0tTPLjMcL3RiHkqn0BJ4+aGcl56APwo32zj5+kG+NqxYA==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.12.0.tgz", + "integrity": "sha512-TxoAbL/lauS3k/brBWVsiQTnyHBwHrAGJhTuiD0tWS/eu4dLNULchcSQfcOaFS91OgDEz4lMMbClgChFuo+53Q==", "dev": true, "requires": { "@microsoft/tsdoc": "0.12.19", - "@rushstack/node-core-library": "3.34.7" + "@rushstack/node-core-library": "3.35.1" } }, "@microsoft/tsdoc": { @@ -361,21 +355,21 @@ "dev": true }, "@microsoft/tsdoc-config": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.13.5.tgz", - "integrity": "sha512-KlnIdTRnPSsU9Coz9wzDAkT8JCLopP3ec1sgsgo7trwE6QLMKRpM4hZi2uzVX897SW49Q4f439auGBcQLnZQfA==", + "version": "0.13.6", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.13.6.tgz", + "integrity": "sha512-VJjV35PnrNISoX2WMemZjnCIdOUPTRpCz6pu8inISotLd3SgoDSJygGaE7+lOYdCtDl+4c8PWJdZivxxXgOnLw==", "dev": true, "requires": { - "@microsoft/tsdoc": "0.12.20", + "@microsoft/tsdoc": "0.12.21", "ajv": "~6.12.3", "jju": "~1.4.0", "resolve": "~1.12.0" }, "dependencies": { "@microsoft/tsdoc": { - "version": "0.12.20", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.12.20.tgz", - "integrity": "sha512-/b13m37QZYPV6nCOiqkFyvlQjlTNvAcQpgFZ6ZKIqtStJxNdqVo/frULubxMUMWi6p9Uo5f4BRlguv5ViFcL0A==", + "version": "0.12.21", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.12.21.tgz", + "integrity": "sha512-j+9OJ0A0buZZaUn6NxeHUVpoa05tY2PgVs7kXJhJQiKRB0G1zQqbJxer3T7jWtzpqQWP89OBDluyIeyTsMk8Sg==", "dev": true }, "resolve": { @@ -390,9 +384,9 @@ } }, "@rushstack/node-core-library": { - "version": "3.34.7", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.34.7.tgz", - "integrity": "sha512-7FwJ0jmZsh7bDIZ1IqDNphY9Kc6aAi1D2K8jiq+da4flMyL84HNeq2KxvwFLzjLwu3eMr88X+oBpgxCTD5Y57Q==", + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.35.1.tgz", + "integrity": "sha512-ZwnXp2loZyVUgrZ+fEKKF/EHl0ikcy6SCsd34ewYXoEAs0XWIy2VS9bemrfaFtd2VzJ/G/ZbP3xHkqRnUPKJ4Q==", "dev": true, "requires": { "@types/node": "10.17.13", @@ -421,9 +415,9 @@ } }, "@rushstack/rig-package": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.2.7.tgz", - "integrity": "sha512-hI1L0IIzCHqH/uW64mKqEQ0/MANA/IklVId3jGpj1kt9RJcBdeNUIlzDtHl437LZRAuEA8CyotRHzG6YDgWlTw==", + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.2.8.tgz", + "integrity": "sha512-Ltjeg1a5Sx7XTW9oBxmcfhHseBLnH7I/8d6tAtjx5s0r7F6WmNVJdxVmt86qNfXcFRsiGNrzLqjMwlcX3GyldQ==", "dev": true, "requires": { "@types/node": "10.17.13", @@ -440,9 +434,9 @@ } }, "@rushstack/ts-command-line": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.7.6.tgz", - "integrity": "sha512-falJVNfpJtsL3gJaY77JXXycfzhzB9VkKhqEfjRWD69/f6ezMUorPR6Nc90MnIaWgePTcdTJPZibxOQrNpu1Uw==", + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.7.7.tgz", + "integrity": "sha512-COSDys0WTVCORKam2hsTL32As4fHAf1RqC6FKS98hgR0Z90nh1JX8fGNkvSdxaZ6dOuNTJj3txh+SpWoHJoZJA==", "dev": true, "requires": { "@types/argparse": "1.0.38", @@ -2389,6 +2383,27 @@ "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.12.20.tgz", "integrity": "sha512-/b13m37QZYPV6nCOiqkFyvlQjlTNvAcQpgFZ6ZKIqtStJxNdqVo/frULubxMUMWi6p9Uo5f4BRlguv5ViFcL0A==", "dev": true + }, + "@microsoft/tsdoc-config": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.13.5.tgz", + "integrity": "sha512-KlnIdTRnPSsU9Coz9wzDAkT8JCLopP3ec1sgsgo7trwE6QLMKRpM4hZi2uzVX897SW49Q4f439auGBcQLnZQfA==", + "dev": true, + "requires": { + "@microsoft/tsdoc": "0.12.20", + "ajv": "~6.12.3", + "jju": "~1.4.0", + "resolve": "~1.12.0" + } + }, + "resolve": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.3.tgz", + "integrity": "sha512-hF6+hAPlxjqHWrw4p1rF3Wztbgxd4AjA5VlUzY5zcTb4J8D3JK4/1RjU48pHz2PJWzGVsLB1VWZkvJzhK2CCOA==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } } } }, @@ -3457,9 +3472,9 @@ "dev": true }, "highlight.js": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.1.2.tgz", - "integrity": "sha512-Q39v/Mn5mfBlMff9r+zzA+gWxRsCRKwEMvYTiisLr/XUiFI/4puWt0Ojdko3R3JCNWGdOWaA5g/Yxqa23kC5AA==", + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.3.2.tgz", + "integrity": "sha512-3jRT7OUYsVsKvukNKZCtnvRcFyCJqSEIuIMsEybAXRiFSwpt65qjPd/Pr+UOdYt7WJlt+lj3+ypUsHiySBp/Jw==", "dev": true }, "hosted-git-info": { @@ -7150,21 +7165,22 @@ } }, "typedoc": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.18.0.tgz", - "integrity": "sha512-UgDQwapCGQCCdYhEQzQ+kGutmcedklilgUGf62Vw6RdI29u6FcfAXFQfRTiJEbf16aK3YnkB20ctQK1JusCRbA==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.19.2.tgz", + "integrity": "sha512-oDEg1BLEzi1qvgdQXc658EYgJ5qJLVSeZ0hQ57Eq4JXy6Vj2VX4RVo18qYxRWz75ifAaYuYNBUCnbhjd37TfOg==", "dev": true, "requires": { "fs-extra": "^9.0.1", "handlebars": "^4.7.6", - "highlight.js": "^10.0.0", - "lodash": "^4.17.15", - "lunr": "^2.3.8", + "highlight.js": "^10.2.0", + "lodash": "^4.17.20", + "lunr": "^2.3.9", "marked": "^1.1.1", "minimatch": "^3.0.0", "progress": "^2.0.3", + "semver": "^7.3.2", "shelljs": "^0.8.4", - "typedoc-default-themes": "^0.10.2" + "typedoc-default-themes": "^0.11.4" }, "dependencies": { "fs-extra": { @@ -7180,19 +7196,39 @@ } }, "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } } }, "marked": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/marked/-/marked-1.1.1.tgz", - "integrity": "sha512-mJzT8D2yPxoPh7h0UXkB+dBj4FykPJ2OIfxAWeIHrvoHDkFxukV/29QxoFQoPM6RLEwhIFdJpmKBlqVM3s2ZIw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.4.tgz", + "integrity": "sha512-6x5TFGCTKSQBLTZtOburGxCxFEBJEGYVLwCMTBCxzvyuisGcC20UNzDSJhCr/cJ/Kmh6ulfJm10g6WWEAJ3kvg==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "typedoc-default-themes": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.11.4.tgz", + "integrity": "sha512-Y4Lf+qIb9NTydrexlazAM46SSLrmrQRqWiD52593g53SsmUFioAsMWt8m834J6qsp+7wHRjxCXSZeiiW5cMUdw==", "dev": true }, "universalify": { @@ -7223,9 +7259,9 @@ } }, "typescript": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", - "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz", + "integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==", "dev": true }, "typescript-cached-transpile": { diff --git a/package.json b/package.json index 0d26cd4885..012b1ea0a9 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ }, "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.1", - "@microsoft/api-extractor": "^7.11.2", - "@microsoft/tsdoc-config": "^0.13.5", + "@microsoft/api-extractor": "^7.12.0", + "@microsoft/tsdoc-config": "^0.13.6", "@types/aws4": "^1.5.1", "@types/bl": "^2.1.0", "@types/bson": "^4.0.2", @@ -71,9 +71,9 @@ "standard-version": "^7.1.0", "through2": "^3.0.1", "ts-node": "^9.0.0", - "typedoc": "^0.18.0", + "typedoc": "^0.19.2", "typedoc-plugin-pages": "^1.0.1", - "typescript": "^4.0.2", + "typescript": "^4.0.5", "typescript-cached-transpile": "^0.0.6", "worker-farm": "^1.5.0", "wtfnode": "^0.8.2", diff --git a/src/connection_string.ts b/src/connection_string.ts index 2cdc103c4d..e9b7af701c 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -1,12 +1,14 @@ import * as url from 'url'; import * as qs from 'querystring'; import * as dns from 'dns'; +import { URL } from 'url'; import { ReadPreference } from './read_preference'; import { MongoParseError } from './error'; import type { AnyOptions, Callback } from './utils'; import type { ConnectionOptions } from './cmap/connection'; import type { Document } from './bson'; import type { CompressorName } from './cmap/wire_protocol/compression'; +import type { MongoClientOptions, MongoOptions } from './mongo_client'; /** * The following regular expression validates a connection string and breaks the @@ -760,3 +762,49 @@ export function parseConnectionString( callback(undefined, result); } + +// NEW PARSER WORK... + +const HOSTS_REGEX = new RegExp( + '(?mongodb(?:\\+srv|)):\\/\\/(?:(?[^:]*)(?::(?[^@]*))?@)?(?[^\\/?]*)(?.*)' +); + +function parseURI(uri: string): { srv: boolean; url: URL; hosts: string[] } { + const match = uri.match(HOSTS_REGEX); + if (!match) { + throw new MongoParseError(`Invalid connection string ${uri}`); + } + + const protocol = match.groups?.protocol; + const username = match.groups?.username; + const password = match.groups?.password; + const hosts = match.groups?.hosts; + const rest = match.groups?.rest; + + if (!protocol || !hosts) { + throw new MongoParseError('Invalid connection string, protocol and host(s) required'); + } + + const authString = username ? (password ? `${username}:${password}` : `${username}`) : ''; + return { + srv: protocol.includes('srv'), + url: new URL(`${protocol.toLowerCase()}://${authString}@dummyHostname${rest}`), + hosts: hosts.split(',') + }; +} + +export function parseOptions( + uri: string, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + options: MongoClientOptions = {} +): Readonly { + try { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { srv, url, hosts } = parseURI(uri); + const mongoOptions: MongoOptions = ({ srv, hosts } as unknown) as MongoOptions; + // TODO(NODE-2699): option parse logic + return Object.freeze(mongoOptions); + } catch { + return Object.freeze({} as MongoOptions); + } +} diff --git a/src/index.ts b/src/index.ts index aa76176e81..8fbedd3f49 100644 --- a/src/index.ts +++ b/src/index.ts @@ -300,4 +300,3 @@ export type { ClientMetadataOptions } from './utils'; export type { WriteConcern, W, WriteConcernOptions } from './write_concern'; -export type { MongoOptions } from './mongo_client_options'; diff --git a/src/mongo_client.ts b/src/mongo_client.ts index 0c6fd846c7..88b4e6a976 100644 --- a/src/mongo_client.ts +++ b/src/mongo_client.ts @@ -18,7 +18,10 @@ import type { Topology } from './sdam/topology'; import type { ClientSession, ClientSessionOptions } from './sessions'; import type { OperationParent } from './operations/command'; import type { TagSet } from './sdam/server_description'; -import { MongoOptions, parseOptions } from './mongo_client_options'; +import type { ConnectionOptions as TLSConnectionOptions } from 'tls'; +import type { TcpSocketConnectOpts as ConnectionOptions } from 'net'; +import type { MongoCredentials } from './cmap/auth/mongo_credentials'; +import { parseOptions } from './connection_string'; /** @public */ export enum LogLevel { @@ -569,3 +572,92 @@ export class MongoClient extends EventEmitter implements OperationParent { if (typeof callback === 'function') callback(undefined, true); }, 'Multiple authentication is prohibited on a connected client, please only authenticate once per MongoClient'); } + +/** + * Mongo Client Options + * @internal + */ +export interface MongoOptions + extends Required, + Omit, + Omit, + Required< + Pick< + MongoClientOptions, + | 'autoEncryption' + | 'compression' + | 'compressors' + | 'connectTimeoutMS' + | 'dbName' + | 'directConnection' + | 'domainsEnabled' + | 'driverInfo' + | 'forceServerObjectId' + | 'gssapiServiceName' + | 'ha' + | 'haInterval' + | 'heartbeatFrequencyMS' + | 'keepAlive' + | 'keepAliveInitialDelay' + | 'localThresholdMS' + | 'logger' + | 'maxIdleTimeMS' + | 'maxPoolSize' + | 'minPoolSize' + | 'monitorCommands' + | 'noDelay' + | 'numberOfRetries' + | 'pkFactory' + | 'promiseLibrary' + | 'raw' + | 'reconnectInterval' + | 'reconnectTries' + | 'replicaSet' + | 'retryReads' + | 'retryWrites' + | 'serverSelectionTimeoutMS' + | 'serverSelectionTryOnce' + | 'socketTimeoutMS' + | 'tlsAllowInvalidCertificates' + | 'tlsAllowInvalidHostnames' + | 'tlsInsecure' + | 'waitQueueMultiple' + | 'waitQueueTimeoutMS' + | 'zlibCompressionLevel' + > + > { + hosts: { host: string; port: number }[]; + srv: boolean; + credentials: MongoCredentials; + readPreference: ReadPreference; + readConcern: ReadConcern; + writeConcern: WriteConcern; + + /** + * # NOTE ABOUT TLS Options + * + * If set TLS enabled, equivalent to setting the ssl option. + * + * ### Additional options: + * + * | nodejs option | MongoDB equivalent | type | + * |:---------------------|--------------------------------------------------------- |:---------------------------------------| + * | `ca` | `sslCA`, `tlsCAFile` | `string \| Buffer \| Buffer[]` | + * | `crl` | `sslCRL` | `string \| Buffer \| Buffer[]` | + * | `cert` | `sslCert`, `tlsCertificateFile`, `tlsCertificateKeyFile` | `string \| Buffer \| Buffer[]` | + * | `key` | `sslKey`, `tlsCertificateKeyFile` | `string \| Buffer \| KeyObject[]` | + * | `passphrase` | `sslPass`, `tlsCertificateKeyFilePassword` | `string` | + * | `rejectUnauthorized` | `sslValidate` | `boolean` | + * + */ + tls: boolean; + + /** + * Turn these options into a reusable options dictionary + */ + toJSON(): Record; + /** + * Turn these options into a reusable connection URI + */ + toURI(): string; +} diff --git a/src/mongo_client_options.ts b/src/mongo_client_options.ts deleted file mode 100644 index bd6aa60e6c..0000000000 --- a/src/mongo_client_options.ts +++ /dev/null @@ -1,144 +0,0 @@ -import type { MongoCredentials } from './cmap/auth/mongo_credentials'; -import type { MongoClientOptions } from './mongo_client'; -import type { ReadConcern } from './read_concern'; -import type { ReadPreference } from './read_preference'; -import type { WriteConcern } from './write_concern'; - -import type { ConnectionOptions as TLSConnectionOptions } from 'tls'; -import type { TcpSocketConnectOpts as ConnectionOptions } from 'net'; -import type { BSONSerializeOptions } from './bson'; -import { MongoParseError } from './error'; -import { URL } from 'url'; - -/** - * Mongo Client Options - * @internal - */ -export interface MongoOptions - extends Required, - Omit, - Omit, - Required< - Pick< - MongoClientOptions, - | 'autoEncryption' - | 'compression' - | 'compressors' - | 'connectTimeoutMS' - | 'dbName' - | 'directConnection' - | 'domainsEnabled' - | 'driverInfo' - | 'forceServerObjectId' - | 'gssapiServiceName' - | 'ha' - | 'haInterval' - | 'heartbeatFrequencyMS' - | 'keepAlive' - | 'keepAliveInitialDelay' - | 'localThresholdMS' - | 'logger' - | 'maxIdleTimeMS' - | 'maxPoolSize' - | 'minPoolSize' - | 'monitorCommands' - | 'noDelay' - | 'numberOfRetries' - | 'pkFactory' - | 'promiseLibrary' - | 'raw' - | 'reconnectInterval' - | 'reconnectTries' - | 'replicaSet' - | 'retryReads' - | 'retryWrites' - | 'serverSelectionTimeoutMS' - | 'serverSelectionTryOnce' - | 'socketTimeoutMS' - | 'tlsAllowInvalidCertificates' - | 'tlsAllowInvalidHostnames' - | 'tlsInsecure' - | 'waitQueueMultiple' - | 'waitQueueTimeoutMS' - | 'zlibCompressionLevel' - > - > { - hosts: { host: string; port: number }[]; - srv: boolean; - credentials: MongoCredentials; - readPreference: ReadPreference; - readConcern: ReadConcern; - writeConcern: WriteConcern; - - /** - * # NOTE ABOUT TLS Options - * - * If set TLS enabled, equivalent to setting the ssl option. - * - * ### Additional options: - * - * | nodejs option | MongoDB equivalent | type | - * |:---------------------|--------------------------------------------------------- |:---------------------------------------| - * | `ca` | `sslCA`, `tlsCAFile` | `string \| Buffer \| Buffer[]` | - * | `crl` | `sslCRL` | `string \| Buffer \| Buffer[]` | - * | `cert` | `sslCert`, `tlsCertificateFile`, `tlsCertificateKeyFile` | `string \| Buffer \| Buffer[]` | - * | `key` | `sslKey`, `tlsCertificateKeyFile` | `string \| Buffer \| KeyObject[]` | - * | `passphrase` | `sslPass`, `tlsCertificateKeyFilePassword` | `string` | - * | `rejectUnauthorized` | `sslValidate` | `boolean` | - * - */ - tls: boolean; - - /** - * Turn these options into a reusable options dictionary - */ - toJSON(): Record; - /** - * Turn these options into a reusable connection URI - */ - toURI(): string; -} - -const HOSTS_RX = new RegExp( - '(?mongodb(?:\\+srv|)):\\/\\/(?:(?[^:]*)(?::(?[^@]*))?@)?(?[^\\/?]*)(?.*)' -); - -function parseURI(uri: string): { srv: boolean; url: URL; hosts: string[] } { - const match = uri.match(HOSTS_RX); - if (!match) { - throw new MongoParseError(`Invalid connection string ${uri}`); - } - - const protocol = match.groups?.protocol; - const username = match.groups?.username; - const password = match.groups?.password; - const hosts = match.groups?.hosts; - const rest = match.groups?.rest; - - if (!protocol || !hosts) { - throw new MongoParseError('Invalid connection string, protocol and host(s) required'); - } - - const authString = username ? (password ? `${username}:${password}` : `${username}`) : ''; - return { - srv: protocol.includes('srv'), - url: new URL(`${protocol.toLowerCase()}://${authString}@dummyHostname${rest}`), - hosts: hosts.split(',') - }; -} - -export function parseOptions( - uri: string, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - options: MongoClientOptions = {} -): Readonly { - try { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { srv, url, hosts } = parseURI(uri); - const mongoOptions: MongoOptions = ({ srv, hosts } as unknown) as MongoOptions; - // TODO(NODE-2699): option parse logic - return Object.freeze(mongoOptions); - } catch { - return Object.freeze({} as MongoOptions); - } -}