@datastax/astra-db-ts
Version:
Data API TypeScript client
126 lines (125 loc) • 4.95 kB
JavaScript
// Copyright Datastax, Inc
// SPDX-License-Identifier: Apache-2.0
import { SerDes } from '../../../lib/api/ser-des/ser-des.js';
import { NEVERMIND } from '../../../lib/api/ser-des/ctx.js';
import { CollectionCodecs } from '../../../documents/collections/ser-des/codecs.js';
import { $SerializeForCollection } from '../../../documents/collections/ser-des/constants.js';
import { isBigNumber } from '../../../lib/utils.js';
import { buildGetNumCoercionForPathFn, coerceNums } from '../../../documents/collections/ser-des/big-nums.js';
import { CollSerDesCfgHandler } from '../../../documents/collections/ser-des/cfg-handler.js';
import { pathMatches } from '../../../lib/api/ser-des/utils.js';
export class CollSerDes extends SerDes {
constructor(cfg) {
super(CollSerDes.cfg.concat([codecs, cfg]), serialize, deserialize);
Object.defineProperty(this, "_getNumCoercionForPath", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this._getNumCoercionForPath = buildGetNumCoercionForPathFn(cfg);
}
adaptSerCtx(ctx) {
ctx.bigNumsEnabled = !!this._getNumCoercionForPath;
return ctx;
}
adaptDesCtx(ctx) {
ctx.getNumCoercionForPath = this._getNumCoercionForPath;
if (ctx.getNumCoercionForPath) {
ctx.rootObj = coerceNums(ctx.rootObj, ctx.getNumCoercionForPath);
}
return ctx;
}
bigNumsPresent() {
return !!this._cfg?.enableBigNumbers;
}
}
Object.defineProperty(CollSerDes, "cfg", {
enumerable: true,
configurable: true,
writable: true,
value: CollSerDesCfgHandler
});
const serialize = (value, ctx) => {
let resp = null;
// Path-based serializers
for (const pathSer of ctx.serializers.forPath[ctx.path.length] ?? []) {
if (pathMatches(pathSer.path, ctx.path) && pathSer.fns.find((fns) => (resp = fns(value, ctx))[0] !== NEVERMIND)) {
return resp;
}
}
// Name-based serializers
const key = ctx.path[ctx.path.length - 1] ?? '';
const nameSer = ctx.serializers.forName[key];
if (nameSer?.find((fns) => (resp = fns(value, ctx))[0] !== NEVERMIND)) {
return resp;
}
// Type-based & custom serializers
for (const guardSer of ctx.serializers.forGuard) {
if (guardSer.guard(value, ctx) && (resp = guardSer.fn(value, ctx))[0] !== NEVERMIND) {
return resp;
}
}
if (typeof value === 'object' && value !== null) {
// Delegate serializer
if (value[$SerializeForCollection] && (resp = value[$SerializeForCollection](ctx))[0] !== NEVERMIND) {
return resp;
}
// Class-based serializers
const classSer = ctx.serializers.forClass.find((c) => value instanceof c.class);
if (classSer?.fns.find((fns) => (resp = fns(value, ctx))[0] !== NEVERMIND)) {
return resp;
}
// Readable err messages for big numbers if not enabled
if (isBigNumber(value)) {
if (!ctx.bigNumsEnabled) {
throw new Error('BigNumber serialization must be enabled through serdes.enableBigNumbers in CollectionSerDesConfig');
}
return ctx.done();
}
}
else if (typeof value === 'bigint') {
if (!ctx.bigNumsEnabled) {
throw new Error('BigInt serialization must be enabled through serdes.enableBigNumbers in CollectionSerDesConfig');
}
return ctx.done();
}
return ctx.recurse();
};
const deserialize = (value, ctx) => {
let resp = null;
// Path-based deserializers
for (const pathDes of ctx.deserializers.forPath[ctx.path.length] ?? []) {
if (pathMatches(pathDes.path, ctx.path) && pathDes.fns.find((fns) => (resp = fns(value, ctx))[0] !== NEVERMIND)) {
return resp;
}
}
// Name-based deserializers
const key = ctx.path[ctx.path.length - 1] ?? '';
const nameDes = ctx.deserializers.forName[key];
if (nameDes?.find((fns) => (resp = fns(value, ctx))[0] !== NEVERMIND)) {
return resp;
}
// Custom deserializers
for (const guardDes of ctx.deserializers.forGuard) {
if (guardDes.guard(value, ctx) && (resp = guardDes.fn(value, ctx))[0] !== NEVERMIND) {
return resp;
}
}
if (typeof value === 'object' && value !== null) {
// Type-based deserializers
const keys = Object.keys(value);
if (keys.length === 1) {
const typeDes = ctx.deserializers.forType[keys[0]];
if (typeDes?.find((fns) => (resp = fns(value, ctx))[0] !== NEVERMIND)) {
return resp;
}
}
// Insurance
if (isBigNumber(value)) {
return ctx.done(value);
}
}
return ctx.recurse(value);
};
const codecs = CollSerDes.cfg.parse({ codecs: Object.values(CollectionCodecs.Defaults) });