@deepkit/bson
Version:
Deepkit BSON parser
253 lines • 12.5 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const globals_1 = require("@jest/globals");
require("reflect-metadata");
const type_1 = require("@deepkit/type");
const bson_1 = __importDefault(require("bson"));
const bson_serialize_1 = require("../src/bson-serialize");
const bson_jit_parser_1 = require("../src/bson-jit-parser");
const { calculateObjectSize, serialize, deserialize } = bson_1.default;
var MyEnum;
(function (MyEnum) {
MyEnum[MyEnum["first"] = 0] = "first";
MyEnum[MyEnum["second"] = 1] = "second";
MyEnum[MyEnum["third"] = 2] = "third";
})(MyEnum || (MyEnum = {}));
var MyEnum2;
(function (MyEnum2) {
MyEnum2["first"] = "first";
MyEnum2["second"] = "second";
MyEnum2["third"] = "third";
})(MyEnum2 || (MyEnum2 = {}));
let DecoratedValue = class DecoratedValue {
constructor(c = []) {
this.c = c;
}
};
DecoratedValue = __decorate([
__param(0, type_1.t.array(type_1.t.string).decorated),
__metadata("design:paramtypes", [Array])
], DecoratedValue);
class DecoratedValue2 {
constructor() {
this.items = [];
}
}
__decorate([
type_1.t.array(type_1.t.string).decorated,
__metadata("design:type", Array)
], DecoratedValue2.prototype, "items", void 0);
let MyModel = class MyModel {
constructor(name) {
this.name = name;
this.type = 'a';
this.items = new DecoratedValue;
}
};
__decorate([
type_1.t.literal('a').discriminant,
__metadata("design:type", String)
], MyModel.prototype, "type", void 0);
__decorate([
type_1.t,
__metadata("design:type", DecoratedValue)
], MyModel.prototype, "items", void 0);
MyModel = __decorate([
type_1.entity.name('myModel'),
__param(0, type_1.t),
__metadata("design:paramtypes", [String])
], MyModel);
let SimpleModel = class SimpleModel {
constructor(name) {
this.name = name;
this.items = new DecoratedValue;
}
};
__decorate([
type_1.t,
__metadata("design:type", DecoratedValue)
], SimpleModel.prototype, "items", void 0);
SimpleModel = __decorate([
__param(0, type_1.t),
__metadata("design:paramtypes", [String])
], SimpleModel);
const ab = new ArrayBuffer(2);
const uint8Array = new Uint8Array(ab);
uint8Array[0] = 11;
uint8Array[1] = 22;
globals_1.test('compare ab', () => {
const other = new Uint8Array([11, 22]).buffer;
globals_1.expect(ab).toEqual(other);
});
const decoratedValue2 = new DecoratedValue2();
decoratedValue2.items = ['a', 'b', 'c'];
const actualUndefined = Symbol('undefined');
const types = [
[type_1.t.string, 'Hello Peter'],
[type_1.t.number, 1],
[type_1.t.number, 0],
[type_1.t.number, -1],
[type_1.t.number, -90071992547409920],
[type_1.t.number, 90071992547409920],
[type_1.t.number, 134.444444445],
[type_1.t.number, -134.444444445],
[type_1.t.number, 212313134.444444445],
[type_1.t.number, -1212313134.444444445],
[type_1.t.bigint, -1348574839n, undefined, true],
[type_1.t.bigint, -156n, undefined, true],
[type_1.t.bigint, -0n, undefined, true],
[type_1.t.bigint, 0n, undefined, true],
[type_1.t.bigint, 555n, undefined, true],
[type_1.t.bigint, 9223372036854775810n, undefined, true],
[type_1.t.bigint, -9223372036854775810n, undefined, true],
[type_1.t.any, -1348574839n, undefined, true],
[type_1.t.any, -156n, undefined, true],
[type_1.t.any, -0n, undefined, true],
[type_1.t.any, 0n, undefined, true],
[type_1.t.any, 555n, undefined, true],
[type_1.t.any, 9223372036854775810n, undefined, true],
[type_1.t.any, -9223372036854775810n, undefined, true],
[type_1.t.bigint, undefined, undefined, true],
[type_1.t.bigint, 'asd', actualUndefined, true],
[type_1.t.boolean, false],
[type_1.t.boolean, true],
[type_1.t.boolean, true],
[type_1.t.uuid, 'bef8de96-41fe-442f-b70c-c3a150f8c96c'],
[type_1.t.uuid, 'bef8de92-41fe-442f-b70c-c3a150f8c961'],
[type_1.t.mongoId, '507f191e810c19729de860ea'],
[type_1.t.date, new Date('1987-10-12T00:00:00.000Z')],
[type_1.t.date, new Date('2920-08-09T19:02:28.397Z')],
[type_1.t.date, new Date('2020-08-09T19:02:28.397Z')],
[type_1.t.date, new Date('1900-10-12T00:00:00.000Z')],
[type_1.t.date, new Date('1000-10-12T00:00:00.000Z')],
[type_1.t.enum(MyEnum), MyEnum.first],
[type_1.t.enum(MyEnum), MyEnum.second],
[type_1.t.enum(MyEnum), MyEnum.third],
[type_1.t.enum(MyEnum2), MyEnum2.first],
[type_1.t.enum(MyEnum2), MyEnum2.second],
[type_1.t.enum(MyEnum2), MyEnum2.third],
[type_1.t.type({ name: type_1.t.string }), { name: 'Peter' }],
[type_1.t.union(type_1.t.string, MyModel), 'asd'],
[type_1.t.union(type_1.t.string, MyModel), { name: 'foo' }, new MyModel('foo'), true],
[type_1.t.union(type_1.t.string, SimpleModel), 'asd'],
[type_1.t.union(type_1.t.string, SimpleModel), { name: 'foo' }, new SimpleModel('foo')],
[type_1.t.union(type_1.t.mongoId, SimpleModel), '507f191e810c19729de860ea', undefined, true],
[type_1.t.union(type_1.t.mongoId, SimpleModel), { name: 'foo' }, new SimpleModel('foo')],
[type_1.t.union(type_1.t.string, type_1.t.array(type_1.t.string)), 'asd'],
[type_1.t.union(type_1.t.string, type_1.t.array(type_1.t.string)), ['a', 'b']],
[type_1.t.union(type_1.t.string, type_1.t.uuid), 'asd'],
[type_1.t.union(type_1.t.string, type_1.t.uuid), '3c25985e-4e25-45db-9e8a-a487cc78929a'],
[type_1.t.union(type_1.t.string, type_1.t.mongoId), 'asd'],
[type_1.t.union(type_1.t.string, type_1.t.mongoId), '507f191e810c19729de860ea', undefined, true],
[type_1.t.union(type_1.t.string, type_1.t.uuid, type_1.t.date), '3c25985e-4e25-45db-9e8a-a487cc78929a'],
[type_1.t.union(type_1.t.string, type_1.t.uuid, type_1.t.date), 'asd'],
[type_1.t.union(type_1.t.string, type_1.t.map(type_1.t.string)), 'asd'],
[type_1.t.union(type_1.t.string, type_1.t.map(type_1.t.string)), { first: 'asd', second: 'asd' }],
[type_1.t.union(type_1.t.string, type_1.t.partial(MyModel)), 'asd'],
[type_1.t.union(type_1.t.string, type_1.t.partial(MyModel)), { name: 'asd' }],
[type_1.t.union(type_1.t.string, type_1.t.type(ArrayBuffer)), 'asd'],
[type_1.t.union(type_1.t.string, type_1.t.type(ArrayBuffer)), ab, undefined, true],
[type_1.t.union(type_1.t.string, type_1.t.type(Uint8Array)), uint8Array, undefined, true],
[type_1.t.type(DecoratedValue), new DecoratedValue(['a', 'b']), undefined, true],
[type_1.t.type(DecoratedValue2), decoratedValue2, undefined, true],
[type_1.t.union(type_1.t.string, MyModel), { type: 'a', name: 'Peter', items: new DecoratedValue(['a', 'b']), }, undefined, true],
[type_1.t.array(type_1.t.string), ['Peter', 'b']],
[type_1.t.array(type_1.t.number.optional), [1, undefined, 2], undefined, true],
[type_1.t.array(type_1.t.string.optional), ['Peter', undefined, 'Bar'], undefined, true],
[type_1.t.array(type_1.t.string.nullable), ['Peter', null, 'Bar']],
[type_1.t.array(type_1.t.union(type_1.t.string, type_1.t.number)), ['Peter', 23, 'Bar']],
[type_1.t.array(type_1.t.union(type_1.t.boolean, type_1.t.number)), [false, 23, true]],
[type_1.t.map(type_1.t.string), { name: 'Peter' }],
[type_1.t.any, { name: 'Peter', ready: false }],
[type_1.t.type(ArrayBuffer), ab],
[type_1.t.type(Uint8Array), new Uint8Array([22, 44, 55, 66])],
[type_1.t.type(Int16Array), new Int16Array([22, 44, 55, 66])],
[type_1.t.union(type_1.t.type({ type: type_1.t.literal('m'), name: type_1.t.string })), { type: 'm', name: 'Peter' }],
[type_1.t.partial({ name: type_1.t.string }), {}],
[type_1.t.partial({ name: type_1.t.string }), { name: 'Peter' }],
[type_1.t.any, new RegExp('/abc/', 'g')],
[type_1.t.any, new RegExp(/abc/, 'g')],
[type_1.t.any, /abc/g],
[type_1.t.any, /abc/i],
[type_1.t.any, /abc/m],
[type_1.t.any, /abc/gim],
];
globals_1.describe('integration', () => {
for (let i = 0; i < types.length; i++) {
const type = types[i];
const [field, value, expected, dontCompareToBSONJS] = type;
const property = field.buildPropertySchema('test_' + i);
globals_1.test(`types round-trip #${i} ${property.toString()}: ${value}`, () => {
const s = type_1.t.schema({
field: field
});
const sOptional = type_1.t.schema({
field: field.optional
});
const sNullable = type_1.t.schema({
field: field.nullable
});
const obj = {
field: value
};
const expectedFieldValue = expected === actualUndefined ? undefined : expected ?? value;
const expectedObj = {
field: expectedFieldValue
};
globals_1.expect(sOptional.getProperty('field').isOptional).toBe(true);
globals_1.expect(sNullable.getProperty('field').isNullable).toBe(true);
const serializer = bson_serialize_1.getBSONSerializer(s);
const bsonDeepkit = serializer(obj);
// console.log(`types round-trip #${i} ${property.toString()}: ${value} back`, obj, deserialize(Buffer.from(bsonDeepkit)));
const decoder = bson_jit_parser_1.getBSONDecoder(s);
const decoded = decoder(bsonDeepkit);
globals_1.expect(decoded).toEqual(expectedObj);
globals_1.expect(decoder(serializer({}))).toEqual({});
//optional
// expect(getBSONDecoder(sOptional)(getBSONSerializer(sOptional)({}))).toEqual({});
const optionalTrip = bson_jit_parser_1.getBSONDecoder(sOptional)(bson_serialize_1.getBSONSerializer(sOptional)({ field: undefined }));
globals_1.expect(optionalTrip).toEqual({ field: undefined });
globals_1.expect('field' in optionalTrip).toEqual(true);
//null
globals_1.expect(bson_jit_parser_1.getBSONDecoder(sNullable)(bson_serialize_1.getBSONSerializer(sNullable)({ field: undefined }))).toEqual({ field: null });
globals_1.expect('field' in bson_jit_parser_1.getBSONDecoder(sNullable)(bson_serialize_1.getBSONSerializer(sNullable)({ field: undefined }))).toEqual(true);
const nullTrip = bson_jit_parser_1.getBSONDecoder(sNullable)(bson_serialize_1.getBSONSerializer(sNullable)({ field: null }));
globals_1.expect(nullTrip).toEqual({ field: null });
const type = field.buildPropertySchema().type;
const blacklist = [
'uuid',
'objectId',
'arrayBuffer',
'Uint8Array',
'Int16Array'
];
if (blacklist.includes(type))
return;
if (dontCompareToBSONJS)
return;
globals_1.expect(bson_serialize_1.createBSONSizer(s)(obj)).toEqual(calculateObjectSize(obj));
//official BSON serializer has a bug not serializing LONG correctly
if (field.buildPropertySchema().type === 'number' && (value > bson_serialize_1.JS_INT_MAX || value < bson_serialize_1.JS_INT_MIN))
return;
const bsonOfficial = serialize(obj);
globals_1.expect(obj).toEqual(deserialize(serialize(obj)));
globals_1.expect(bsonDeepkit).toEqual(bsonOfficial);
});
}
});
//# sourceMappingURL=integration.spec.js.map