All files / src/persistence/pouchDbStores util.ts

83.87% Statements 26/31
60% Branches 3/5
71.42% Functions 5/7
88.46% Lines 23/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 6642x           42x   42x           42x 42x   42x   105x 35x   70x       42x   51x 17x   34x             42x 35x             35x     42x 17x   17x 17x     17x             42x 17x  
import {
  FromSerializableObjectOptions,
  ToSerializableObjectOptions,
  fromSerializableObject,
  toSerializableObject
} from '@cardano-sdk/util';
import omit from 'lodash/omit.js';
 
const PouchDbDocMetadata = ['_id', '_rev', '_attachments', '_conflicts', '_revisions', '_revs_info'] as const;
type PouchDbDocMetadata = typeof PouchDbDocMetadata[number];
type PouchDbDoc = {
  [k in PouchDbDocMetadata]: unknown;
};
 
const transformationTypeKey = 'transformed_type_';
const TRANSFORMED_KEY_PREFIX = 'transformed_key_';
 
const serializeOptions: ToSerializableObjectOptions = {
  serializeKey: (key) => {
    if (key.startsWith('_')) {
      return `${TRANSFORMED_KEY_PREFIX}${key}`;
    }
    return key;
  },
  transformationTypeKey
};
const deserializeOptions: FromSerializableObjectOptions = {
  deserializeKey: (key) => {
    if (key.startsWith(TRANSFORMED_KEY_PREFIX)) {
      return key.slice(TRANSFORMED_KEY_PREFIX.length);
    }
    return key;
  },
  transformationTypeKey
};
 
// PouchDb doesn't know how to store bigint and Map
// toPouchDbDoc/fromPouchDbDoc converts to/from plain json objects
export const toPouchDbDoc = <T>(obj: T): unknown => {
  Iif (Array.isArray(obj)) {
    const value = obj.map((item) => toSerializableObject(item, serializeOptions));
    return {
      [transformationTypeKey]: 'Array',
      value
    };
  }
  return toSerializableObject(obj, serializeOptions);
};
 
export const fromPouchDbDoc = <T>(doc: unknown): T => {
  if (typeof doc === 'object') {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const docAsAny = doc as any;
    Iif (docAsAny[transformationTypeKey] === 'Array')
      return docAsAny.value.map((val: unknown) => fromSerializableObject(val, deserializeOptions));
  }
  return fromSerializableObject(doc, deserializeOptions);
};
 
// PouchDB adds some metadata on docs when you query them.
// Best to keep the objects used by the wallet clean.
// Would be great to have generic constraints on PouchDb stores, to say "not extends {_id, _rev...}".
// Don't think it's possible.
export const sanitizePouchDbDoc = <T>(doc: T & Partial<PouchDbDoc>): T =>
  fromPouchDbDoc(omit(doc, PouchDbDocMetadata)) as T;