@datastax/astra-db-ts
Version:
Data API TypeScript client
160 lines (159 loc) • 6.97 kB
JavaScript
;
// Copyright Datastax, Inc
// SPDX-License-Identifier: Apache-2.0
Object.defineProperty(exports, "__esModule", { value: true });
exports.TableCodecs = void 0;
// Important to import from specific paths here to avoid circular dependencies
const blob_js_1 = require("../../../documents/datatypes/blob.js");
const date_js_1 = require("../../../documents/datatypes/date.js");
const duration_js_1 = require("../../../documents/datatypes/duration.js");
const time_js_1 = require("../../../documents/datatypes/time.js");
const uuid_js_1 = require("../../../documents/datatypes/uuid.js");
const vector_js_1 = require("../../../documents/datatypes/vector.js");
const index_js_1 = require("../../../lib/index.js");
const bignumber_js_1 = require("bignumber.js");
const constants_js_1 = require("../../../documents/tables/ser-des/constants.js");
const inet_js_1 = require("../../../documents/datatypes/inet.js");
const utils_js_1 = require("../../../documents/utils.js");
const utils_js_2 = require("../../../lib/api/ser-des/utils.js");
class TableCodecs {
static forName(name, optsOrClass) {
validateIfCodecClass(optsOrClass);
return [{
tag: 'forName',
name: name,
opts: (constants_js_1.$DeserializeForTable in optsOrClass) ? { deserialize: optsOrClass[constants_js_1.$DeserializeForTable] } : optsOrClass,
}];
}
static forPath(path, optsOrClass) {
validateIfCodecClass(optsOrClass);
return [{
tag: 'forPath',
path: path,
opts: (constants_js_1.$DeserializeForTable in optsOrClass) ? { deserialize: optsOrClass[constants_js_1.$DeserializeForTable] } : optsOrClass,
}];
}
static forType(type, optsOrClass) {
validateIfCodecClass(optsOrClass);
return [{
tag: 'forType',
type: type,
opts: (constants_js_1.$DeserializeForTable in optsOrClass) ? { deserialize: optsOrClass[constants_js_1.$DeserializeForTable] } : optsOrClass,
}];
}
static custom(opts) {
return [{ tag: 'custom', opts: opts }];
}
static asCodecClass(clazz, fns) {
if (fns) {
if (!('prototype' in clazz)) {
throw new TypeError(`Cannot attach ser/des functions to non-class ${clazz}`);
}
clazz[constants_js_1.$DeserializeForTable] = fns.deserializeForTable;
(clazz.prototype)[constants_js_1.$SerializeForTable] = fns.serializeForTable;
}
assertIsCodecClass(clazz);
return clazz;
}
}
exports.TableCodecs = TableCodecs;
Object.defineProperty(TableCodecs, "Defaults", {
enumerable: true,
configurable: true,
writable: true,
value: {
bigint: TableCodecs.forType('bigint', {
deserialize: (value, ctx) => ctx.done(BigInt(value)),
}),
blob: TableCodecs.forType('blob', blob_js_1.DataAPIBlob),
counter: TableCodecs.forType('counter', {
deserialize: (value, ctx) => ctx.done(BigInt(value)),
}),
date: TableCodecs.forType('date', date_js_1.DataAPIDate),
decimal: TableCodecs.forType('decimal', {
deserialize: (value, ctx) => ctx.done((0, bignumber_js_1.BigNumber)(value)),
}),
double: TableCodecs.forType('double', {
deserialize: (value, ctx) => ctx.done(parseFloat(value)),
}),
duration: TableCodecs.forType('duration', duration_js_1.DataAPIDuration),
float: TableCodecs.forType('float', {
deserialize: (value, ctx) => ctx.done(parseFloat(value)),
}),
int: TableCodecs.forType('int', {
deserialize: (value, ctx) => ctx.done(value),
}),
inet: TableCodecs.forType('inet', inet_js_1.DataAPIInet),
smallint: TableCodecs.forType('smallint', {
deserialize: (value, ctx) => ctx.done(value),
}),
time: TableCodecs.forType('time', time_js_1.DataAPITime),
timestamp: TableCodecs.forType('timestamp', {
serializeClass: Date,
serialize(date, ctx) {
if (isNaN(date.valueOf())) {
throw new Error(`Can not serialize an invalid date (at '${(0, index_js_1.escapeFieldNames)(ctx.path)}')`);
}
return ctx.done(date.toISOString());
},
deserialize(value, ctx) {
return ctx.done(new Date(value));
},
}),
timeuuid: TableCodecs.forType('timeuuid', uuid_js_1.UUID),
tinyint: TableCodecs.forType('tinyint', {
deserialize: (value, ctx) => ctx.done(value),
}),
uuid: TableCodecs.forType('uuid', uuid_js_1.UUID),
vector: TableCodecs.forType('vector', vector_js_1.DataAPIVector),
varint: TableCodecs.forType('varint', {
deserialize: (value, ctx) => {
return ctx.done(BigInt(value));
},
}),
map: TableCodecs.forType('map', {
serializeClass: Map,
serialize: (value, ctx) => {
if (value.size) {
return ctx.recurse([...value.entries()]);
}
else {
return ctx.done({}); // BUG https://github.com/stargate/data-api/issues/2005 - can not pass an empty array for a map
}
},
deserialize(_, ctx) {
ctx.mapAfter((es) => new Map(Array.isArray(es) ? es : Object.entries(es)));
return ctx.recurse();
},
}),
list: TableCodecs.forType('list', {
deserialize(_, ctx) {
return ctx.recurse();
},
}),
set: TableCodecs.forType('set', {
serializeClass: Set,
serialize: (value, ctx) => {
return ctx.recurse([...value]);
},
deserialize(_, ctx) {
ctx.mapAfter((es) => new Set(es));
return ctx.recurse();
},
}),
}
});
function assertIsCodecClass(clazz) {
if (typeof clazz !== 'function') {
throw new TypeError(`Invalid codec class: expected a constructor; got ${(0, utils_js_1.betterTypeOf)(clazz)}`);
}
(0, utils_js_2.assertHasSerializeFor)(clazz, constants_js_1.$SerializeForTable, '$SerializeForTable');
(0, utils_js_2.assertHasDeserializeFor)(clazz, constants_js_1.$DeserializeForTable, '$DeserializeForTable');
}
function validateIfCodecClass(val) {
if (typeof val === 'function') {
// We can't check for $SerializeForTable here because it may not be on the prototype, depending on how it's
// implemented in the class. This at least helps catch cases when a completely wrong class is passed.
(0, utils_js_2.assertHasDeserializeFor)(val, constants_js_1.$DeserializeForTable, '$DeserializeForTable');
}
}