Skip to content

Commit 749d804

Browse files
feat: Add JSR support (#409)
* handle import changes Signed-off-by: Jersey <[email protected]> * fix most errors Signed-off-by: Jersey <[email protected]> * web_bson is on jsr now! Signed-off-by: Jersey <[email protected]> * make the document type the right one so that things dont combust Signed-off-by: Jersey <[email protected]> * turns out the scope is DB Signed-off-by: Jersey <[email protected]> * include our own document type and re-export less Signed-off-by: Jersey <[email protected]> * fix lint Signed-off-by: Jersey <[email protected]> * d o c s Signed-off-by: Jersey <[email protected]> * whoops Signed-off-by: Jersey <[email protected]> * turns out i forgot to update the test Signed-off-by: Jersey <[email protected]> * make readme show on jsr side * alphabetically sort stuff Signed-off-by: Jersey <[email protected]> * fix mentioned issues Signed-off-by: Jersey <[email protected]> * empty commit to run tests again, they're flaky Signed-off-by: Jersey <[email protected]> * turns out i forgot to add a few things back Signed-off-by: Jersey <[email protected]> * whoops i forgot to remove an unused dep --------- Signed-off-by: Jersey <[email protected]>
1 parent 5356b71 commit 749d804

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+418
-178
lines changed

deno.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "@db/mongo",
3+
"version": "0.33.0",
4+
"exports": {
5+
".": "./mod.ts",
6+
"./client": "./src/client.ts",
7+
"./collection": "./src/collection/collection.ts",
8+
"./gridfs": "./src/gridfs/bucket.ts",
9+
"./types": "./src/types.ts"
10+
},
11+
"publish": {
12+
"exclude": [".github", "tests", ".gitattributes", ".gitignore", "deno.lock"]
13+
},
14+
"test": {
15+
"include": [
16+
"tests/cases/*.ts"
17+
]
18+
},
19+
"lock": false
20+
}

deps.ts

+22-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
1-
export * from "https://deno.land/x/[email protected]/mod.js";
2-
export { writeAll } from "https://deno.land/[email protected]/streams/write_all.ts";
3-
export { crypto } from "https://deno.land/[email protected]/crypto/mod.ts";
4-
export { BufReader } from "https://deno.land/[email protected]/io/mod.ts";
5-
export * as b64 from "https://deno.land/[email protected]/encoding/base64.ts";
6-
export * as hex from "https://deno.land/[email protected]/encoding/hex.ts";
1+
export {
2+
Binary,
3+
BSONRegExp,
4+
BSONSymbol,
5+
Code,
6+
DBRef,
7+
Decimal128,
8+
deserialize,
9+
Double,
10+
Int32,
11+
Long,
12+
MaxKey,
13+
MinKey,
14+
ObjectId,
15+
serialize,
16+
Timestamp,
17+
UUID,
18+
} from "jsr:@lucsoft/web-bson@^0.3.1";
19+
export { crypto as stdCrypto } from "jsr:@std/crypto@^0.220.1/crypto";
20+
export { decodeBase64, encodeBase64 } from "jsr:@std/encoding@^0.220.1/base64";
21+
export { encodeHex } from "jsr:@std/encoding@^0.220.1/hex";
22+
export { BufReader, writeAll } from "jsr:@std/io@^0.220.1";

mod.ts

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
export { MongoClient } from "./src/client.ts";
2-
export { Database } from "./src/database.ts";
3-
export { Collection } from "./src/collection/mod.ts";
4-
export * from "./src/types.ts";
5-
export * as Bson from "./deps.ts";
61
export {
72
Binary,
83
BSONRegExp,
@@ -19,5 +14,8 @@ export {
1914
Timestamp,
2015
UUID,
2116
} from "./deps.ts";
22-
export type { Document } from "./deps.ts";
17+
export { MongoClient } from "./src/client.ts";
18+
export { Collection } from "./src/collection/mod.ts";
19+
export { Database } from "./src/database.ts";
2320
export { GridFSBucket } from "./src/gridfs/bucket.ts";
21+
export * from "./src/types.ts";

src/auth/base.ts

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
import { ConnectOptions, Credential } from "../types.ts";
21
import { WireProtocol } from "../protocol/mod.ts";
3-
import { Document } from "../../deps.ts";
2+
import { ConnectOptions, Credential, Document } from "../types.ts";
43

54
export abstract class AuthPlugin {
6-
abstract prepare(
7-
authContext: AuthContext,
8-
): Document;
9-
abstract auth(
10-
authContext: AuthContext,
11-
): Document;
5+
abstract auth(authContext: AuthContext): Document;
6+
abstract prepare(authContext: AuthContext): Document;
127
}
8+
139
/** Context used during authentication */
1410
export class AuthContext {
1511
/** The connection to authenticate */

src/auth/scram.ts

+17-11
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1-
import { Credential } from "../types.ts";
2-
import { saslprep } from "../utils/saslprep/mod.ts";
3-
import { AuthContext, AuthPlugin } from "./base.ts";
4-
import { HandshakeDocument } from "../protocol/handshake.ts";
1+
import {
2+
Binary,
3+
decodeBase64,
4+
encodeBase64,
5+
encodeHex,
6+
stdCrypto,
7+
} from "../../deps.ts";
58
import { MongoDriverError } from "../error.ts";
6-
import { b64, Binary, crypto as stdCrypto, Document, hex } from "../../deps.ts";
9+
import { HandshakeDocument } from "../protocol/handshake.ts";
710
import { driverMetadata } from "../protocol/mod.ts";
11+
import { Credential, Document } from "../types.ts";
12+
import { saslprep } from "../utils/saslprep/mod.ts";
13+
import { AuthContext, AuthPlugin } from "./base.ts";
814
import { pbkdf2 } from "./pbkdf2.ts";
915

1016
type CryptoMethod = "sha1" | "sha256";
@@ -65,7 +71,7 @@ export function clientFirstMessageBare(username: string, nonce: Uint8Array) {
6571
...enc.encode("n="),
6672
...enc.encode(username),
6773
...enc.encode(",r="),
68-
...enc.encode(b64.encodeBase64(nonce)),
74+
...enc.encode(encodeBase64(nonce)),
6975
],
7076
);
7177
}
@@ -160,7 +166,7 @@ export async function continueScramConversation(
160166
const withoutProof = `c=biws,r=${rnonce}`;
161167
const saltedPassword = await HI(
162168
processedPassword,
163-
b64.decodeBase64(salt),
169+
decodeBase64(salt),
164170
iterations,
165171
cryptoMethod,
166172
);
@@ -193,7 +199,7 @@ export async function continueScramConversation(
193199
);
194200
if (
195201
!compareDigest(
196-
b64.decodeBase64(parsedResponse.v),
202+
decodeBase64(parsedResponse.v),
197203
new Uint8Array(serverSignature),
198204
)
199205
) {
@@ -260,7 +266,7 @@ export async function passwordDigest(
260266
"MD5",
261267
enc.encode(`${username}:mongo:${password}`),
262268
);
263-
return hex.encodeHex(new Uint8Array(result));
269+
return encodeHex(new Uint8Array(result));
264270
}
265271

266272
// XOR two buffers
@@ -275,7 +281,7 @@ export function xor(_a: ArrayBuffer, _b: ArrayBuffer) {
275281
res[i] = a[i] ^ b[i];
276282
}
277283

278-
return b64.encodeBase64(res);
284+
return encodeBase64(res);
279285
}
280286

281287
export function H(method: CryptoMethod, text: BufferSource) {
@@ -333,7 +339,7 @@ export async function HI(
333339
cryptoMethod: CryptoMethod,
334340
): Promise<ArrayBuffer> {
335341
// omit the work if already generated
336-
const key = [data, b64.encodeBase64(salt), iterations].join(
342+
const key = [data, encodeBase64(salt), iterations].join(
337343
"_",
338344
);
339345
if (_hiCache[key] !== undefined) {

src/auth/x509.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import { Credential } from "../types.ts";
2-
import { AuthContext, AuthPlugin } from "./base.ts";
31
import { HandshakeDocument } from "../protocol/handshake.ts";
42
import { driverMetadata } from "../protocol/mod.ts";
5-
import { Document } from "../../deps.ts";
3+
import { Credential, Document } from "../types.ts";
4+
import { AuthContext, AuthPlugin } from "./base.ts";
65

76
export interface X509Command extends Document {
87
authenticate: number;

src/client.ts

+33-7
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
1+
import { Cluster } from "./cluster.ts";
12
import { Database } from "./database.ts";
2-
import { BuildInfo, ConnectOptions, ListDatabaseInfo } from "./types.ts";
3-
import { parse } from "./utils/uri.ts";
43
import { MongoDriverError } from "./error.ts";
5-
import { Cluster } from "./cluster.ts";
6-
import { Document } from "../deps.ts";
4+
import {
5+
BuildInfo,
6+
ConnectOptions,
7+
Document,
8+
ListDatabaseInfo,
9+
} from "./types.ts";
10+
import { parse } from "./utils/uri.ts";
11+
12+
/**
13+
* A client that allows you to interact with a MongoDB Server
14+
* @module
15+
*/
716

17+
/** A client that allows you to interact with a MongoDB Server */
818
export class MongoClient {
919
#cluster?: Cluster;
1020
#defaultDbName = "admin";
1121
#buildInfo?: BuildInfo;
1222

13-
get buildInfo() {
23+
/** Get information about your server's build */
24+
get buildInfo(): BuildInfo | undefined {
1425
return this.#buildInfo;
1526
}
1627

17-
getCluster() {
28+
/** Get the cluster associated with the client */
29+
getCluster(): Cluster {
1830
if (!this.#cluster) {
1931
throw new MongoDriverError(
2032
"MongoClient is not connected to the Database",
@@ -24,6 +36,11 @@ export class MongoClient {
2436
return this.#cluster;
2537
}
2638

39+
/**
40+
* Connect to the given MongoDB server
41+
*
42+
* @param options Connection options or a MongoDB URI
43+
*/
2744
async connect(
2845
options: ConnectOptions | string,
2946
): Promise<Database> {
@@ -48,6 +65,12 @@ export class MongoClient {
4865
return this.database((options as ConnectOptions).db);
4966
}
5067

68+
/**
69+
* List all databases on the connected server
70+
*
71+
* @param options Options to pass to the `listDatabases` command
72+
* @returns A list of databases including their name, size on disk, and whether they are empty
73+
*/
5174
async listDatabases(options: {
5275
filter?: Document;
5376
nameOnly?: boolean;
@@ -64,15 +87,18 @@ export class MongoClient {
6487
return databases;
6588
}
6689

90+
/** Run a command on the connected server */
6791
// deno-lint-ignore no-explicit-any
6892
runCommand<T = any>(db: string, body: Document): Promise<T> {
6993
return this.getCluster().protocol.commandSingle(db, body);
7094
}
7195

72-
database(name = this.#defaultDbName): Database {
96+
/** Get a database instance on the connected server */
97+
database(name: string = this.#defaultDbName): Database {
7398
return new Database(this.getCluster(), name);
7499
}
75100

101+
/** Close the connection to the server */
76102
close() {
77103
if (this.#cluster) this.#cluster.close();
78104
}

src/cluster.ts

+13-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import { WireProtocol } from "./protocol/mod.ts";
2-
import { ConnectOptions } from "./types.ts";
31
import { AuthContext, ScramAuthPlugin, X509AuthPlugin } from "./auth/mod.ts";
42
import { MongoDriverError } from "./error.ts";
5-
import { Server } from "./types.ts";
3+
import { WireProtocol } from "./protocol/mod.ts";
4+
import { ConnectOptions, Server } from "./types.ts";
65

76
export class Cluster {
87
#options: ConnectOptions;
@@ -24,7 +23,10 @@ export class Cluster {
2423
);
2524
}
2625

27-
connectToServer(server: Server, options: ConnectOptions) {
26+
connectToServer(
27+
server: Server,
28+
options: ConnectOptions,
29+
): Promise<Deno.TlsConn | Deno.TcpConn> {
2830
const denoConnectOps: Deno.ConnectTlsOptions = {
2931
hostname: server.host,
3032
port: server.port,
@@ -57,7 +59,10 @@ export class Cluster {
5759
);
5860
}
5961

60-
async authenticateToServer(conn: Deno.Conn, options: ConnectOptions) {
62+
async authenticateToServer(
63+
conn: Deno.Conn,
64+
options: ConnectOptions,
65+
): Promise<WireProtocol> {
6166
const protocol = new WireProtocol(conn);
6267
if (options.credential) {
6368
const authContext = new AuthContext(
@@ -111,16 +116,16 @@ export class Cluster {
111116
};
112117
}
113118

114-
get protocol() {
119+
get protocol(): WireProtocol {
115120
return this.getMaster().protocol;
116121
}
117122

118123
close() {
119124
for (const conn of this.#connections) {
120125
try {
121126
conn.close();
122-
} catch (error) {
123-
console.error(`Error closing connection: ${error}`);
127+
} catch {
128+
// this is safe to ignore
124129
}
125130
}
126131
}

0 commit comments

Comments
 (0)