Skip to content

Commit 4843287

Browse files
committed
NODE-2253: Serialize v1 Extended JSON:
- Adds a legacy: true option to serialize and stringify - Adds tests for cases where v1 and v2 extjson differ.
1 parent cea1867 commit 4843287

File tree

8 files changed

+134
-17
lines changed

8 files changed

+134
-17
lines changed

lib/binary.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,12 +280,18 @@ class Binary {
280280
/**
281281
* @ignore
282282
*/
283-
toExtendedJSON() {
283+
toExtendedJSON(options) {
284284
const base64String = Buffer.isBuffer(this.buffer)
285285
? this.buffer.toString('base64')
286286
: Buffer.from(this.buffer).toString('base64');
287287

288288
const subType = Number(this.sub_type).toString(16);
289+
if (options.legacy) {
290+
return {
291+
$binary: base64String,
292+
$type: subType.length === 1 ? '0' + subType : subType
293+
};
294+
}
289295
return {
290296
$binary: {
291297
base64: base64String,

lib/db_ref.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,16 @@ class DBRef {
4646
/**
4747
* @ignore
4848
*/
49-
toExtendedJSON() {
49+
toExtendedJSON(options) {
5050
let o = {
5151
$ref: this.collection,
5252
$id: this.oid
5353
};
5454

55+
if (options.legacy) {
56+
return o;
57+
}
58+
5559
if (this.db) o.$db = this.db;
5660
o = Object.assign(o, this.fields);
5761
return o;

lib/double.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ class Double {
3434
* @ignore
3535
*/
3636
toExtendedJSON(options) {
37-
if (options && options.relaxed && isFinite(this.value)) return this.value;
37+
if (options && (options.legacy || (options.relaxed && isFinite(this.value)))) {
38+
return this.value;
39+
}
3840
return { $numberDouble: this.value.toString() };
3941
}
4042

lib/extended_json.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,11 @@ function serializeValue(value, options) {
233233
// is it in year range 1970-9999?
234234
inRange = dateNum > -1 && dateNum < 253402318800000;
235235

236+
if (options.legacy) {
237+
return options.relaxed && inRange
238+
? { $date: value.getTime().toString() }
239+
: { $date: getISOString(value) };
240+
}
236241
return options.relaxed && inRange
237242
? { $date: getISOString(value) }
238243
: { $date: { $numberLong: value.getTime().toString() } };
@@ -258,7 +263,7 @@ function serializeValue(value, options) {
258263
}
259264

260265
const rx = new BSONRegExp(value.source, flags);
261-
return rx.toExtendedJSON();
266+
return rx.toExtendedJSON(options);
262267
}
263268

264269
if (value != null && typeof value === 'object') return serializeDocument(value, options);

lib/int_32.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class Int32 {
3434
* @ignore
3535
*/
3636
toExtendedJSON(options) {
37-
if (options && options.relaxed) return this.value;
37+
if (options && (options.relaxed || options.legacy)) return this.value;
3838
return { $numberInt: this.value.toString() };
3939
}
4040

lib/regexp.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ class BSONRegExp {
4242
/**
4343
* @ignore
4444
*/
45-
toExtendedJSON() {
45+
toExtendedJSON(options) {
46+
if (options.legacy) {
47+
return { $regex: this.pattern, $options: this.options };
48+
}
4649
return { $regularExpression: { pattern: this.pattern, options: this.options } };
4750
}
4851

package-lock.json

Lines changed: 30 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/node/extended_json_tests.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,4 +498,82 @@ describe('Extended JSON', function() {
498498
expect(() => EJSON.serialize(badArray)).to.throw();
499499
// expect(() => EJSON.serialize(badMap)).to.throw(); // uncomment when EJSON supports ES6 Map
500500
});
501+
502+
context('when dealing with legacy extended json', function() {
503+
describe('.stringify', function() {
504+
context('when serializing binary', function() {
505+
it('stringifies $binary and $type', function() {
506+
const binary = new Binary(new Uint8Array([1, 2, 3, 4, 5]));
507+
const doc = { field: binary };
508+
const json = EJSON.stringify(doc, { legacy: true });
509+
expect(json).to.equal('{"field":{"$binary":"AQIDBAU=","$type":"00"}}');
510+
});
511+
});
512+
513+
context('when serializing date', function() {
514+
context('when using strict mode', function() {
515+
it('stringifies $date with with ISO-8601 string', function() {
516+
const date = new Date(1452124800000);
517+
const doc = { field: date };
518+
const json = EJSON.stringify(doc, { legacy: true, relaxed: false });
519+
expect(json).to.equal('{"field":{"$date":"2016-01-07T00:00:00Z"}}');
520+
});
521+
});
522+
523+
context('when using relaxed mode', function() {
524+
it('stringifies $date with with millis since epoch', function() {
525+
const date = new Date(1452124800000);
526+
const doc = { field: date };
527+
const json = EJSON.stringify(doc, { legacy: true, relaxed: true });
528+
expect(json).to.equal('{"field":{"$date":"1452124800000"}}');
529+
});
530+
});
531+
});
532+
533+
context('when serializing regex', function() {
534+
it('stringifies $regex and $options', function() {
535+
const regexp = new BSONRegExp('hello world', 'i');
536+
const doc = { field: regexp };
537+
const json = EJSON.stringify(doc, { legacy: true });
538+
expect(json).to.equal('{"field":{"$regex":"hello world","$options":"i"}}');
539+
});
540+
});
541+
542+
context('when serializing dbref', function() {
543+
it('stringifies $ref and $id', function() {
544+
const dbRef = new DBRef('tests', new Int32(1));
545+
const doc = { field: dbRef };
546+
const json = EJSON.stringify(doc, { legacy: true });
547+
expect(json).to.equal('{"field":{"$ref":"tests","$id":1}}');
548+
});
549+
});
550+
551+
context('when serializing dbref', function() {
552+
it('stringifies $ref and $id', function() {
553+
const dbRef = new DBRef('tests', new Int32(1));
554+
const doc = { field: dbRef };
555+
const json = EJSON.stringify(doc, { legacy: true });
556+
expect(json).to.equal('{"field":{"$ref":"tests","$id":1}}');
557+
});
558+
});
559+
560+
context('when serializing int32', function() {
561+
it('stringifies the number', function() {
562+
const int32 = new Int32(1);
563+
const doc = { field: int32 };
564+
const json = EJSON.stringify(doc, { legacy: true });
565+
expect(json).to.equal('{"field":1}');
566+
});
567+
});
568+
569+
context('when serializing double', function() {
570+
it('stringifies the number', function() {
571+
const doub = new Double(1.1);
572+
const doc = { field: doub };
573+
const json = EJSON.stringify(doc, { legacy: true });
574+
expect(json).to.equal('{"field":1.1}');
575+
});
576+
});
577+
});
578+
});
501579
});

0 commit comments

Comments
 (0)