quosdolorem
Version:
The MongoDB Shell
101 lines (87 loc) • 3.13 kB
text/typescript
import { bson as BSON } from './index';
const inspectCustom = Symbol.for('nodejs.util.inspect.custom');
export const bsonStringifiers: Record<string, (this: any) => string> = {
ObjectId: function(): string {
return `ObjectId("${this.toHexString()}")`;
},
DBRef: function(): string {
// NOTE: if OID is an ObjectId class it will just print the oid string.
return `DBRef("${this.namespace}", "${
this.oid === undefined || this.oid.toString === undefined ?
this.oid :
this.oid.toString()
}"${this.db ? `, "${this.db}"` : ''})`;
},
MaxKey: function(): string {
return 'MaxKey()';
},
MinKey: function(): string {
return 'MinKey()';
},
Timestamp: function(): string {
return `Timestamp(${this.getLowBits().toString()}, ${this.getHighBits().toString()})`;
},
BSONSymbol: function(): string {
return `BSONSymbol("${this.valueOf()}")`;
},
Code: function(): string {
const j = this.toJSON();
return `Code("${j.code}"${j.scope ? `, ${JSON.stringify(j.scope)}` : ''})`;
},
Decimal128: function(): string {
return `Decimal128.fromString("${this.toString()}")`;
},
Int32: function(): string {
return `Int32(${this.valueOf()})`;
},
Long: function(): string {
return `Long.fromString("${this.toString()}"${this.unsigned ? ', true' : ''})`;
},
Binary: function(): string {
const asBuffer = this.value(true);
switch (this.sub_type) {
case BSON.Binary.SUBTYPE_MD5:
return `MD5("${asBuffer.toString('hex')}")`;
case BSON.Binary.SUBTYPE_UUID:
if (asBuffer.length === 16) {
// Format '0123456789abcdef0123456789abcdef' into
// '01234567-89ab-cdef-0123-456789abcdef'.
const hex = asBuffer.toString('hex');
const asUUID = hex.match(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/)
.slice(1, 6).join('-');
return `UUID("${asUUID}")`;
}
// In case somebody did something weird and used an UUID with a
// non-standard length, fall through.
default:
return `Binary(Buffer.from("${asBuffer.toString('hex')}", "hex"), ${this.sub_type})`;
}
},
};
bsonStringifiers.ObjectID = bsonStringifiers.ObjectId;
/**
* This method modifies the BSON class passed in as argument. This is required so that
* we can have the driver return our BSON classes without having to write our own serializer.
* @param {Object} bson
*/
export default function(bson?: typeof BSON): void {
if (!bson) {
bson = BSON;
}
for (const [ key, stringifier ] of Object.entries(bsonStringifiers)) {
if (!(key in bson)) {
continue;
}
const cls = bson[key as keyof typeof BSON];
for (const key of [inspectCustom, 'inspect']) {
try {
(cls as any).prototype[key] = stringifier;
} catch {
// This may fail because bson.ObjectId.prototype[toString] can exist as a
// read-only property. https://github.com/mongodb/js-bson/pull/412 takes
// care of this. In the CLI repl and Compass this still works fine, because
// those are on bson@1.x.
}
}
}
}