Skip to content

Commit f29f835

Browse files
authored
fix: better support for polymorphic inputs (#87)
1 parent 534c01d commit f29f835

File tree

2 files changed

+74
-5
lines changed

2 files changed

+74
-5
lines changed

src/classes/polymorphic-serialiser.ts

+37-5
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,48 @@ export default class PolymorphicSerializer<
4545
})
4646
);
4747

48-
return documents.reduce((result, document) => {
49-
if (!result) {
50-
return document;
51-
}
48+
// Construct initial document and included data
49+
let document: Partial<DataDocument<PrimaryType>> = {
50+
data: [],
51+
};
52+
53+
// Document versioning
54+
if (options?.version) {
55+
document.jsonapi = { ...document.jsonapi, version: options.version };
56+
}
5257

58+
if (options?.metaizers?.jsonapi) {
59+
document.jsonapi = { ...document.jsonapi, meta: options.metaizers.jsonapi.metaize() };
60+
}
61+
62+
document = documents.reduce((result, document) => {
5363
result.data = [result.data ?? [], document.data ?? []].flat();
5464
result.included = [result.included ?? [], document.included ?? []].flat();
5565

5666
return result;
57-
});
67+
}, document);
68+
69+
// Handle meta
70+
if (options?.metaizers?.document) {
71+
document.meta = options.metaizers.document.metaize(data);
72+
}
73+
74+
// Handle links
75+
if (options?.linkers?.document) {
76+
if (options.linkers.document) {
77+
document.links = { ...document.links, self: options.linkers.document.link(data) };
78+
}
79+
if (options.linkers.paginator) {
80+
const pagination = options.linkers.paginator.paginate(
81+
data as PrimaryType | PrimaryType[]
82+
);
83+
if (pagination) {
84+
document.links = { ...document.links, ...pagination };
85+
}
86+
}
87+
}
88+
89+
return document;
5890
} else if (data) {
5991
return this.serializeType(data, options);
6092
}

test/issue-80.test.ts

+37
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,41 @@ describe('Issue #80 - Polymorphic serializer', () => {
7676
expect(data.data[0].id).toEqual('1');
7777
expect(data.data[0].type).toEqual('Model1');
7878
});
79+
80+
it('should correctly handle empty input', async () => {
81+
const Model1Serializer = new Serializer<Model1>('Model1');
82+
const Model2Serializer = new Serializer<Model2>('Model2');
83+
84+
const PolySerializer = new PolymorphicSerializer<Model>('Model', 'type', {
85+
'type:Model1': Model1Serializer,
86+
'type:Model2': Model2Serializer,
87+
});
88+
89+
const data = (await PolySerializer.serialize([])) as {
90+
data: Resource<Model>;
91+
};
92+
93+
expect(data.data).toBeInstanceOf(Array);
94+
expect(data.data).toHaveLength(0);
95+
});
96+
97+
it('should correctly handle non-array input', async () => {
98+
const model1: Model1 = new Model1('1', 'model1');
99+
100+
const Model1Serializer = new Serializer<Model1>('Model1');
101+
const Model2Serializer = new Serializer<Model2>('Model2');
102+
103+
const PolySerializer = new PolymorphicSerializer<Model>('Model', 'type', {
104+
'type:Model1': Model1Serializer,
105+
'type:Model2': Model2Serializer,
106+
});
107+
108+
const data = (await PolySerializer.serialize(model1)) as {
109+
data: Resource<Model>;
110+
};
111+
112+
expect(data.data).toBeInstanceOf(Resource);
113+
expect(data.data.id).toEqual('1');
114+
expect(data.data.type).toEqual('Model1');
115+
});
79116
});

0 commit comments

Comments
 (0)