UNPKG

ts-japi

Version:

A highly-modular (typescript-friendly)-framework agnostic library for serializing data to the JSON:API specification

105 lines 4.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const serializer_1 = __importDefault(require("./serializer")); class PolymorphicSerializer extends serializer_1.default { serialisers; key; constructor(commonName, key, serializers) { super(commonName); this.serialisers = serializers; this.key = key; } async serialize(data, options) { if (Array.isArray(data)) { const documents = await Promise.all(Object.values(data.reduce((acc, d) => { // group data by type const type = d[this.key]; if (!acc[type]) { acc[type] = []; } acc[type].push(d); return acc; }, {})).map((d) => { return this.serializeType(d, options); })); // Construct initial document and included data let document = { data: [], }; // Document versioning if (options?.version) { document.jsonapi = { ...document.jsonapi, version: options.version }; } if (options?.metaizers?.jsonapi) { document.jsonapi = { ...document.jsonapi, meta: options.metaizers.jsonapi.metaize() }; } document = documents.reduce((result, document) => { result.data = [result.data ?? [], document.data ?? []].flat(); result.included = [result.included ?? [], document.included ?? []].flat(); return result; }, document); // Sort data to match input order - this is important for cases where // data has been sorted prior to serialization. if (Array.isArray(document.data)) { document.data = document.data.sort((a, b) => { const aIndex = data.findIndex((datum) => datum.id === a.id); const bIndex = data.findIndex((datum) => datum.id === b.id); return aIndex - bIndex; }); } // Handle meta if (options?.metaizers?.document) { document.meta = options.metaizers.document.metaize(data); } // Handle links if (options?.linkers) { if (options.linkers.document) { document.links = { ...document.links, self: options.linkers.document.link(data) }; } if (options.linkers.paginator) { const pagination = options.linkers.paginator.paginate(data); if (pagination) { document.links = { ...document.links, ...pagination }; } } } return document; } else if (data) { return this.serializeType(data, options); } return Object.values(this.serialisers)[0].serialize(data, options); } createIdentifier(data, options) { const serializer = this.getSerializerForData(data); if (serializer) { return serializer.createIdentifier(data, options); } return super.createIdentifier(data, options); } async createResource(data, options, helpers, relatorDataCache) { const serializer = this.getSerializerForData(data); if (serializer) { return serializer.createResource(data, options, helpers, relatorDataCache); } return super.createResource(data, options, helpers, relatorDataCache); } async serializeType(data, options) { const serializer = this.getSerializerForData(Array.isArray(data) ? data[0] : data); if (serializer) { return serializer.serialize(data, options); } return super.serialize(data, options); } getSerializerForData(data) { if (this.serialisers[data[this.key]]) { return this.serialisers[data[this.key]]; } return null; } } exports.default = PolymorphicSerializer; //# sourceMappingURL=polymorphic-serialiser.js.map