/
serializer.ts
97 lines (83 loc) · 3.07 KB
/
serializer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import { EventDispatcher } from "../utils";
import type { ProjectReflection } from "../models";
import { SerializeEvent, SerializeEventData } from "./events";
import type { ModelToObject } from "./schema";
import type { SerializerComponent } from "./components";
export class Serializer extends EventDispatcher {
/**
* Triggered when the {@link Serializer} begins transforming a project.
* @event EVENT_BEGIN
*/
static EVENT_BEGIN = "begin";
/**
* Triggered when the {@link Serializer} has finished transforming a project.
* @event EVENT_END
*/
static EVENT_END = "end";
private serializers: SerializerComponent<any>[] = [];
addSerializer(serializer: SerializerComponent<any>): void {
if ("serializeGroup" in serializer) {
// Remove this check in 0.24
throw new Error(
"Support for `serializeGroup` was removed. Use supports instead."
);
}
this.serializers.push(serializer);
this.serializers.sort((a, b) => b.priority - a.priority);
}
toObject<T extends { toObject(serializer: Serializer): ModelToObject<T> }>(
value: T
): ModelToObject<T>;
toObject<T extends { toObject(serializer: Serializer): ModelToObject<T> }>(
value: T | undefined
): ModelToObject<T> | undefined;
toObject(
value: { toObject(serializer: Serializer): any } | undefined
): unknown {
if (value === undefined) {
return undefined;
}
return this.serializers
.filter((s) => s.supports(value))
.reduce(
(val, s) => s.toObject(value, val, this),
value.toObject(this)
);
}
toObjectsOptional<
T extends { toObject(serializer: Serializer): ModelToObject<T> }
>(value: T[] | undefined): ModelToObject<T>[] | undefined {
if (!value || value.length === 0) {
return undefined;
}
return value.map((val) => this.toObject(val));
}
/**
* Same as toObject but emits {@link Serializer.EVENT_BEGIN} and {@link Serializer.EVENT_END} events.
* @param value
* @param eventData Partial information to set in the event
*/
projectToObject(
value: ProjectReflection,
eventData: { begin?: SerializeEventData; end?: SerializeEventData } = {}
): ModelToObject<ProjectReflection> {
const eventBegin = new SerializeEvent(Serializer.EVENT_BEGIN, value);
if (eventData.begin) {
eventBegin.outputDirectory = eventData.begin.outputDirectory;
eventBegin.outputFile = eventData.begin.outputFile;
}
this.trigger(eventBegin);
const project = this.toObject(value);
const eventEnd = new SerializeEvent(
Serializer.EVENT_END,
value,
project
);
if (eventData.end) {
eventBegin.outputDirectory = eventData.end.outputDirectory;
eventBegin.outputFile = eventData.end.outputFile;
}
this.trigger(eventEnd);
return project;
}
}