UNPKG

@datastax/astra-db-ts

Version:
126 lines (125 loc) 4.95 kB
// 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) });