@tsed/json-mapper 8.11.1 → 8.12.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/lib/esm/components/DateMapper.js +0 -1
  2. package/lib/esm/components/PrimitiveMapper.js +0 -1
  3. package/lib/esm/components/SymbolMapper.js +0 -1
  4. package/lib/esm/decorators/afterDeserialize.js +0 -1
  5. package/lib/esm/decorators/beforeDeserialize.js +0 -1
  6. package/lib/esm/decorators/jsonMapper.js +0 -1
  7. package/lib/esm/decorators/onDeserialize.js +0 -1
  8. package/lib/esm/decorators/onSerialize.js +0 -1
  9. package/lib/esm/domain/JsonDeserializer.js +0 -1
  10. package/lib/esm/domain/JsonDeserializerOptions.js +0 -1
  11. package/lib/esm/domain/JsonMapperCompiler.js +0 -1
  12. package/lib/esm/domain/JsonMapperGlobalOptions.js +0 -1
  13. package/lib/esm/domain/JsonMapperSettings.js +0 -1
  14. package/lib/esm/domain/JsonMapperTypesContainer.js +0 -1
  15. package/lib/esm/domain/JsonSerializer.js +0 -1
  16. package/lib/esm/domain/JsonSerializerOptions.js +0 -1
  17. package/lib/esm/domain/Writer.js +0 -1
  18. package/lib/esm/hooks/alterAfterDeserialize.js +0 -1
  19. package/lib/esm/hooks/alterBeforeDeserialize.js +0 -1
  20. package/lib/esm/hooks/alterOnDeserialize.js +0 -1
  21. package/lib/esm/hooks/alterOnSerialize.js +0 -1
  22. package/lib/esm/index.js +0 -1
  23. package/lib/esm/interfaces/JsonMapperMethods.js +0 -1
  24. package/lib/esm/utils/deserialize.js +0 -1
  25. package/lib/esm/utils/getObjectProperties.js +0 -1
  26. package/lib/esm/utils/serialize.js +0 -1
  27. package/package.json +12 -11
  28. package/lib/browser/components/DateMapper.js +0 -22
  29. package/lib/browser/components/DateMapper.js.map +0 -1
  30. package/lib/browser/components/PrimitiveMapper.js +0 -52
  31. package/lib/browser/components/PrimitiveMapper.js.map +0 -1
  32. package/lib/browser/components/SymbolMapper.js +0 -21
  33. package/lib/browser/components/SymbolMapper.js.map +0 -1
  34. package/lib/browser/decorators/afterDeserialize.js +0 -10
  35. package/lib/browser/decorators/afterDeserialize.js.map +0 -1
  36. package/lib/browser/decorators/beforeDeserialize.js +0 -10
  37. package/lib/browser/decorators/beforeDeserialize.js.map +0 -1
  38. package/lib/browser/decorators/jsonMapper.js +0 -12
  39. package/lib/browser/decorators/jsonMapper.js.map +0 -1
  40. package/lib/browser/decorators/onDeserialize.js +0 -10
  41. package/lib/browser/decorators/onDeserialize.js.map +0 -1
  42. package/lib/browser/decorators/onSerialize.js +0 -10
  43. package/lib/browser/decorators/onSerialize.js.map +0 -1
  44. package/lib/browser/domain/JsonDeserializer.js +0 -179
  45. package/lib/browser/domain/JsonDeserializer.js.map +0 -1
  46. package/lib/browser/domain/JsonDeserializerOptions.js +0 -2
  47. package/lib/browser/domain/JsonDeserializerOptions.js.map +0 -1
  48. package/lib/browser/domain/JsonMapperCompiler.js +0 -110
  49. package/lib/browser/domain/JsonMapperCompiler.js.map +0 -1
  50. package/lib/browser/domain/JsonMapperGlobalOptions.js +0 -2
  51. package/lib/browser/domain/JsonMapperGlobalOptions.js.map +0 -1
  52. package/lib/browser/domain/JsonMapperSettings.js +0 -9
  53. package/lib/browser/domain/JsonMapperSettings.js.map +0 -1
  54. package/lib/browser/domain/JsonMapperTypesContainer.js +0 -12
  55. package/lib/browser/domain/JsonMapperTypesContainer.js.map +0 -1
  56. package/lib/browser/domain/JsonSerializer.js +0 -164
  57. package/lib/browser/domain/JsonSerializer.js.map +0 -1
  58. package/lib/browser/domain/JsonSerializerOptions.js +0 -2
  59. package/lib/browser/domain/JsonSerializerOptions.js.map +0 -1
  60. package/lib/browser/domain/Writer.js +0 -124
  61. package/lib/browser/domain/Writer.js.map +0 -1
  62. package/lib/browser/hooks/alterAfterDeserialize.js +0 -8
  63. package/lib/browser/hooks/alterAfterDeserialize.js.map +0 -1
  64. package/lib/browser/hooks/alterBeforeDeserialize.js +0 -8
  65. package/lib/browser/hooks/alterBeforeDeserialize.js.map +0 -1
  66. package/lib/browser/hooks/alterOnDeserialize.js +0 -7
  67. package/lib/browser/hooks/alterOnDeserialize.js.map +0 -1
  68. package/lib/browser/hooks/alterOnSerialize.js +0 -7
  69. package/lib/browser/hooks/alterOnSerialize.js.map +0 -1
  70. package/lib/browser/index.js +0 -47
  71. package/lib/browser/index.js.map +0 -1
  72. package/lib/browser/utils/deserialize.js +0 -12
  73. package/lib/browser/utils/deserialize.js.map +0 -1
  74. package/lib/browser/utils/getObjectProperties.js +0 -8
  75. package/lib/browser/utils/getObjectProperties.js.map +0 -1
  76. package/lib/browser/utils/serialize.js +0 -12
  77. package/lib/browser/utils/serialize.js.map +0 -1
  78. package/lib/esm/components/DateMapper.js.map +0 -1
  79. package/lib/esm/components/PrimitiveMapper.js.map +0 -1
  80. package/lib/esm/components/SymbolMapper.js.map +0 -1
  81. package/lib/esm/decorators/afterDeserialize.js.map +0 -1
  82. package/lib/esm/decorators/beforeDeserialize.js.map +0 -1
  83. package/lib/esm/decorators/jsonMapper.js.map +0 -1
  84. package/lib/esm/decorators/onDeserialize.js.map +0 -1
  85. package/lib/esm/decorators/onSerialize.js.map +0 -1
  86. package/lib/esm/domain/JsonDeserializer.js.map +0 -1
  87. package/lib/esm/domain/JsonDeserializerOptions.js.map +0 -1
  88. package/lib/esm/domain/JsonMapperCompiler.js.map +0 -1
  89. package/lib/esm/domain/JsonMapperGlobalOptions.js.map +0 -1
  90. package/lib/esm/domain/JsonMapperSettings.js.map +0 -1
  91. package/lib/esm/domain/JsonMapperTypesContainer.js.map +0 -1
  92. package/lib/esm/domain/JsonSerializer.js.map +0 -1
  93. package/lib/esm/domain/JsonSerializerOptions.js.map +0 -1
  94. package/lib/esm/domain/Writer.js.map +0 -1
  95. package/lib/esm/hooks/alterAfterDeserialize.js.map +0 -1
  96. package/lib/esm/hooks/alterBeforeDeserialize.js.map +0 -1
  97. package/lib/esm/hooks/alterOnDeserialize.js.map +0 -1
  98. package/lib/esm/hooks/alterOnSerialize.js.map +0 -1
  99. package/lib/esm/index.js.map +0 -1
  100. package/lib/esm/interfaces/JsonMapperMethods.js.map +0 -1
  101. package/lib/esm/utils/deserialize.js.map +0 -1
  102. package/lib/esm/utils/getObjectProperties.js.map +0 -1
  103. package/lib/esm/utils/serialize.js.map +0 -1
  104. package/src/components/DateMapper.spec.ts +0 -43
  105. package/src/components/DateMapper.ts +0 -29
  106. package/src/components/PrimitiveMapper.spec.ts +0 -179
  107. package/src/components/PrimitiveMapper.ts +0 -64
  108. package/src/components/SymbolMapper.spec.ts +0 -23
  109. package/src/components/SymbolMapper.ts +0 -19
  110. package/src/decorators/afterDeserialize.ts +0 -39
  111. package/src/decorators/beforeDeserialize.ts +0 -39
  112. package/src/decorators/jsonMapper.ts +0 -16
  113. package/src/decorators/onDeserialize.ts +0 -29
  114. package/src/decorators/onSerialize.ts +0 -29
  115. package/src/domain/JsonDeserializer.spec.ts +0 -1437
  116. package/src/domain/JsonDeserializer.ts +0 -402
  117. package/src/domain/JsonDeserializerOptions.ts +0 -31
  118. package/src/domain/JsonMapperCompiler.ts +0 -247
  119. package/src/domain/JsonMapperGlobalOptions.ts +0 -14
  120. package/src/domain/JsonMapperSettings.ts +0 -7
  121. package/src/domain/JsonMapperTypesContainer.ts +0 -20
  122. package/src/domain/JsonSerializer.spec.ts +0 -1506
  123. package/src/domain/JsonSerializer.ts +0 -371
  124. package/src/domain/JsonSerializerOptions.ts +0 -17
  125. package/src/domain/Writer.spec.ts +0 -11
  126. package/src/domain/Writer.ts +0 -181
  127. package/src/domain/__snapshots__/Writer.spec.ts.snap +0 -10
  128. package/src/hooks/alterAfterDeserialize.ts +0 -5
  129. package/src/hooks/alterBeforeDeserialize.ts +0 -5
  130. package/src/hooks/alterOnDeserialize.ts +0 -5
  131. package/src/hooks/alterOnSerialize.ts +0 -5
  132. package/src/index.ts +0 -28
  133. package/src/interfaces/JsonMapperMethods.ts +0 -32
  134. package/src/utils/deserialize.spec.ts +0 -33
  135. package/src/utils/deserialize.ts +0 -12
  136. package/src/utils/getObjectProperties.ts +0 -5
  137. package/src/utils/serialize.spec.ts +0 -37
  138. package/src/utils/serialize.ts +0 -12
  139. package/vite.config.mts +0 -45
  140. package/vitest.config.mts +0 -21
@@ -1,1506 +0,0 @@
1
- import "../components/DateMapper.js";
2
- import "../components/PrimitiveMapper.js";
3
- import "../components/SymbolMapper.js";
4
-
5
- import {parse} from "node:querystring";
6
-
7
- import {cleanObject, isBoolean, isNumber, isObjectID, useDecorators} from "@tsed/core";
8
- import {
9
- AdditionalProperties,
10
- Allow,
11
- CollectionOf,
12
- Default,
13
- DiscriminatorKey,
14
- DiscriminatorValue,
15
- Email,
16
- Groups,
17
- Ignore,
18
- JsonHookContext,
19
- MinLength,
20
- Name,
21
- Nullable,
22
- Property,
23
- Required,
24
- Uri
25
- } from "@tsed/schema";
26
- import {snakeCase} from "change-case";
27
-
28
- import {Post} from "../../test/helpers/Post.js";
29
- import {User} from "../../test/helpers/User.js";
30
- import {OnDeserialize} from "../decorators/onDeserialize.js";
31
- import {OnSerialize} from "../decorators/onSerialize.js";
32
- import {deserialize} from "../utils/deserialize.js";
33
- import {JsonMapperSettings} from "./JsonMapperSettings.js";
34
- import {getJsonMapperTypes} from "./JsonMapperTypesContainer.js";
35
- import {JsonSerializer} from "./JsonSerializer.js";
36
-
37
- const serializer = new JsonSerializer();
38
-
39
- const serialize = (...args: any[]) => (serializer.map as any)(...args);
40
-
41
- function createMap(value: any) {
42
- return new Map([["test", value]]);
43
- }
44
-
45
- class ObjectId {
46
- _bsontype = true;
47
-
48
- constructor(public id: string) {}
49
-
50
- toString() {
51
- return this.id;
52
- }
53
- }
54
-
55
- describe("JsonSerializer", () => {
56
- describe("Primitives", () => {
57
- it("should serialize values", () => {
58
- expect(serialize(undefined)).toBeUndefined();
59
- expect(serialize(null)).toEqual(null);
60
- expect(serialize("null")).toEqual("null");
61
- expect(serialize(Symbol.for("TEST"))).toEqual("TEST");
62
- expect(serialize(false)).toEqual(false);
63
- expect(serialize(true)).toEqual(true);
64
- expect(serialize("")).toEqual("");
65
- expect(serialize("1")).toEqual("1");
66
- expect(serialize(0)).toEqual(0);
67
- expect(serialize(1)).toEqual(1);
68
- expect(serialize(1)).toEqual(1);
69
- expect(serialize(BigInt(1n))).toEqual(BigInt(1));
70
- });
71
- });
72
- describe("Object", () => {
73
- it("should serialize values", () => {
74
- expect(serialize({test: "test"}, {type: Object})).toEqual({test: "test"});
75
- expect(serialize({test: "test"}, {type: false})).toEqual({test: "test"});
76
- expect(serialize({test: "test"}, {type: null})).toEqual({test: "test"});
77
- expect(serialize({test: "test"}, {type: undefined})).toEqual({test: "test"});
78
- });
79
- it("should serialize parsed querystring", () => {
80
- expect(serialize({qs: parse("q[offset]=0&q[limit]=10&q[where][a]=0&q[where][b]=1")})).toEqual({
81
- qs: {
82
- "q[limit]": "10",
83
- "q[offset]": "0",
84
- "q[where][a]": "0",
85
- "q[where][b]": "1"
86
- }
87
- });
88
- });
89
- });
90
- describe("Array<primitive>", () => {
91
- it("should serialize values", () => {
92
- expect(serialize([null])).toEqual([null]);
93
- expect(serialize([false])).toEqual([false]);
94
- expect(serialize([true])).toEqual([true]);
95
- expect(serialize([""])).toEqual([""]);
96
- expect(serialize(["1"])).toEqual(["1"]);
97
- expect(serialize([1])).toEqual([1]);
98
-
99
- class ArrayLike extends Array {}
100
-
101
- const arrayLike = new ArrayLike();
102
- arrayLike.push(1);
103
-
104
- expect(serialize(arrayLike)).toEqual([1]);
105
-
106
- class SetLike extends Set {}
107
-
108
- const setLike = new SetLike();
109
- setLike.add(1);
110
-
111
- expect(serialize(setLike)).toEqual([1]);
112
-
113
- class MapLike extends Map {}
114
-
115
- const mapLike = new MapLike();
116
- mapLike.set("i", 1);
117
-
118
- expect(serialize(mapLike)).toEqual({i: 1});
119
- });
120
- });
121
- describe("Map<primitive>", () => {
122
- it("should serialize values", () => {
123
- expect(serialize(createMap(null))).toEqual({test: null});
124
- expect(serialize(createMap(false))).toEqual({test: false});
125
- expect(serialize(createMap(true))).toEqual({test: true});
126
- expect(serialize(createMap(""))).toEqual({test: ""});
127
- expect(serialize(createMap("1"))).toEqual({test: "1"});
128
- expect(serialize(createMap(1))).toEqual({test: 1});
129
- });
130
- });
131
- describe("toJson()", () => {
132
- it("should serialize obj from toJSON", () => {
133
- const result = serialize({
134
- toJSON() {
135
- return "hello";
136
- }
137
- });
138
-
139
- expect(result).toEqual("hello");
140
- });
141
-
142
- it("should serialize obj from toJSON (with type)", () => {
143
- class Model {}
144
-
145
- const result = serialize(
146
- {
147
- toJSON() {
148
- return "hello";
149
- }
150
- },
151
- {type: Model}
152
- );
153
-
154
- expect(result).toEqual("hello");
155
- });
156
- });
157
- describe("Plain Object", () => {
158
- it("should serialize plain object (1)", () => {
159
- expect(serialize({prop: "1"})).toEqual({prop: "1"});
160
-
161
- const result = serialize({
162
- prop: "1",
163
- roles: [{label: "Admin"}]
164
- });
165
- expect(result).toEqual({
166
- prop: "1",
167
- roles: [
168
- {
169
- label: "Admin"
170
- }
171
- ]
172
- });
173
- });
174
- it("should serialize plain object (2)", () => {
175
- expect(serialize({prop: "1"})).toEqual({prop: "1"});
176
- const roles = new Map();
177
- roles.set("ro", "le");
178
-
179
- const result = serialize({
180
- prop: "1",
181
- roles
182
- });
183
- expect(result).toEqual({
184
- prop: "1",
185
- roles: {
186
- ro: "le"
187
- }
188
- });
189
- });
190
- });
191
- describe("Class", () => {
192
- describe("ignore hook is configured on props", () => {
193
- it("should serialize model (api = true)", () => {
194
- class Role {
195
- @Property()
196
- label: string;
197
-
198
- constructor({label}: any = {}) {
199
- this.label = label;
200
- }
201
- }
202
-
203
- class Model {
204
- @Property()
205
- id: string;
206
-
207
- @Ignore((ignored, ctx: JsonHookContext) => ctx.api)
208
- password: string;
209
-
210
- @OnSerialize((value) => String(value) + "test")
211
- @Name("mapped_prop")
212
- mappedProp: string;
213
-
214
- @CollectionOf(Role)
215
- roles: Role[] = [];
216
-
217
- @CollectionOf(Role)
218
- mapRoles: Map<string, Role> = new Map();
219
-
220
- @CollectionOf(String)
221
- setRoleNames: Set<string> = new Set();
222
- }
223
-
224
- const model = new Model();
225
- model.id = "id";
226
- model.password = "string";
227
- model.mappedProp = "mappedProp";
228
- model.roles = [new Role({label: "ADMIN"})];
229
-
230
- model.mapRoles = new Map([["ADMIN", new Role({label: "ADMIN"})]]);
231
-
232
- model.setRoleNames = new Set();
233
- model.setRoleNames.add("ADMIN");
234
-
235
- expect(
236
- serialize(model, {
237
- useAlias: false,
238
- api: true
239
- })
240
- ).toEqual({
241
- id: "id",
242
- mapRoles: {
243
- ADMIN: {
244
- label: "ADMIN"
245
- }
246
- },
247
- mappedProp: "mappedProptest",
248
- roles: [
249
- {
250
- label: "ADMIN"
251
- }
252
- ],
253
- setRoleNames: ["ADMIN"]
254
- });
255
- });
256
- it("should serialize model (api = false)", () => {
257
- class Role {
258
- @Property()
259
- label: string;
260
-
261
- constructor({label}: any = {}) {
262
- this.label = label;
263
- }
264
- }
265
-
266
- class Model {
267
- @Property()
268
- id: string;
269
-
270
- @Ignore((ignored, ctx: JsonHookContext) => ctx.api)
271
- password: string;
272
-
273
- @OnSerialize((value) => String(value) + "test")
274
- @Name("mapped_prop")
275
- mappedProp: string;
276
-
277
- @CollectionOf(Role)
278
- roles: Role[] = [];
279
-
280
- @CollectionOf(Role)
281
- mapRoles: Map<string, Role> = new Map();
282
-
283
- @CollectionOf(String)
284
- setRoleNames: Set<string> = new Set();
285
- }
286
-
287
- const model = new Model();
288
- model.id = "id";
289
- model.password = "string";
290
- model.mappedProp = "mappedProp";
291
- model.roles = [new Role({label: "ADMIN"})];
292
-
293
- model.mapRoles = new Map([["ADMIN", new Role({label: "ADMIN"})]]);
294
-
295
- model.setRoleNames = new Set();
296
- model.setRoleNames.add("ADMIN");
297
-
298
- expect(
299
- serialize(model, {
300
- useAlias: false,
301
- api: false
302
- })
303
- ).toEqual({
304
- id: "id",
305
- mapRoles: {
306
- ADMIN: {
307
- label: "ADMIN"
308
- }
309
- },
310
- password: "string",
311
- mappedProp: "mappedProptest",
312
- roles: [
313
- {
314
- label: "ADMIN"
315
- }
316
- ],
317
- setRoleNames: ["ADMIN"]
318
- });
319
- });
320
- });
321
- it("should serialize model and take the right type", () => {
322
- class Role {
323
- @Property()
324
- label: string;
325
-
326
- constructor({label}: any = {}) {
327
- this.label = label;
328
- }
329
- }
330
-
331
- class Model {
332
- @Property()
333
- id: string;
334
-
335
- @Ignore((ignored, ctx: JsonHookContext) => ctx.api)
336
- password: string;
337
-
338
- @OnSerialize((value) => String(value) + "test")
339
- @Name("mapped_prop")
340
- mappedProp: string;
341
-
342
- @CollectionOf(Role)
343
- roles: Map<string, Role> = new Map();
344
- }
345
-
346
- class ServerResponse {
347
- @Property()
348
- data: Model;
349
- }
350
-
351
- const model = new Model();
352
- model.id = "id";
353
- model.password = "hellopassword";
354
- model.mappedProp = "hello";
355
- model.roles.set("olo", new Role({label: "label"}));
356
-
357
- expect(serialize(model, {type: ServerResponse})).toEqual({
358
- id: "id",
359
- password: "hellopassword",
360
- mapped_prop: "hellotest",
361
- roles: {
362
- olo: {
363
- label: "label"
364
- }
365
- }
366
- });
367
- });
368
- it("should serialize model with alias property", () => {
369
- class Role {
370
- @Property()
371
- label: string;
372
-
373
- constructor({label}: any = {}) {
374
- this.label = label;
375
- }
376
- }
377
-
378
- class Model {
379
- @Property()
380
- id: string;
381
-
382
- @Ignore((ignored, ctx: JsonHookContext) => ctx.api)
383
- password: string;
384
-
385
- @OnSerialize((value) => String(value) + "test")
386
- @Name("mapped_prop")
387
- mappedProp: string;
388
-
389
- @CollectionOf(Role)
390
- roles: Role[] = [];
391
-
392
- @CollectionOf(Role)
393
- mapRoles: Map<string, Role> = new Map();
394
-
395
- @CollectionOf(String)
396
- setRoleNames: Set<string> = new Set();
397
- }
398
-
399
- const model = new Model();
400
- model.id = "id";
401
- model.password = "string";
402
- model.mappedProp = "mappedProp";
403
- model.roles = [new Role({label: "ADMIN"})];
404
-
405
- model.mapRoles = new Map([["ADMIN", new Role({label: "ADMIN"})]]);
406
-
407
- model.setRoleNames = new Set();
408
- model.setRoleNames.add("ADMIN");
409
-
410
- expect(
411
- serialize(model, {
412
- useAlias: true,
413
- api: false
414
- })
415
- ).toEqual({
416
- id: "id",
417
- mapRoles: {
418
- ADMIN: {
419
- label: "ADMIN"
420
- }
421
- },
422
- mapped_prop: "mappedProptest",
423
- password: "string",
424
- roles: [
425
- {
426
- label: "ADMIN"
427
- }
428
- ],
429
- setRoleNames: ["ADMIN"]
430
- });
431
- });
432
- it("should serialize model with nested object", () => {
433
- class Nested {
434
- @Property()
435
- label: string;
436
-
437
- @Name("additional_description")
438
- additionalDescription: string;
439
-
440
- constructor({label, additionalDescription}: any = {}) {
441
- this.label = label;
442
- this.additionalDescription = additionalDescription;
443
- }
444
- }
445
-
446
- class Model {
447
- @Property()
448
- id: string;
449
-
450
- @Property()
451
- nested: any;
452
-
453
- @Property()
454
- nestedTyped: Nested;
455
- }
456
-
457
- const model = new Model();
458
- model.id = "id";
459
- model.nested = {
460
- other: "other",
461
- test: new Nested({
462
- additionalDescription: "additionalDescription",
463
- label: "label"
464
- })
465
- };
466
-
467
- model.nestedTyped = new Nested({
468
- additionalDescription: "additionalDescription",
469
- label: "label"
470
- });
471
-
472
- expect(
473
- serialize(model, {
474
- useAlias: true,
475
- api: false
476
- })
477
- ).toEqual({
478
- id: "id",
479
- nested: {
480
- other: "other",
481
- test: {
482
- additional_description: "additionalDescription",
483
- label: "label"
484
- }
485
- },
486
- nestedTyped: {
487
- additional_description: "additionalDescription",
488
- label: "label"
489
- }
490
- });
491
- });
492
- it("should serialize model with additional properties", () => {
493
- @AdditionalProperties(true)
494
- class Model {
495
- @Property()
496
- id: string;
497
-
498
- @OnSerialize((value) => String(value) + "test")
499
- @Name("mapped_prop")
500
- mappedProp: string;
501
- }
502
-
503
- expect(
504
- serialize(
505
- {
506
- id: "id",
507
- mappedProp: "mappedProp",
508
- additionalProperty: true
509
- },
510
- {
511
- type: Model,
512
- useAlias: false
513
- }
514
- )
515
- ).toEqual({
516
- additionalProperty: true,
517
- id: "id",
518
- mappedProp: "mappedProptest"
519
- });
520
- });
521
- it("should serialize model (recursive class)", () => {
522
- class User {
523
- @Property()
524
- name: string;
525
-
526
- @CollectionOf(() => Post)
527
- posts: any[];
528
-
529
- @Property(() => Post)
530
- @Name("main_post")
531
- mainPost: any;
532
- }
533
-
534
- class Post {
535
- @Property()
536
- id: string;
537
-
538
- @Property()
539
- owner: User;
540
-
541
- @Name("title")
542
- initializedTitle: string;
543
- }
544
-
545
- const post = new Post();
546
- post.id = "id";
547
-
548
- post.owner = new User();
549
- post.owner.name = "name";
550
- post.owner.posts = [new Post()];
551
- post.owner.posts[0].id = "id";
552
- post.owner.posts[0].initializedTitle = "initializedTitle";
553
-
554
- post.owner.mainPost = new Post();
555
- post.owner.mainPost.id = "idMain";
556
- post.owner.mainPost.initializedTitle = "initializedTitle";
557
-
558
- const result = serialize(post, {useAlias: true});
559
-
560
- expect(result).toEqual({
561
- id: "id",
562
- owner: {
563
- name: "name",
564
- main_post: {
565
- id: "idMain",
566
- title: "initializedTitle"
567
- },
568
- posts: [
569
- {
570
- id: "id",
571
- title: "initializedTitle"
572
- }
573
- ]
574
- }
575
- });
576
- });
577
- it("should serialize model without props", () => {
578
- class Test {
579
- raw: any;
580
- affected?: number | null;
581
- }
582
-
583
- const t = new Test();
584
-
585
- t.raw = 1;
586
- t.affected = 1;
587
-
588
- const result = serialize(t, {type: Object});
589
-
590
- expect(result).toEqual({
591
- affected: 1,
592
- raw: 1
593
- });
594
- });
595
- it("should discover property dynamically when any schema decorators are used", () => {
596
- function log(): PropertyDecorator {
597
- return () => {};
598
- }
599
-
600
- class User {
601
- @log()
602
- id: string;
603
-
604
- test: string;
605
-
606
- [key: string]: any;
607
-
608
- constructor({id, test}: any = {}) {
609
- this.id = id;
610
- test && (this.test = test);
611
- }
612
- }
613
-
614
- const user1 = new User({id: "id"});
615
- const user2 = new User({id: "id", test: "test"});
616
- const user3 = new User({id: "id", test: "test"});
617
-
618
- user3.extra = "extra";
619
-
620
- expect(serialize(user1, {type: User})).toEqual({id: "id"});
621
- expect(serialize(user2, {type: User})).toEqual({id: "id", test: "test"});
622
- expect(serialize(user3, {type: User})).toEqual({
623
- extra: "extra",
624
- id: "id",
625
- test: "test"
626
- });
627
- });
628
- it("should serialize model with null values", () => {
629
- class NestedModel {
630
- @Property()
631
- id: string;
632
- }
633
-
634
- class NullModel {
635
- @Property()
636
- prop1: string;
637
-
638
- @Property()
639
- prop2: number;
640
-
641
- @Property()
642
- prop3: Date;
643
-
644
- @Nullable(NestedModel)
645
- prop4: NestedModel;
646
- }
647
-
648
- expect(
649
- serialize(
650
- {
651
- prop1: null,
652
- prop2: null,
653
- prop3: null,
654
- prop4: null
655
- },
656
- {type: NullModel}
657
- )
658
- ).toEqual({
659
- prop1: null,
660
- prop2: null,
661
- prop3: null,
662
- prop4: null
663
- });
664
- });
665
- it("should transform keep array, map, set without nullable value", () => {
666
- class Model {
667
- @CollectionOf(String)
668
- public bars?: string[];
669
-
670
- @CollectionOf(String)
671
- public barsSet?: Set<string>;
672
-
673
- @CollectionOf(String)
674
- public barsMap?: Map<string, string>;
675
- }
676
-
677
- const payload = {
678
- bars: null,
679
- barsSet: null,
680
- barsMap: null
681
- };
682
-
683
- const result = serialize(payload, {type: Model});
684
-
685
- expect(result).toEqual({
686
- bars: null,
687
- barsSet: null,
688
- barsMap: null
689
- });
690
- });
691
- it("should serialize array model with alias property", () => {
692
- class SpaBooking {
693
- @Required()
694
- @Name("booking_number")
695
- bookingNumber: string;
696
-
697
- @Required()
698
- status: string;
699
-
700
- @Required()
701
- @Name("order_id")
702
- orderId: number;
703
-
704
- @Required()
705
- @Name("appointment_id")
706
- appointmentId: number;
707
-
708
- @Name("customer_id")
709
- @Groups("!create", "!read")
710
- customerId: number;
711
- }
712
-
713
- const appointments = [
714
- {
715
- bookingNumber: "100566224434",
716
- status: "Booked",
717
- orderId: 711376505,
718
- appointmentId: 566224434,
719
- customerId: null
720
- }
721
- ];
722
-
723
- const serializedResult = serialize(appointments, {
724
- type: SpaBooking
725
- });
726
-
727
- expect(serializedResult).toEqual([
728
- {
729
- booking_number: "100566224434",
730
- status: "Booked",
731
- order_id: 711376505,
732
- appointment_id: 566224434,
733
- customer_id: null
734
- }
735
- ]);
736
- });
737
- it("should serialize model without decorator", () => {
738
- class Client {
739
- clientId: string;
740
- clientSecret: string;
741
- }
742
-
743
- const client = new Client();
744
- client.clientId = "id";
745
- client.clientSecret = "secret";
746
-
747
- const result = serialize(client, {useAlias: false, groups: ["render"]});
748
-
749
- expect(result === client).toBeFalsy();
750
- expect(result).toEqual({
751
- clientId: "id",
752
- clientSecret: "secret"
753
- });
754
- });
755
- });
756
- describe("class with toJSON/toClass", () => {
757
- it("should serialize model", () => {
758
- class Role {
759
- @Property()
760
- label: string;
761
-
762
- constructor({label}: any = {}) {
763
- this.label = label;
764
- }
765
- }
766
-
767
- class Model {
768
- @Property()
769
- id: string;
770
-
771
- @Ignore((ignored, ctx: JsonHookContext) => ctx.api)
772
- password: string;
773
-
774
- @OnSerialize((value) => String(value) + "test")
775
- @Name("mapped_prop")
776
- mappedProp: string;
777
-
778
- @CollectionOf(Role)
779
- roles: Map<string, Role> = new Map();
780
- }
781
-
782
- const model = new Model();
783
- // @ts-ignore
784
- model.$isMongooseModelPrototype = true;
785
- // @ts-ignore
786
- model["toJSON"] = (options: any) => {
787
- const result = deserialize(
788
- {
789
- id: "id",
790
- password: "hellopassword",
791
- mappedProp: "hello"
792
- },
793
- {useAlias: false, type: Model}
794
- );
795
-
796
- return serialize(result, options);
797
- };
798
-
799
- expect(serialize(model, {type: Model})).toEqual({
800
- id: "id",
801
- mapped_prop: "hellotest",
802
- password: "hellopassword",
803
- roles: {}
804
- });
805
-
806
- expect(serialize(model, {api: true, useAlias: false})).toEqual({
807
- id: "id",
808
- mappedProp: "hellotest",
809
- roles: {}
810
- });
811
-
812
- expect(serialize([model], {type: Model})).toEqual([
813
- {
814
- id: "id",
815
- mapped_prop: "hellotest",
816
- password: "hellopassword",
817
- roles: {}
818
- }
819
- ]);
820
- });
821
- it("should serialize model (protected keyword)", () => {
822
- class Role {
823
- @Property()
824
- label: string;
825
-
826
- constructor({label}: any = {}) {
827
- this.label = label;
828
- }
829
- }
830
-
831
- class Model {
832
- @Property()
833
- id: string;
834
-
835
- @Ignore((ignored, ctx: JsonHookContext) => ctx.api)
836
- password: string;
837
-
838
- @OnSerialize((value) => String(value) + "test")
839
- @Name("mapped_prop")
840
- mappedProp: string;
841
-
842
- @Property()
843
- enum: string;
844
-
845
- @CollectionOf(Role)
846
- roles: Map<string, Role> = new Map();
847
- }
848
-
849
- const model = new Model();
850
- // @ts-ignore
851
- model.$isMongooseModelPrototype = true;
852
- // @ts-ignore
853
- model["toJSON"] = (options: any) => {
854
- const result = deserialize(
855
- {
856
- id: "id",
857
- password: "hellopassword",
858
- mappedProp: "hello",
859
- enum: "test"
860
- },
861
- {useAlias: false, type: Model}
862
- );
863
-
864
- return serialize(result, options);
865
- };
866
-
867
- expect(serialize(model, {type: Model})).toEqual({
868
- id: "id",
869
- enum: "test",
870
- mapped_prop: "hellotest",
871
- password: "hellopassword",
872
- roles: {}
873
- });
874
-
875
- expect(serialize(model, {api: true, useAlias: false})).toEqual({
876
- id: "id",
877
- enum: "test",
878
- mappedProp: "hellotest",
879
- roles: {}
880
- });
881
-
882
- expect(serialize([model], {type: Model})).toEqual([
883
- {
884
- id: "id",
885
- enum: "test",
886
- mapped_prop: "hellotest",
887
- password: "hellopassword",
888
- roles: {}
889
- }
890
- ]);
891
- });
892
- it("should serialize model Array", () => {
893
- class Role {
894
- @Property()
895
- label: string;
896
-
897
- constructor({label}: any = {}) {
898
- this.label = label;
899
- }
900
- }
901
-
902
- class Model {
903
- @Property()
904
- id: string;
905
-
906
- @Ignore((ignored, ctx: JsonHookContext) => ctx.api)
907
- password: string;
908
-
909
- @OnSerialize((value) => String(value) + "test")
910
- @Name("mapped_prop")
911
- mappedProp: string;
912
-
913
- @CollectionOf(Role)
914
- roles: Map<string, Role> = new Map();
915
- }
916
-
917
- const model = new Model();
918
- model.id = "id";
919
- model.password = "hellopassword";
920
- model.mappedProp = "hello";
921
- model.roles.set("olo", new Role({label: "label"}));
922
-
923
- expect(serialize([model], {type: Model})).toEqual([
924
- {
925
- id: "id",
926
- password: "hellopassword",
927
- mapped_prop: "hellotest",
928
- roles: {
929
- olo: {
930
- label: "label"
931
- }
932
- }
933
- }
934
- ]);
935
- });
936
- it("should serialize model with nested model and not populated data (mongoose)", () => {
937
- class Workspace {
938
- @Property()
939
- _id: string;
940
-
941
- @Property()
942
- name: string;
943
- }
944
-
945
- class MyWorkspace {
946
- @Property()
947
- workspaceId: Workspace;
948
-
949
- @Property()
950
- title: string;
951
- }
952
-
953
- class UserWorkspace {
954
- @Property()
955
- _id: string;
956
-
957
- @CollectionOf(MyWorkspace)
958
- workspaces: MyWorkspace[];
959
- }
960
-
961
- const userWorkspace = new UserWorkspace();
962
- userWorkspace._id = new ObjectId("64e061ba7356daf00a66c130") as unknown as string;
963
- userWorkspace.workspaces = [new MyWorkspace()];
964
- userWorkspace.workspaces[0].title = "MyTest";
965
- userWorkspace.workspaces[0].workspaceId = new ObjectId("64e061ba7356daf00a66c130") as unknown as Workspace;
966
-
967
- expect(serialize(userWorkspace, {type: UserWorkspace})).toEqual({
968
- _id: "64e061ba7356daf00a66c130",
969
- workspaces: [
970
- {
971
- title: "MyTest",
972
- workspaceId: "64e061ba7356daf00a66c130"
973
- }
974
- ]
975
- });
976
- });
977
- it("should serialize model with nested model and not populated data (Ref mongoose)", () => {
978
- class TestUser {
979
- @Required()
980
- email: string;
981
-
982
- @Required()
983
- @MinLength(6)
984
- @Groups("creation")
985
- password: string;
986
- }
987
-
988
- class TestProfile {
989
- @OnSerialize((value, ctx) => {
990
- if (isObjectID(value)) {
991
- return value.toString();
992
- }
993
-
994
- return serialize(value, {...ctx, type: TestUser});
995
- })
996
- user: any;
997
- }
998
-
999
- const profile = new TestProfile();
1000
- profile.user = new ObjectId("64e061ba7356daf00a66c130");
1001
-
1002
- expect(serialize([profile])).toEqual([
1003
- {
1004
- user: "64e061ba7356daf00a66c130"
1005
- }
1006
- ]);
1007
- });
1008
- it("should serialize model (inherited class)", () => {
1009
- class Role {
1010
- @Property()
1011
- label: string;
1012
-
1013
- constructor({label}: any = {}) {
1014
- this.label = label;
1015
- }
1016
- }
1017
-
1018
- class Base {
1019
- @CollectionOf(Role)
1020
- roles: Map<string, Role> = new Map();
1021
- }
1022
-
1023
- class Model extends Base {
1024
- @Property()
1025
- id: string;
1026
-
1027
- @Ignore((ignored, ctx: JsonHookContext) => ctx.api)
1028
- password: string;
1029
-
1030
- @OnSerialize((value) => String(value) + "test")
1031
- @Name("mapped_prop")
1032
- mappedProp: string;
1033
- }
1034
-
1035
- const model = new Model();
1036
- model.id = "id";
1037
- model.password = "hellopassword";
1038
- model.mappedProp = "hello";
1039
- model.roles.set("olo", new Role({label: "label"}));
1040
-
1041
- expect(serialize(model)).toEqual({
1042
- id: "id",
1043
- password: "hellopassword",
1044
- mapped_prop: "hellotest",
1045
- roles: {
1046
- olo: {
1047
- label: "label"
1048
- }
1049
- }
1050
- });
1051
-
1052
- expect(serialize(model, {api: true, useAlias: false})).toEqual({
1053
- id: "id",
1054
- mappedProp: "hellotest",
1055
- roles: {
1056
- olo: {
1057
- label: "label"
1058
- }
1059
- }
1060
- });
1061
- });
1062
- it("should serialize model (recursive class)", () => {
1063
- const post = new Post();
1064
- post.id = "id";
1065
- post.owner = new User();
1066
- post.owner.name = "name";
1067
- post.owner.posts = [new Post()];
1068
- post.owner.posts[0].id = "id";
1069
-
1070
- const result = serialize(post);
1071
-
1072
- expect(result).toEqual({
1073
- id: "id",
1074
- owner: {
1075
- name: "name",
1076
- posts: [
1077
- {
1078
- id: "id"
1079
- }
1080
- ]
1081
- }
1082
- });
1083
- });
1084
- it("should serialize model with object props", () => {
1085
- class Model {
1086
- @Property()
1087
- test: any;
1088
-
1089
- @Property()
1090
- id: string;
1091
- }
1092
-
1093
- const test = new Model();
1094
- test.id = "id";
1095
- test.test = {
1096
- value: "test",
1097
- nullProp: null
1098
- };
1099
-
1100
- const result = serialize(test, {type: Model});
1101
-
1102
- expect(result).toEqual({
1103
- id: "id",
1104
- test: {
1105
- value: "test",
1106
- nullProp: null
1107
- }
1108
- });
1109
- });
1110
- it("should serialize model with additional object props", () => {
1111
- @AdditionalProperties(true)
1112
- class Model {
1113
- @Property()
1114
- id: string;
1115
-
1116
- @Ignore(true)
1117
- ignored: boolean;
1118
-
1119
- @Name("renamed")
1120
- name: string;
1121
-
1122
- [type: string]: any;
1123
- }
1124
-
1125
- const test = new Model();
1126
- test.id = "id";
1127
- test.ignored = true;
1128
- test.name = "myname";
1129
- test.additional = {foo: "bar"};
1130
-
1131
- const result = serialize(test, {type: Model});
1132
-
1133
- expect(result).toEqual({
1134
- id: "id",
1135
- renamed: "myname",
1136
- additional: {
1137
- foo: "bar"
1138
- }
1139
- });
1140
- });
1141
- it("should not serialize model with additional object props", () => {
1142
- class Model {
1143
- @Property()
1144
- id: string;
1145
-
1146
- @Ignore(true)
1147
- ignored: boolean;
1148
-
1149
- @Name("renamed")
1150
- name: string;
1151
-
1152
- [type: string]: any;
1153
- }
1154
-
1155
- const test = new Model();
1156
- test.id = "id";
1157
- test.ignored = true;
1158
- test.name = "myname";
1159
- test.additional = {foo: "bar"};
1160
-
1161
- const result = serialize(test, {type: Model});
1162
-
1163
- expect(result).toEqual({
1164
- id: "id",
1165
- renamed: "myname"
1166
- });
1167
- });
1168
- it("should serialize model to object (with default value - no assigned)", () => {
1169
- class SpaCareCategory {
1170
- @Required()
1171
- @Groups("!details")
1172
- id: string;
1173
-
1174
- @Required()
1175
- label: string;
1176
-
1177
- @Required()
1178
- @OnDeserialize((name: string) => snakeCase(name).toUpperCase())
1179
- code: string;
1180
-
1181
- @Required()
1182
- @Default(0)
1183
- @OnSerialize((o) => {
1184
- return o || 0;
1185
- })
1186
- weight: number = 0;
1187
-
1188
- constructor({id, label, code, weight}: Partial<SpaCareCategory> = {}) {
1189
- Object.assign(
1190
- this,
1191
- cleanObject({
1192
- id,
1193
- label,
1194
- code,
1195
- weight
1196
- })
1197
- );
1198
- }
1199
- }
1200
-
1201
- expect(
1202
- serialize(
1203
- {
1204
- label: "categoryLabel",
1205
- code: "CATEGORY_CODE"
1206
- },
1207
- {type: SpaCareCategory}
1208
- )
1209
- ).toEqual({
1210
- code: "CATEGORY_CODE",
1211
- label: "categoryLabel",
1212
- weight: 0
1213
- });
1214
- });
1215
- it("should serialize model to object (with default value - no assigned - custom decorator)", () => {
1216
- function AllowEmpty() {
1217
- return useDecorators(
1218
- Default(""),
1219
- Allow(""),
1220
- OnDeserialize((o: any) => (o === null || o === undefined ? "" : o)),
1221
- OnSerialize((o: any) => (o === null || o === undefined ? "" : o))
1222
- );
1223
- }
1224
-
1225
- class SpaInformation {
1226
- @Required()
1227
- id: number;
1228
-
1229
- @Required()
1230
- @AllowEmpty()
1231
- label: string = "";
1232
-
1233
- @Required()
1234
- @AllowEmpty()
1235
- description: string = "";
1236
-
1237
- @AllowEmpty()
1238
- currency: string = "EUR";
1239
-
1240
- @Email()
1241
- @AllowEmpty()
1242
- email: string;
1243
-
1244
- @AllowEmpty()
1245
- phone: string;
1246
-
1247
- @Required()
1248
- @Name("are_children_accepted")
1249
- areChildrenAccepted: boolean = false;
1250
-
1251
- @AllowEmpty()
1252
- website: string = "";
1253
-
1254
- @Uri()
1255
- @AllowEmpty()
1256
- logo: string;
1257
-
1258
- @Uri()
1259
- @AllowEmpty()
1260
- image: string;
1261
-
1262
- @AllowEmpty()
1263
- location: string = "";
1264
-
1265
- @Name("cancellation_hours_limit")
1266
- @Nullable(Number)
1267
- @OnSerialize((o) => (isNumber(o) ? o : null))
1268
- cancellationHoursLimit: number | null = null;
1269
-
1270
- constructor({
1271
- id,
1272
- label,
1273
- description,
1274
- currency,
1275
- email,
1276
- phone,
1277
- areChildrenAccepted,
1278
- website,
1279
- logo,
1280
- image,
1281
- location,
1282
- cancellationHoursLimit = null
1283
- }: Partial<SpaInformation> = {}) {
1284
- Object.assign(
1285
- this,
1286
- cleanObject({
1287
- id,
1288
- label,
1289
- description,
1290
- currency,
1291
- email,
1292
- phone,
1293
- areChildrenAccepted,
1294
- website,
1295
- logo,
1296
- image,
1297
- location,
1298
- cancellationHoursLimit
1299
- })
1300
- );
1301
- }
1302
- }
1303
-
1304
- const result = serialize(
1305
- {
1306
- id: 453,
1307
- address: null,
1308
- label: null,
1309
- currency: null,
1310
- description: null,
1311
- email: null,
1312
- phone: undefined,
1313
- areChildrenAccepted: true,
1314
- website: "website",
1315
- logo: undefined,
1316
- image: null,
1317
- cares: [],
1318
- cancellationHoursLimit: undefined
1319
- },
1320
- {type: SpaInformation}
1321
- );
1322
-
1323
- expect(result).toEqual({
1324
- are_children_accepted: true,
1325
- currency: "",
1326
- description: "",
1327
- email: "",
1328
- id: 453,
1329
- image: "",
1330
- label: "",
1331
- location: "",
1332
- logo: "",
1333
- phone: "",
1334
- website: "website",
1335
- cancellation_hours_limit: null
1336
- });
1337
- });
1338
-
1339
- describe("when jsonMapper.strictGroups = false", () => {
1340
- it("should serialize props", () => {
1341
- class Model {
1342
- @Property()
1343
- id: string;
1344
-
1345
- @Groups("summary")
1346
- ignored: boolean;
1347
-
1348
- @Name("renamed")
1349
- name: string;
1350
- }
1351
-
1352
- const test = new Model();
1353
- test.id = "id";
1354
- test.ignored = true;
1355
- test.name = "myname";
1356
-
1357
- const result = serialize(test, {type: Model});
1358
-
1359
- expect(result).toEqual({
1360
- id: "id",
1361
- ignored: true,
1362
- renamed: "myname"
1363
- });
1364
- });
1365
- });
1366
- describe("when jsonMapper.strictGroups = true", () => {
1367
- beforeEach(() => {
1368
- JsonMapperSettings.strictGroups = true;
1369
- });
1370
- afterEach(() => {
1371
- JsonMapperSettings.strictGroups = false;
1372
- });
1373
- it("should serialize props", () => {
1374
- class Model {
1375
- @Property()
1376
- id: string;
1377
-
1378
- @Groups("summary")
1379
- ignored: boolean;
1380
-
1381
- @Name("renamed")
1382
- name: string;
1383
- }
1384
-
1385
- const test = new Model();
1386
- test.id = "id";
1387
- test.ignored = true;
1388
- test.name = "myname";
1389
-
1390
- const result = serialize(test, {type: Model});
1391
-
1392
- expect(result).toEqual({
1393
- id: "id",
1394
- renamed: "myname"
1395
- });
1396
- });
1397
- });
1398
- });
1399
- describe("custom date mapper", () => {
1400
- it("should use a custom date mapper", () => {
1401
- class Test {
1402
- @Property() myDate: Date;
1403
- }
1404
-
1405
- class CustomDateMapper {
1406
- deserialize(data: string | number): Date;
1407
- deserialize(data: boolean | null | undefined): boolean | null | undefined;
1408
- deserialize(data: any): any {
1409
- // don't convert unexpected data. In normal case, Ajv reject unexpected data.
1410
- // But by default, we have to skip data deserialization and let user to apply
1411
- // the right mapping
1412
- if (isBoolean(data) || data === null || data === undefined) {
1413
- return data;
1414
- }
1415
-
1416
- return new Date(data);
1417
- }
1418
-
1419
- serialize(object: Date): any {
1420
- return new Date(object).toDateString();
1421
- }
1422
- }
1423
-
1424
- const obj = new Test();
1425
- obj.myDate = new Date("2022-10-02");
1426
-
1427
- const types = new Map<any, any>(getJsonMapperTypes());
1428
- types.set(Date, new CustomDateMapper());
1429
-
1430
- const result = serialize(obj, {
1431
- types
1432
- });
1433
- expect(result).toEqual({
1434
- myDate: "Sun Oct 02 2022"
1435
- });
1436
- });
1437
- });
1438
- describe("discriminator", () => {
1439
- it("should serialize items", () => {
1440
- class Event {
1441
- @DiscriminatorKey() // declare this property as discriminator key
1442
- type: string;
1443
-
1444
- @Property()
1445
- value: string;
1446
- }
1447
-
1448
- class SubEvent extends Event {
1449
- @Property()
1450
- metaSub: string;
1451
- }
1452
-
1453
- @DiscriminatorValue("page_view") // or @DiscriminatorValue() value can be inferred by the class name
1454
- class PageView extends SubEvent {
1455
- @Required()
1456
- url: string;
1457
- }
1458
-
1459
- @DiscriminatorValue("action", "click_action")
1460
- class Action extends SubEvent {
1461
- @Required()
1462
- event: string;
1463
- }
1464
-
1465
- @DiscriminatorValue()
1466
- class CustomAction extends Event {
1467
- @Required()
1468
- event: string;
1469
-
1470
- @Property()
1471
- meta: string;
1472
- }
1473
-
1474
- type OneOfEvents = PageView | Action | CustomAction;
1475
-
1476
- const event = new Event();
1477
- event.value = "value";
1478
-
1479
- const pageView = new PageView();
1480
- pageView.value = "value";
1481
- pageView.url = "url";
1482
-
1483
- const action = new Action();
1484
- action.value = "value";
1485
- action.event = "event";
1486
-
1487
- const list = [event, pageView, action];
1488
-
1489
- expect(serialize(list)).toEqual([
1490
- {
1491
- value: "value"
1492
- },
1493
- {
1494
- type: "page_view",
1495
- url: "url",
1496
- value: "value"
1497
- },
1498
- {
1499
- type: "action",
1500
- event: "event",
1501
- value: "value"
1502
- }
1503
- ]);
1504
- });
1505
- });
1506
- });