diff --git a/lib/extended_json.js b/lib/extended_json.js index bfb03c35..d4e682ca 100644 --- a/lib/extended_json.js +++ b/lib/extended_json.js @@ -251,6 +251,16 @@ function serializeValue(value, options) { return { $numberDouble: value.toString() }; } + if (value instanceof RegExp) { + let flags = value.flags; + if (flags === undefined) { + flags = value.toString().match(/[gimuy]*$/)[0]; + } + + const rx = new BSONRegExp(value.source, flags); + return rx.toExtendedJSON(); + } + if (value != null && typeof value === 'object') return serializeDocument(value, options); return value; } @@ -258,46 +268,27 @@ function serializeValue(value, options) { function serializeDocument(doc, options) { if (doc == null || typeof doc !== 'object') throw new Error('not an object instance'); - // the document itself is a BSON type - if (doc._bsontype && typeof doc.toExtendedJSON === 'function') { - if (doc._bsontype === 'Code' && doc.scope) { - doc.scope = serializeDocument(doc.scope, options); - } else if (doc._bsontype === 'DBRef' && doc.oid) { - doc.oid = serializeDocument(doc.oid, options); - } - - return doc.toExtendedJSON(options); - } - - // the document is an object with nested BSON types - const _doc = {}; - for (let name in doc) { - let val = doc[name]; - if (Array.isArray(val)) { - _doc[name] = serializeArray(val, options); - } else if (val != null && typeof val.toExtendedJSON === 'function') { - if (val._bsontype === 'Code' && val.scope) { - val.scope = serializeDocument(val.scope, options); - } else if (val._bsontype === 'DBRef' && val.oid) { - val.oid = serializeDocument(val.oid, options); + // the "document" is a BSON type + if (doc._bsontype) { + if (typeof doc.toExtendedJSON === 'function') { + // TODO: the two cases below mutate the original document! Bad. I don't know + // enough about these two BSON types to know how to safely clone these objects, but + // someone who knows MongoDB better should fix this to clone instead of mutating input objects. + if (doc._bsontype === 'Code' && doc.scope) { + doc.scope = serializeDocument(doc.scope, options); + } else if (doc._bsontype === 'DBRef' && doc.oid) { + doc.oid = serializeDocument(doc.oid, options); } - _doc[name] = val.toExtendedJSON(options); - } else if (val instanceof Date) { - _doc[name] = serializeValue(val, options); - } else if (val != null && typeof val === 'object') { - _doc[name] = serializeDocument(val, options); + return doc.toExtendedJSON(options); } - _doc[name] = serializeValue(val, options); - if (val instanceof RegExp) { - let flags = val.flags; - if (flags === undefined) { - flags = val.toString().match(/[gimuy]*$/)[0]; - } + // TODO: should we throw an exception if there's a BSON type that has no toExtendedJSON method? + } - const rx = new BSONRegExp(val.source, flags); - _doc[name] = rx.toExtendedJSON(); - } + // Recursively serialize this document's property values. + const _doc = {}; + for (let name in doc) { + _doc[name] = serializeValue(doc[name], options); } return _doc;