From 09cc0e2852c1deb68d2dd5edfd9907124f582b1f Mon Sep 17 00:00:00 2001 From: Edward Date: Thu, 18 Apr 2024 09:14:46 +0100 Subject: [PATCH] fix: better support for polymorphic inputs --- src/classes/polymorphic-serialiser.ts | 42 +++++++++++++++++++++++---- test/issue-80.test.ts | 37 +++++++++++++++++++++++ 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/classes/polymorphic-serialiser.ts b/src/classes/polymorphic-serialiser.ts index 054a898..bfa7d20 100644 --- a/src/classes/polymorphic-serialiser.ts +++ b/src/classes/polymorphic-serialiser.ts @@ -45,16 +45,48 @@ export default class PolymorphicSerializer< }) ); - return documents.reduce((result, document) => { - if (!result) { - return document; - } + // Construct initial document and included data + let document: Partial> = { + 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); + + // Handle meta + if (options?.metaizers?.document) { + document.meta = options.metaizers.document.metaize(data); + } + + // Handle links + if (options?.linkers?.document) { + 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 as PrimaryType | PrimaryType[] + ); + if (pagination) { + document.links = { ...document.links, ...pagination }; + } + } + } + + return document; } else if (data) { return this.serializeType(data, options); } diff --git a/test/issue-80.test.ts b/test/issue-80.test.ts index a7afb7f..51c0f45 100644 --- a/test/issue-80.test.ts +++ b/test/issue-80.test.ts @@ -76,4 +76,41 @@ describe('Issue #80 - Polymorphic serializer', () => { expect(data.data[0].id).toEqual('1'); expect(data.data[0].type).toEqual('Model1'); }); + + it('should correctly handle empty input', async () => { + const Model1Serializer = new Serializer('Model1'); + const Model2Serializer = new Serializer('Model2'); + + const PolySerializer = new PolymorphicSerializer('Model', 'type', { + 'type:Model1': Model1Serializer, + 'type:Model2': Model2Serializer, + }); + + const data = (await PolySerializer.serialize([])) as { + data: Resource; + }; + + expect(data.data).toBeInstanceOf(Array); + expect(data.data).toHaveLength(0); + }); + + it('should correctly handle non-array input', async () => { + const model1: Model1 = new Model1('1', 'model1'); + + const Model1Serializer = new Serializer('Model1'); + const Model2Serializer = new Serializer('Model2'); + + const PolySerializer = new PolymorphicSerializer('Model', 'type', { + 'type:Model1': Model1Serializer, + 'type:Model2': Model2Serializer, + }); + + const data = (await PolySerializer.serialize(model1)) as { + data: Resource; + }; + + expect(data.data).toBeInstanceOf(Resource); + expect(data.data.id).toEqual('1'); + expect(data.data.type).toEqual('Model1'); + }); });