Skip to content

Commit aeae3a7

Browse files
authored
fix: #92 re-sort data after serialization (#93)
1 parent ec9b41b commit aeae3a7

File tree

3 files changed

+80
-1
lines changed

3 files changed

+80
-1
lines changed

.github/workflows/ci.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
node: 18
5555
- name: macOS
5656
machine: macos-latest
57-
node: 14
57+
node: 16
5858
- name: Windows
5959
machine: windows-latest
6060
node: 14

src/classes/polymorphic-serialiser.ts

+11
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ export default class PolymorphicSerializer<
6666
return result;
6767
}, document);
6868

69+
// Sort data to match input order - this is important for cases where
70+
// data has been sorted prior to serialization.
71+
if (Array.isArray(document.data)) {
72+
document.data = document.data.sort((a, b) => {
73+
const aIndex = data.findIndex((datum) => datum.id === a.id);
74+
const bIndex = data.findIndex((datum) => datum.id === b.id);
75+
76+
return aIndex - bIndex;
77+
});
78+
}
79+
6980
// Handle meta
7081
if (options?.metaizers?.document) {
7182
document.meta = options.metaizers.document.metaize(data);

test/issue-92.test.ts

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { PolymorphicSerializer, Serializer } from '../lib';
2+
import Resource from '../lib/models/resource.model';
3+
4+
describe('Issue #92 - Polymorphic serializer ordering', () => {
5+
abstract class Model {
6+
public type: string;
7+
8+
constructor(public id: string) {}
9+
}
10+
11+
class Model1 extends Model {
12+
constructor(id: string) {
13+
super(id);
14+
this.type = 'type:Model1';
15+
}
16+
}
17+
18+
class Model2 extends Model {
19+
constructor(id: string) {
20+
super(id);
21+
this.type = 'type:Model2';
22+
}
23+
}
24+
25+
it('should maintain data input ordering', async () => {
26+
const model1A: Model1 = new Model1('1a');
27+
const model1B: Model1 = new Model1('1b');
28+
const model1C: Model1 = new Model1('1c');
29+
const model2A: Model2 = new Model2('2a');
30+
const model2B: Model2 = new Model2('2b');
31+
32+
const Model1Serializer = new Serializer<Model1>('Model1');
33+
const Model2Serializer = new Serializer<Model2>('Model2');
34+
35+
const PolySerializer = new PolymorphicSerializer<Model>('Model', 'type', {
36+
'type:Model1': Model1Serializer,
37+
'type:Model2': Model2Serializer,
38+
});
39+
40+
const data = (await PolySerializer.serialize([
41+
model1A,
42+
model2A,
43+
model1C,
44+
model2B,
45+
model1B,
46+
])) as {
47+
data: Resource<Model>;
48+
};
49+
50+
expect(data.data).toBeInstanceOf(Array);
51+
expect(data.data).toHaveLength(5);
52+
53+
expect(data.data[0].id).toEqual('1a');
54+
expect(data.data[0].type).toEqual('Model1');
55+
56+
expect(data.data[1].id).toEqual('2a');
57+
expect(data.data[1].type).toEqual('Model2');
58+
59+
expect(data.data[2].id).toEqual('1c');
60+
expect(data.data[2].type).toEqual('Model1');
61+
62+
expect(data.data[3].id).toEqual('2b');
63+
expect(data.data[3].type).toEqual('Model2');
64+
65+
expect(data.data[4].id).toEqual('1b');
66+
expect(data.data[4].type).toEqual('Model1');
67+
});
68+
});

0 commit comments

Comments
 (0)