Skip to content

Commit 10e5f00

Browse files
committed
feat(ext-json): add extended JSON codecs directly to BSON types
1 parent 23811c7 commit 10e5f00

13 files changed

+220
-0
lines changed

Diff for: lib/binary.js

+26
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,32 @@ class Binary {
274274
toString(format) {
275275
return this.buffer != null ? this.buffer.slice(0, this.position).toString(format) : '';
276276
}
277+
278+
/**
279+
* @ignore
280+
*/
281+
toExtendedJSON() {
282+
const base64String = Buffer.isBuffer(this.buffer)
283+
? this.buffer.toString('base64')
284+
: Buffer.from(this.buffer).toString('base64');
285+
286+
const subType = Number(this.sub_type).toString(16);
287+
return {
288+
$binary: {
289+
base64: base64String,
290+
subType: subType.length === 1 ? '0' + subType : subType
291+
}
292+
};
293+
}
294+
295+
/**
296+
* @ignore
297+
*/
298+
static fromExtendedJSON(doc) {
299+
const type = doc.$binary.subType ? parseInt(doc.$binary.subType, 16) : 0;
300+
const data = new Buffer(doc.$binary.base64, 'base64');
301+
return new Binary(data, type);
302+
}
277303
}
278304

279305
/**

Diff for: lib/code.js

+18
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,24 @@ class Code {
2222
toJSON() {
2323
return { scope: this.scope, code: this.code };
2424
}
25+
26+
/**
27+
* @ignore
28+
*/
29+
toExtendedJSON() {
30+
if (this.scope) {
31+
return { $code: this.code, $scope: this.scope };
32+
}
33+
34+
return { $code: this.code };
35+
}
36+
37+
/**
38+
* @ignore
39+
*/
40+
static fromExtendedJSON(doc) {
41+
return new Code(doc.$code, doc.$scope);
42+
}
2543
}
2644

2745
Object.defineProperty(Code.prototype, '_bsontype', { value: 'Code' });

Diff for: lib/db_ref.js

+23
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,29 @@ class DBRef {
4242
if (this.db != null) o.$db = this.db;
4343
return o;
4444
}
45+
46+
/**
47+
* @ignore
48+
*/
49+
toExtendedJSON() {
50+
let o = {
51+
$ref: this.collection,
52+
$id: this.oid
53+
};
54+
55+
if (this.db) o.$db = this.db;
56+
o = Object.assign(o, this.fields);
57+
return o;
58+
}
59+
60+
/**
61+
* @ignore
62+
*/
63+
static fromExtendedJSON(doc) {
64+
var copy = Object.assign({}, doc);
65+
['$ref', '$id', '$db'].forEach(k => delete copy[k]);
66+
return new DBRef(doc.$ref, doc.$id, doc.$db, copy);
67+
}
4568
}
4669

4770
Object.defineProperty(DBRef.prototype, '_bsontype', { value: 'DBRef' });

Diff for: lib/decimal128.js

+14
Original file line numberDiff line numberDiff line change
@@ -788,5 +788,19 @@ Decimal128.prototype.toJSON = function() {
788788
return { $numberDecimal: this.toString() };
789789
};
790790

791+
/**
792+
* @ignore
793+
*/
794+
Decimal128.prototype.toExtendedJSON = function() {
795+
return { $numberDecimal: this.toString() };
796+
};
797+
798+
/**
799+
* @ignore
800+
*/
801+
Decimal128.fromExtendedJSON = function(doc) {
802+
return Decimal128.fromString(doc.$numberDecimal);
803+
};
804+
791805
Object.defineProperty(Decimal128.prototype, '_bsontype', { value: 'Decimal128' });
792806
module.exports = Decimal128;

Diff for: lib/double.js

+17
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@ class Double {
2929
toJSON() {
3030
return this.value;
3131
}
32+
33+
/**
34+
* @ignore
35+
*/
36+
toExtendedJSON(options) {
37+
if (options && options.relaxed && isFinite(this.value)) return this.value;
38+
return { $numberDouble: this.value.toString() };
39+
}
40+
41+
/**
42+
* @ignore
43+
*/
44+
static fromExtendedJSON(doc, options) {
45+
return options && options.relaxed
46+
? parseFloat(doc.$numberDouble)
47+
: new Double(parseFloat(doc.$numberDouble));
48+
}
3249
}
3350

3451
Object.defineProperty(Double.prototype, '_bsontype', { value: 'Double' });

Diff for: lib/int_32.js

+15
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@ class Int32 {
2929
toJSON() {
3030
return this.value;
3131
}
32+
33+
/**
34+
* @ignore
35+
*/
36+
toExtendedJSON(options) {
37+
if (options && options.relaxed) return this.value;
38+
return { $numberInt: this.value.toString() };
39+
}
40+
41+
/**
42+
* @ignore
43+
*/
44+
static fromExtendedJSON(doc, options) {
45+
return options && options.relaxed ? parseInt(doc.$numberInt, 10) : new Int32(doc.$numberInt);
46+
}
3247
}
3348

3449
Object.defineProperty(Int32.prototype, '_bsontype', { value: 'Int32' });

Diff for: lib/long.js

+16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
'use strict';
22
const Long = require('long');
33

4+
/**
5+
* @ignore
6+
*/
7+
Long.prototype.toExtendedJSON = function(options) {
8+
if (options && options.relaxed) return this.toNumber();
9+
return { $numberLong: this.toString() };
10+
};
11+
12+
/**
13+
* @ignore
14+
*/
15+
Long.fromExtendedJSON = function(doc, options) {
16+
const result = Long.fromString(doc.$numberLong);
17+
return options && options.relaxed ? result.toNumber() : result;
18+
};
19+
420
Object.defineProperty(Long.prototype, '_bsontype', { value: 'Long' });
521
module.exports = Long;

Diff for: lib/max_key.js

+14
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,20 @@ class MaxKey {
99
* @return {MaxKey} A MaxKey instance
1010
*/
1111
constructor() {}
12+
13+
/**
14+
* @ignore
15+
*/
16+
toExtendedJSON() {
17+
return { $maxKey: 1 };
18+
}
19+
20+
/**
21+
* @ignore
22+
*/
23+
static fromExtendedJSON() {
24+
return new MaxKey();
25+
}
1226
}
1327

1428
Object.defineProperty(MaxKey.prototype, '_bsontype', { value: 'MaxKey' });

Diff for: lib/min_key.js

+14
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,20 @@ class MinKey {
99
* @return {MinKey} A MinKey instance
1010
*/
1111
constructor() {}
12+
13+
/**
14+
* @ignore
15+
*/
16+
toExtendedJSON() {
17+
return { $minKey: 1 };
18+
}
19+
20+
/**
21+
* @ignore
22+
*/
23+
static fromExtendedJSON() {
24+
return new MinKey();
25+
}
1226
}
1327

1428
Object.defineProperty(MinKey.prototype, '_bsontype', { value: 'MinKey' });

Diff for: lib/objectid.js

+15
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,21 @@ class ObjectId {
351351

352352
return false;
353353
}
354+
355+
/**
356+
* @ignore
357+
*/
358+
toExtendedJSON() {
359+
if (this.toHexString) return { $oid: this.toHexString() };
360+
return { $oid: this.toString('hex') };
361+
}
362+
363+
/**
364+
* @ignore
365+
*/
366+
static fromExtendedJSON(doc) {
367+
return new ObjectId(doc.$oid);
368+
}
354369
}
355370

356371
/**

Diff for: lib/regexp.js

+20
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,26 @@ class BSONRegExp {
3838
}
3939
}
4040
}
41+
42+
/**
43+
* @ignore
44+
*/
45+
toExtendedJSON() {
46+
return { $regularExpression: { pattern: this.pattern, options: this.options } };
47+
}
48+
49+
/**
50+
* @ignore
51+
*/
52+
static fromExtendedJSON(doc) {
53+
return new BSONRegExp(
54+
doc.$regularExpression.pattern,
55+
doc.$regularExpression.options
56+
.split('')
57+
.sort()
58+
.join('')
59+
);
60+
}
4161
}
4262

4363
Object.defineProperty(BSONRegExp.prototype, '_bsontype', { value: 'BSONRegExp' });

Diff for: lib/symbol.js

+14
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,20 @@ class Symbol {
4242
toJSON() {
4343
return this.value;
4444
}
45+
46+
/**
47+
* @ignore
48+
*/
49+
toExtendedJSON() {
50+
return { $symbol: this.value };
51+
}
52+
53+
/**
54+
* @ignore
55+
*/
56+
static fromExtendedJSON(doc) {
57+
return new Symbol(doc.$symbol);
58+
}
4559
}
4660

4761
Object.defineProperty(Symbol.prototype, '_bsontype', { value: 'Symbol' });

Diff for: lib/timestamp.js

+14
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,20 @@ class Timestamp extends Long {
7474
static fromString(str, opt_radix) {
7575
return new Timestamp(Long.fromString(str, opt_radix));
7676
}
77+
78+
/**
79+
* @ignore
80+
*/
81+
toExtendedJSON() {
82+
return { $timestamp: { t: this.high, i: this.low } };
83+
}
84+
85+
/**
86+
* @ignore
87+
*/
88+
static fromExtendedJSON(doc) {
89+
return new Timestamp(doc.$timestamp.i, doc.$timestamp.t);
90+
}
7791
}
7892

7993
Object.defineProperty(Timestamp.prototype, '_bsontype', { value: 'Timestamp' });

0 commit comments

Comments
 (0)