UNPKG

@lordfokas/magic-orm

Version:

A class-based ORM in TypeScript. Unorthodox and extremely opinionated, made to fit my specific use cases.

79 lines 2.71 kB
import { Entity } from "./Entity.js"; export class Serializer { /** Entity name to Entity Class map */ static #forward = {}; /** Entity Class name to Entity name map */ static #reverse = {}; static register(entity, name) { this.#forward[name] = entity; this.#reverse[entity.name] = name; } static lookup(name) { return this.#forward[name]; } /** Transforms a JSON structure into concrete entities */ static fromJSON(data) { if (typeof data !== 'string') throw new Error('Expected data type to be string'); return JSON.parse(data, (k, obj) => Serializer.#reviver(obj)); } /** Transforms an object into concrete entities */ static fromObject(data) { return Serializer.#traverse(data, (obj) => Serializer.#reviver(obj)); } /** Deserialization function */ static #reviver(val) { if (val instanceof Object && val['@type']) { const obj = val; const ctor = this.#forward[obj["@type"]]; if (!ctor) throw new Error(`Entity name "${obj["@type"]}" not recognized`); const entity = new ctor(obj); delete entity["@type"]; return entity; } else { return val; } } /** Converts entities into JSON strings. */ static toJSON(data, pretty = false) { return JSON.stringify(Serializer.toObject(data), null, pretty ? 4 : 0); } /** Converts entities into raw objects */ static toObject(data) { return Serializer.#traverse(data, $ => $, (obj) => { if (obj instanceof Entity) { const type = this.#reverse[obj.constructor.name]; if (!type) throw new Error(`Entity class "${obj.constructor.name}" not recognized`); return { "@type": type }; } else if (Array.isArray(data)) { return []; } else { return obj; } }); } /** Applies a function to every node of the given data */ static #traverse(data, fn, init) { if (data instanceof Object) { const obj = init ? init(data) : {}; for (const key in data) { obj[key] = Serializer.#traverse(data[key], fn, init); } return fn(obj); } if (Array.isArray(data)) { const arr = init ? init(data) : []; for (const e of data) { arr.push(Serializer.#traverse(e, fn, init)); } return fn(arr); } return data; } } //# sourceMappingURL=Serializer.js.map