@qp-mongosh/service-provider-core 0.0.0-dev.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/.eslintignore +2 -0
- package/.eslintrc.js +1 -0
- package/AUTHORS +11 -0
- package/LICENSE +201 -0
- package/lib/admin.d.ts +28 -0
- package/lib/admin.js +3 -0
- package/lib/admin.js.map +1 -0
- package/lib/all-fle-types.d.ts +2 -0
- package/lib/all-fle-types.js +3 -0
- package/lib/all-fle-types.js.map +1 -0
- package/lib/all-transport-types.d.ts +1 -0
- package/lib/all-transport-types.js +3 -0
- package/lib/all-transport-types.js.map +1 -0
- package/lib/cli-options.d.ts +43 -0
- package/lib/cli-options.js +3 -0
- package/lib/cli-options.js.map +1 -0
- package/lib/closable.d.ts +4 -0
- package/lib/closable.js +3 -0
- package/lib/closable.js.map +1 -0
- package/lib/connect-info.d.ts +19 -0
- package/lib/connect-info.js +35 -0
- package/lib/connect-info.js.map +1 -0
- package/lib/index.d.ts +31 -0
- package/lib/index.js +56 -0
- package/lib/index.js.map +1 -0
- package/lib/platform.d.ts +6 -0
- package/lib/platform.js +11 -0
- package/lib/platform.js.map +1 -0
- package/lib/printable-bson.d.ts +3 -0
- package/lib/printable-bson.js +82 -0
- package/lib/printable-bson.js.map +1 -0
- package/lib/readable.d.ts +18 -0
- package/lib/readable.js +3 -0
- package/lib/readable.js.map +1 -0
- package/lib/service-provider.d.ts +11 -0
- package/lib/service-provider.js +19 -0
- package/lib/service-provider.js.map +1 -0
- package/lib/shell-auth-options.d.ts +7 -0
- package/lib/shell-auth-options.js +3 -0
- package/lib/shell-auth-options.js.map +1 -0
- package/lib/textencoder-polyfill.d.ts +2 -0
- package/lib/textencoder-polyfill.js +22 -0
- package/lib/textencoder-polyfill.js.map +1 -0
- package/lib/uri-generator.d.ts +8 -0
- package/lib/uri-generator.js +176 -0
- package/lib/uri-generator.js.map +1 -0
- package/lib/writable.d.ts +22 -0
- package/lib/writable.js +3 -0
- package/lib/writable.js.map +1 -0
- package/package.json +54 -0
- package/src/admin.ts +119 -0
- package/src/all-fle-types.ts +17 -0
- package/src/all-transport-types.ts +80 -0
- package/src/cli-options.ts +49 -0
- package/src/closable.ts +14 -0
- package/src/connect-info.spec.ts +192 -0
- package/src/connect-info.ts +57 -0
- package/src/index.ts +62 -0
- package/src/platform.ts +6 -0
- package/src/printable-bson.spec.ts +75 -0
- package/src/printable-bson.ts +103 -0
- package/src/readable.ts +242 -0
- package/src/service-provider.ts +23 -0
- package/src/shell-auth-options.ts +7 -0
- package/src/textencoder-polyfill.spec.ts +11 -0
- package/src/textencoder-polyfill.ts +30 -0
- package/src/uri-generator.spec.ts +481 -0
- package/src/uri-generator.ts +265 -0
- package/src/writable.ts +367 -0
- package/tsconfig.json +12 -0
- package/tsconfig.lint.json +8 -0
|
@@ -0,0 +1,49 @@
|
|
|
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
|
+
}
|
package/src/closable.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export default interface Closable {
|
|
2
|
+
/**
|
|
3
|
+
* Close the connection.
|
|
4
|
+
*
|
|
5
|
+
* @param {boolean} force - Whether to force close.
|
|
6
|
+
*/
|
|
7
|
+
close(force: boolean): Promise<void>;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Suspends the connection, i.e. temporarily force-closes it
|
|
11
|
+
* and returns a function that will re-open the connection.
|
|
12
|
+
*/
|
|
13
|
+
suspend(): Promise<() => Promise<void>>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/* eslint camelcase: 0, camelcase: 0 */
|
|
2
|
+
import { expect } from 'chai';
|
|
3
|
+
import getConnectInfo from './connect-info';
|
|
4
|
+
|
|
5
|
+
describe('getConnectInfo', function() {
|
|
6
|
+
const BUILD_INFO = {
|
|
7
|
+
'version': '3.2.0-rc2',
|
|
8
|
+
'gitVersion': '8a3acb42742182c5e314636041c2df368232bbc5',
|
|
9
|
+
'modules': [
|
|
10
|
+
'enterprise'
|
|
11
|
+
],
|
|
12
|
+
'allocator': 'system',
|
|
13
|
+
'javascriptEngine': 'mozjs',
|
|
14
|
+
'sysInfo': 'deprecated',
|
|
15
|
+
'versionArray': [
|
|
16
|
+
3,
|
|
17
|
+
2,
|
|
18
|
+
0,
|
|
19
|
+
-48
|
|
20
|
+
],
|
|
21
|
+
'openssl': {
|
|
22
|
+
'running': 'OpenSSL 0.9.8zg 14 July 2015',
|
|
23
|
+
'compiled': 'OpenSSL 0.9.8y 5 Feb 2013'
|
|
24
|
+
},
|
|
25
|
+
'buildEnvironment': {
|
|
26
|
+
'distmod': '',
|
|
27
|
+
'distarch': 'x86_64',
|
|
28
|
+
'cc': 'gcc: Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)',
|
|
29
|
+
'ccflags': '-fno-omit-frame-pointer -fPIC -fno-strict-aliasing -ggdb -pthread -Wall -Wsign-compare -Wno-unknown-pragmas -Winvalid-pch -Werror -O2 -Wno-unused-function -Wno-unused-private-field -Wno-deprecated-declarations -Wno-tautological-constant-out-of-range-compare -Wno-unused-const-variable -Wno-missing-braces -mmacosx-version-min=10.7 -fno-builtin-memcmp',
|
|
30
|
+
'cxx': 'g++: Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)',
|
|
31
|
+
'cxxflags': '-Wnon-virtual-dtor -Woverloaded-virtual -stdlib=libc++ -std=c++11',
|
|
32
|
+
'linkflags': '-fPIC -pthread -Wl,-bind_at_load -mmacosx-version-min=10.7 -stdlib=libc++ -fuse-ld=gold',
|
|
33
|
+
'target_arch': 'x86_64',
|
|
34
|
+
'target_os': 'osx'
|
|
35
|
+
},
|
|
36
|
+
'bits': 64,
|
|
37
|
+
'debug': false,
|
|
38
|
+
'maxBsonObjectSize': 16777216,
|
|
39
|
+
'storageEngines': [
|
|
40
|
+
'devnull',
|
|
41
|
+
'ephemeralForTest',
|
|
42
|
+
'inMemory',
|
|
43
|
+
'mmapv1',
|
|
44
|
+
'wiredTiger'
|
|
45
|
+
],
|
|
46
|
+
'ok': 1
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const CMD_LINE_OPTS = {
|
|
50
|
+
'argv': [
|
|
51
|
+
'/opt/mongodb-osx-x86_64-enterprise-3.6.3/bin/mongod',
|
|
52
|
+
'--dbpath=/Users/user/testdata'
|
|
53
|
+
],
|
|
54
|
+
'parsed': {
|
|
55
|
+
'storage': {
|
|
56
|
+
'dbPath': '/Users/user/testdata'
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
'ok': 1
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const ATLAS_VERSION = {
|
|
63
|
+
'atlasVersion': '20210330.0.0.1617063608',
|
|
64
|
+
'gitVersion': '8f7e5bdde713391e8123a463895bb7fb660a5ffd'
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const TOPOLOGY_WITH_CREDENTIALS = {
|
|
68
|
+
's': {
|
|
69
|
+
'credentials': {
|
|
70
|
+
'mechanism': 'LDAP'
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const TOPOLOGY_NO_CREDENTIALS = {
|
|
76
|
+
's': {}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const ATLAS_URI = 'mongodb+srv://admin:catscatscats@cat-data-sets.cats.example.net/admin';
|
|
80
|
+
|
|
81
|
+
it('reports on an enterprise version >=3.2 of mongodb with credentials', function() {
|
|
82
|
+
const output = {
|
|
83
|
+
is_atlas: true,
|
|
84
|
+
is_localhost: false,
|
|
85
|
+
is_do: false,
|
|
86
|
+
server_version: '3.2.0-rc2',
|
|
87
|
+
mongosh_version: '0.0.6',
|
|
88
|
+
is_enterprise: true,
|
|
89
|
+
auth_type: 'LDAP',
|
|
90
|
+
is_data_lake: false,
|
|
91
|
+
dl_version: null,
|
|
92
|
+
atlas_version: '20210330.0.0.1617063608',
|
|
93
|
+
is_genuine: true,
|
|
94
|
+
non_genuine_server_name: 'mongodb',
|
|
95
|
+
server_arch: 'x86_64',
|
|
96
|
+
node_version: process.version,
|
|
97
|
+
server_os: 'osx',
|
|
98
|
+
uri: ATLAS_URI
|
|
99
|
+
};
|
|
100
|
+
expect(getConnectInfo(
|
|
101
|
+
ATLAS_URI,
|
|
102
|
+
'0.0.6',
|
|
103
|
+
BUILD_INFO,
|
|
104
|
+
CMD_LINE_OPTS,
|
|
105
|
+
ATLAS_VERSION,
|
|
106
|
+
TOPOLOGY_WITH_CREDENTIALS)).to.deep.equal(output);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('reports on an enterprise version >=3.2 of mongodb with no credentials', function() {
|
|
110
|
+
const output = {
|
|
111
|
+
is_atlas: true,
|
|
112
|
+
is_localhost: false,
|
|
113
|
+
is_do: false,
|
|
114
|
+
server_version: '3.2.0-rc2',
|
|
115
|
+
mongosh_version: '0.0.6',
|
|
116
|
+
is_enterprise: true,
|
|
117
|
+
auth_type: null,
|
|
118
|
+
is_data_lake: false,
|
|
119
|
+
dl_version: null,
|
|
120
|
+
atlas_version: '20210330.0.0.1617063608',
|
|
121
|
+
is_genuine: true,
|
|
122
|
+
non_genuine_server_name: 'mongodb',
|
|
123
|
+
server_arch: 'x86_64',
|
|
124
|
+
node_version: process.version,
|
|
125
|
+
server_os: 'osx',
|
|
126
|
+
uri: ATLAS_URI
|
|
127
|
+
};
|
|
128
|
+
expect(getConnectInfo(
|
|
129
|
+
ATLAS_URI,
|
|
130
|
+
'0.0.6',
|
|
131
|
+
BUILD_INFO,
|
|
132
|
+
CMD_LINE_OPTS,
|
|
133
|
+
ATLAS_VERSION,
|
|
134
|
+
TOPOLOGY_NO_CREDENTIALS)).to.deep.equal(output);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('reports correct information when an empty uri is passed', function() {
|
|
138
|
+
const output = {
|
|
139
|
+
is_atlas: false,
|
|
140
|
+
is_localhost: false,
|
|
141
|
+
is_do: false,
|
|
142
|
+
server_version: '3.2.0-rc2',
|
|
143
|
+
mongosh_version: '0.0.6',
|
|
144
|
+
is_enterprise: true,
|
|
145
|
+
auth_type: 'LDAP',
|
|
146
|
+
is_data_lake: false,
|
|
147
|
+
dl_version: null,
|
|
148
|
+
atlas_version: null,
|
|
149
|
+
is_genuine: true,
|
|
150
|
+
non_genuine_server_name: 'mongodb',
|
|
151
|
+
server_arch: 'x86_64',
|
|
152
|
+
node_version: process.version,
|
|
153
|
+
server_os: 'osx',
|
|
154
|
+
uri: ''
|
|
155
|
+
};
|
|
156
|
+
expect(getConnectInfo(
|
|
157
|
+
'',
|
|
158
|
+
'0.0.6',
|
|
159
|
+
BUILD_INFO,
|
|
160
|
+
CMD_LINE_OPTS,
|
|
161
|
+
null,
|
|
162
|
+
TOPOLOGY_WITH_CREDENTIALS)).to.deep.equal(output);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('does not fail when buildInfo is unavailable', function() {
|
|
166
|
+
const output = {
|
|
167
|
+
is_atlas: false,
|
|
168
|
+
is_localhost: false,
|
|
169
|
+
is_do: false,
|
|
170
|
+
server_version: undefined,
|
|
171
|
+
mongosh_version: '0.0.6',
|
|
172
|
+
is_enterprise: false,
|
|
173
|
+
auth_type: 'LDAP',
|
|
174
|
+
is_data_lake: false,
|
|
175
|
+
dl_version: null,
|
|
176
|
+
atlas_version: null,
|
|
177
|
+
is_genuine: true,
|
|
178
|
+
non_genuine_server_name: 'mongodb',
|
|
179
|
+
server_arch: null,
|
|
180
|
+
node_version: process.version,
|
|
181
|
+
server_os: null,
|
|
182
|
+
uri: ''
|
|
183
|
+
};
|
|
184
|
+
expect(getConnectInfo(
|
|
185
|
+
'',
|
|
186
|
+
'0.0.6',
|
|
187
|
+
null,
|
|
188
|
+
CMD_LINE_OPTS,
|
|
189
|
+
null,
|
|
190
|
+
TOPOLOGY_WITH_CREDENTIALS)).to.deep.equal(output);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/* eslint-disable camelcase */
|
|
2
|
+
// ^ segment data is in snake_case: forgive me javascript, for i have sinned.
|
|
3
|
+
|
|
4
|
+
import getBuildInfo from 'mongodb-build-info';
|
|
5
|
+
|
|
6
|
+
export interface ConnectInfo {
|
|
7
|
+
is_atlas: boolean;
|
|
8
|
+
is_localhost: boolean;
|
|
9
|
+
is_do: boolean;
|
|
10
|
+
server_version: string;
|
|
11
|
+
mongosh_version: string;
|
|
12
|
+
server_os?: string;
|
|
13
|
+
server_arch?: string;
|
|
14
|
+
is_enterprise: boolean;
|
|
15
|
+
auth_type?: string;
|
|
16
|
+
is_data_lake: boolean;
|
|
17
|
+
dl_version?: string;
|
|
18
|
+
atlas_version?: string;
|
|
19
|
+
is_genuine: boolean;
|
|
20
|
+
non_genuine_server_name: string;
|
|
21
|
+
node_version: string;
|
|
22
|
+
uri: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export default function getConnectInfo(uri: string, mongoshVersion: string, buildInfo: any, cmdLineOpts: any, atlasVersion: any, topology: any): ConnectInfo {
|
|
26
|
+
buildInfo ??= {}; // We're currently not getting buildInfo with --apiStrict.
|
|
27
|
+
const { isGenuine: is_genuine, serverName: non_genuine_server_name } =
|
|
28
|
+
getBuildInfo.getGenuineMongoDB(buildInfo, cmdLineOpts);
|
|
29
|
+
const { isDataLake: is_data_lake, dlVersion: dl_version }
|
|
30
|
+
= getBuildInfo.getDataLake(buildInfo);
|
|
31
|
+
|
|
32
|
+
// get this information from topology rather than cmdLineOpts, since not all
|
|
33
|
+
// connections are able to run getCmdLineOpts command
|
|
34
|
+
const auth_type = topology.s.credentials
|
|
35
|
+
? topology.s.credentials.mechanism : null;
|
|
36
|
+
const { serverOs: server_os, serverArch: server_arch }
|
|
37
|
+
= getBuildInfo.getBuildEnv(buildInfo);
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
is_atlas: !!atlasVersion?.atlasVersion || getBuildInfo.isAtlas(uri),
|
|
41
|
+
is_localhost: getBuildInfo.isLocalhost(uri),
|
|
42
|
+
is_do: getBuildInfo.isDigitalOcean(uri),
|
|
43
|
+
server_version: buildInfo.version,
|
|
44
|
+
node_version: process.version,
|
|
45
|
+
mongosh_version: mongoshVersion,
|
|
46
|
+
server_os,
|
|
47
|
+
uri,
|
|
48
|
+
server_arch,
|
|
49
|
+
is_enterprise: getBuildInfo.isEnterprise(buildInfo),
|
|
50
|
+
auth_type,
|
|
51
|
+
is_data_lake,
|
|
52
|
+
dl_version,
|
|
53
|
+
atlas_version: atlasVersion?.atlasVersion ?? null,
|
|
54
|
+
is_genuine,
|
|
55
|
+
non_genuine_server_name
|
|
56
|
+
};
|
|
57
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import './textencoder-polyfill'; // for mongodb-connection-string-url in the java-shell
|
|
2
|
+
import ServiceProvider, { ServiceProviderCore } from './service-provider';
|
|
3
|
+
import getConnectInfo, { ConnectInfo } from './connect-info';
|
|
4
|
+
import { ReplPlatform } from './platform';
|
|
5
|
+
import CliOptions from './cli-options';
|
|
6
|
+
import generateUri from './uri-generator';
|
|
7
|
+
const DEFAULT_DB = 'test';
|
|
8
|
+
import {
|
|
9
|
+
ObjectId,
|
|
10
|
+
DBRef,
|
|
11
|
+
MaxKey,
|
|
12
|
+
MinKey,
|
|
13
|
+
Timestamp,
|
|
14
|
+
BSONSymbol,
|
|
15
|
+
Code,
|
|
16
|
+
Decimal128,
|
|
17
|
+
Int32,
|
|
18
|
+
Long,
|
|
19
|
+
Binary,
|
|
20
|
+
Map,
|
|
21
|
+
calculateObjectSize,
|
|
22
|
+
Double,
|
|
23
|
+
EJSON,
|
|
24
|
+
BSONRegExp
|
|
25
|
+
} from 'bson';
|
|
26
|
+
import { bsonStringifiers } from './printable-bson';
|
|
27
|
+
import ShellAuthOptions from './shell-auth-options';
|
|
28
|
+
export * from './all-transport-types';
|
|
29
|
+
export * from './all-fle-types';
|
|
30
|
+
|
|
31
|
+
const bson = {
|
|
32
|
+
ObjectId,
|
|
33
|
+
DBRef,
|
|
34
|
+
MaxKey,
|
|
35
|
+
MinKey,
|
|
36
|
+
Timestamp,
|
|
37
|
+
BSONSymbol,
|
|
38
|
+
Code,
|
|
39
|
+
Decimal128,
|
|
40
|
+
Int32,
|
|
41
|
+
Long,
|
|
42
|
+
Binary,
|
|
43
|
+
Map,
|
|
44
|
+
calculateObjectSize,
|
|
45
|
+
Double,
|
|
46
|
+
EJSON,
|
|
47
|
+
BSONRegExp
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export {
|
|
51
|
+
ServiceProvider,
|
|
52
|
+
ShellAuthOptions,
|
|
53
|
+
getConnectInfo,
|
|
54
|
+
ReplPlatform,
|
|
55
|
+
CliOptions,
|
|
56
|
+
generateUri,
|
|
57
|
+
DEFAULT_DB,
|
|
58
|
+
ServiceProviderCore,
|
|
59
|
+
bson,
|
|
60
|
+
bsonStringifiers,
|
|
61
|
+
ConnectInfo
|
|
62
|
+
};
|
package/src/platform.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { bson } from './index';
|
|
3
|
+
import { inspect } from 'util';
|
|
4
|
+
import makePrintableBson from './printable-bson';
|
|
5
|
+
|
|
6
|
+
describe('BSON printers', function() {
|
|
7
|
+
before('make BSON objects printable', function() {
|
|
8
|
+
makePrintableBson(bson);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('formats ObjectIds correctly', function() {
|
|
12
|
+
expect(inspect(new bson.ObjectId('5fa5694f88211043b23c7f11')))
|
|
13
|
+
.to.equal('ObjectId("5fa5694f88211043b23c7f11")');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('formats DBRefs correctly', function() {
|
|
17
|
+
expect(inspect(new bson.DBRef('a', new bson.ObjectId('5f16b8bebe434dc98cdfc9cb'), 'db')))
|
|
18
|
+
.to.equal('DBRef("a", ObjectId("5f16b8bebe434dc98cdfc9cb"), "db")');
|
|
19
|
+
expect(inspect(new bson.DBRef('a', 'foo' as any, 'db')))
|
|
20
|
+
.to.equal('DBRef("a", \'foo\', "db")');
|
|
21
|
+
expect(inspect(new bson.DBRef('a', { x: 1 } as any, 'db')))
|
|
22
|
+
.to.equal('DBRef("a", { x: 1 }, "db")');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('formats MinKey and MaxKey correctly', function() {
|
|
26
|
+
expect(inspect(new bson.MinKey())).to.equal('MinKey()');
|
|
27
|
+
expect(inspect(new bson.MaxKey())).to.equal('MaxKey()');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('formats NumberInt correctly', function() {
|
|
31
|
+
expect(inspect(new bson.Int32(32))).to.equal('Int32(32)');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('formats NumberLong correctly', function() {
|
|
35
|
+
expect(inspect(bson.Long.fromString('64'))).to.equal('Long("64")');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('formats unsigned NumberLong correctly', function() {
|
|
39
|
+
expect(inspect(bson.Long.fromString('64', true))).to.equal('Long("64", true)');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('formats NumberDecimal correctly', function() {
|
|
43
|
+
expect(inspect(bson.Decimal128.fromString('1'))).to.equal('Decimal128("1")');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('formats Timestamp correctly', function() {
|
|
47
|
+
expect(inspect(new bson.Timestamp(new bson.Long(100, 1)))).to.equal('Timestamp({ t: 1, i: 100 })');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('formats Symbol correctly', function() {
|
|
51
|
+
expect(inspect(new bson.BSONSymbol('abc'))).to.equal('BSONSymbol("abc")');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('formats Code correctly', function() {
|
|
55
|
+
expect(inspect(new bson.Code('abc'))).to.equal('Code("abc")');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('formats BinData correctly', function() {
|
|
59
|
+
expect(inspect(new bson.Binary('abc'))).to.equal('Binary(Buffer.from("616263", "hex"), 0)');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('formats BSONRegExp correctly', function() {
|
|
63
|
+
expect(inspect(new bson.BSONRegExp('(?-i)AA_', 'im'))).to.equal('BSONRegExp("(?-i)AA_", "im")');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('formats UUIDs correctly', function() {
|
|
67
|
+
expect(inspect(new bson.Binary(Buffer.from('0123456789abcdef0123456789abcdef', 'hex'), 4)))
|
|
68
|
+
.to.equal('UUID("01234567-89ab-cdef-0123-456789abcdef")');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('formats MD5s correctly', function() {
|
|
72
|
+
expect(inspect(new bson.Binary(Buffer.from('0123456789abcdef0123456789abcdef', 'hex'), 5)))
|
|
73
|
+
.to.equal('MD5("0123456789abcdef0123456789abcdef")');
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { bson as BSON } from './index';
|
|
2
|
+
import { inspect } from 'util';
|
|
3
|
+
const inspectCustom = Symbol.for('nodejs.util.inspect.custom');
|
|
4
|
+
|
|
5
|
+
export const bsonStringifiers: Record<string, (this: any, depth: any, options: any) => string> = {
|
|
6
|
+
ObjectId: function(): string {
|
|
7
|
+
return `ObjectId("${this.toHexString()}")`;
|
|
8
|
+
},
|
|
9
|
+
|
|
10
|
+
DBRef: function(depth: any, options: any): string {
|
|
11
|
+
return `DBRef("${this.namespace}", ` +
|
|
12
|
+
inspect(this.oid, options) +
|
|
13
|
+
(this.db ? `, "${this.db}"` : '') +
|
|
14
|
+
')';
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
MaxKey: function(): string {
|
|
18
|
+
return 'MaxKey()';
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
MinKey: function(): string {
|
|
22
|
+
return 'MinKey()';
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
Timestamp: function(): string {
|
|
26
|
+
return `Timestamp({ t: ${this.getHighBits()}, i: ${this.getLowBits()} })`;
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
BSONSymbol: function(): string {
|
|
30
|
+
return `BSONSymbol("${this.valueOf()}")`;
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
Code: function(): string {
|
|
34
|
+
const j = this.toJSON();
|
|
35
|
+
return `Code("${j.code}"${j.scope ? `, ${JSON.stringify(j.scope)}` : ''})`;
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
Decimal128: function(): string {
|
|
39
|
+
return `Decimal128("${this.toString()}")`;
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
Int32: function(): string {
|
|
43
|
+
return `Int32(${this.valueOf()})`;
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
Long: function(): string {
|
|
47
|
+
return `Long("${this.toString()}"${this.unsigned ? ', true' : ''})`;
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
BSONRegExp: function(): string {
|
|
51
|
+
return `BSONRegExp(${JSON.stringify(this.pattern)}, ${JSON.stringify(this.options)})`;
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
Binary: function(): string {
|
|
55
|
+
const asBuffer = this.value(true);
|
|
56
|
+
switch (this.sub_type) {
|
|
57
|
+
case BSON.Binary.SUBTYPE_MD5:
|
|
58
|
+
return `MD5("${asBuffer.toString('hex')}")`;
|
|
59
|
+
case BSON.Binary.SUBTYPE_UUID:
|
|
60
|
+
if (asBuffer.length === 16) {
|
|
61
|
+
// Format '0123456789abcdef0123456789abcdef' into
|
|
62
|
+
// '01234567-89ab-cdef-0123-456789abcdef'.
|
|
63
|
+
const hex = asBuffer.toString('hex');
|
|
64
|
+
const asUUID = hex.match(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/)
|
|
65
|
+
.slice(1, 6).join('-');
|
|
66
|
+
return `UUID("${asUUID}")`;
|
|
67
|
+
}
|
|
68
|
+
// In case somebody did something weird and used an UUID with a
|
|
69
|
+
// non-standard length, fall through.
|
|
70
|
+
default:
|
|
71
|
+
return `Binary(Buffer.from("${asBuffer.toString('hex')}", "hex"), ${this.sub_type})`;
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
bsonStringifiers.ObjectID = bsonStringifiers.ObjectId;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* This method modifies the BSON class passed in as argument. This is required so that
|
|
79
|
+
* we can have the driver return our BSON classes without having to write our own serializer.
|
|
80
|
+
* @param {Object} bson
|
|
81
|
+
*/
|
|
82
|
+
export default function(bson?: typeof BSON): void {
|
|
83
|
+
if (!bson) {
|
|
84
|
+
bson = BSON;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
for (const [ key, stringifier ] of Object.entries(bsonStringifiers)) {
|
|
88
|
+
if (!(key in bson)) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const cls = bson[key as keyof typeof BSON];
|
|
92
|
+
for (const key of [inspectCustom, 'inspect']) {
|
|
93
|
+
try {
|
|
94
|
+
(cls as any).prototype[key] = stringifier;
|
|
95
|
+
} catch {
|
|
96
|
+
// This may fail because bson.ObjectId.prototype[toString] can exist as a
|
|
97
|
+
// read-only property. https://github.com/mongodb/js-bson/pull/412 takes
|
|
98
|
+
// care of this. In the CLI repl and Compass this still works fine, because
|
|
99
|
+
// those are on bson@1.x.
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|