@cratis/fundamentals 5.5.1 → 5.6.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.
- package/JsonSerializer.ts +49 -2
- package/dist/cjs/JsonSerializer.d.ts +1 -0
- package/dist/cjs/JsonSerializer.d.ts.map +1 -1
- package/dist/cjs/JsonSerializer.js +39 -1
- package/dist/cjs/JsonSerializer.js.map +1 -1
- package/dist/esm/JsonSerializer.d.ts +1 -0
- package/dist/esm/JsonSerializer.d.ts.map +1 -1
- package/dist/esm/JsonSerializer.js +39 -1
- package/dist/esm/JsonSerializer.js.map +1 -1
- package/for_JsonSerializer/Types.ts +67 -0
- package/for_JsonSerializer/when_deserializing_complex_nested_object_with_multiple_wellknown_types.ts +24 -60
- package/for_JsonSerializer/when_serializing_complex_nested_object_with_multiple_wellknown_types.ts +57 -0
- package/package.json +1 -1
package/JsonSerializer.ts
CHANGED
|
@@ -2,13 +2,21 @@
|
|
|
2
2
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
3
|
|
|
4
4
|
import { Constructor } from './Constructor';
|
|
5
|
+
import { DerivedType } from './DerivedType';
|
|
5
6
|
import { Field } from './Field';
|
|
6
7
|
import { Fields } from './Fields';
|
|
7
|
-
import { DerivedType } from './DerivedType';
|
|
8
8
|
import { Guid } from './Guid';
|
|
9
9
|
|
|
10
10
|
type typeSerializer = (value: any) => any;
|
|
11
11
|
|
|
12
|
+
const typeConverters: Map<Constructor, typeSerializer> = new Map<Constructor, typeSerializer>([
|
|
13
|
+
[Number, (value: number) => value],
|
|
14
|
+
[String, (value: string) => value],
|
|
15
|
+
[Boolean, (value: boolean) => value],
|
|
16
|
+
[Date, (value: Date) => value.toISOString()],
|
|
17
|
+
[Guid, (value: Guid) => value?.toString() ?? '']
|
|
18
|
+
]);
|
|
19
|
+
|
|
12
20
|
const typeSerializers: Map<Constructor, typeSerializer> = new Map<Constructor, typeSerializer>([
|
|
13
21
|
[Number, (value: any) => value],
|
|
14
22
|
[String, (value: any) => value],
|
|
@@ -17,6 +25,16 @@ const typeSerializers: Map<Constructor, typeSerializer> = new Map<Constructor, t
|
|
|
17
25
|
[Guid, (value: any) => Guid.parse(value.toString())],
|
|
18
26
|
]);
|
|
19
27
|
|
|
28
|
+
const serializeValueForType = (type: Constructor, value: any) => {
|
|
29
|
+
if (!value) return value;
|
|
30
|
+
|
|
31
|
+
if (typeConverters.has(type)) {
|
|
32
|
+
return typeConverters.get(type)!(value);
|
|
33
|
+
} else {
|
|
34
|
+
return convertTypesOnInstance(value);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
20
38
|
const deserializeValueFromType = (type: Constructor, value: any) => {
|
|
21
39
|
if (typeSerializers.has(type)) {
|
|
22
40
|
return typeSerializers.get(type)!(value);
|
|
@@ -39,12 +57,41 @@ const deserializeValueFromField = (field: Field, value: any) => {
|
|
|
39
57
|
}
|
|
40
58
|
};
|
|
41
59
|
|
|
60
|
+
const convertTypesOnInstance = (instance: any) => {
|
|
61
|
+
const properties = Object.getOwnPropertyNames(instance);
|
|
62
|
+
const converted: any = {};
|
|
63
|
+
properties.forEach(property => {
|
|
64
|
+
let value = instance[property];
|
|
65
|
+
if (value !== undefined) {
|
|
66
|
+
if (Array.isArray(value)) {
|
|
67
|
+
value = value.map(_ => convertTypesOnInstance(_));
|
|
68
|
+
} else {
|
|
69
|
+
value = serializeValueForType(value.__proto__.constructor, value);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
converted[property] = value;
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
return converted;
|
|
77
|
+
};
|
|
78
|
+
|
|
42
79
|
/**
|
|
43
80
|
* Represents a serializer for JSON.
|
|
44
81
|
*/
|
|
45
82
|
export class JsonSerializer {
|
|
46
83
|
static readonly DerivedTypeIdProperty: string = "_derivedTypeId";
|
|
47
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Serialize with strong type information.
|
|
87
|
+
* @param {*} value The value to serialize.
|
|
88
|
+
* @returns A JSON string.
|
|
89
|
+
*/
|
|
90
|
+
static serialize(value: any): string {
|
|
91
|
+
const converted = convertTypesOnInstance(value);
|
|
92
|
+
return JSON.stringify(converted);
|
|
93
|
+
}
|
|
94
|
+
|
|
48
95
|
/**
|
|
49
96
|
* Deserialize a JSON string to the specific type.
|
|
50
97
|
* @param {Constructor} targetType Type to deserialize to.
|
|
@@ -76,7 +123,7 @@ export class JsonSerializer {
|
|
|
76
123
|
static deserializeFromInstance<TResult extends {}>(targetType: Constructor<TResult>, instance: any): TResult {
|
|
77
124
|
const fields = Fields.getFieldsForType(targetType as Constructor);
|
|
78
125
|
|
|
79
|
-
if(
|
|
126
|
+
if (typeSerializers.has(targetType)) {
|
|
80
127
|
return deserializeValueFromType(targetType, instance);
|
|
81
128
|
}
|
|
82
129
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Constructor } from './Constructor';
|
|
2
2
|
export declare class JsonSerializer {
|
|
3
3
|
static readonly DerivedTypeIdProperty: string;
|
|
4
|
+
static serialize(value: any): string;
|
|
4
5
|
static deserialize<TResult extends {}>(targetType: Constructor<TResult>, json: string): TResult;
|
|
5
6
|
static deserializeArray<TResult extends {}>(targetType: Constructor<TResult>, json: string): TResult[];
|
|
6
7
|
static deserializeFromInstance<TResult extends {}>(targetType: Constructor<TResult>, instance: any): TResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsonSerializer.d.ts","sourceRoot":"","sources":["../../JsonSerializer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"JsonSerializer.d.ts","sourceRoot":"","sources":["../../JsonSerializer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AA8E5C,qBAAa,cAAc;IACvB,MAAM,CAAC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAoB;IAOjE,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM;IAWpC,MAAM,CAAC,WAAW,CAAC,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAW/F,MAAM,CAAC,gBAAgB,CAAC,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE;IAWtG,MAAM,CAAC,uBAAuB,CAAC,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,GAAG,GAAG,OAAO;IAwC5G,MAAM,CAAC,4BAA4B,CAAC,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,GAAG,GAAG,OAAO,EAAE;CASvH"}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var Fields = require('./Fields.js');
|
|
4
3
|
var DerivedType = require('./DerivedType.js');
|
|
4
|
+
var Fields = require('./Fields.js');
|
|
5
5
|
var Guid = require('./Guid.js');
|
|
6
6
|
|
|
7
|
+
const typeConverters = new Map([
|
|
8
|
+
[Number, (value) => value],
|
|
9
|
+
[String, (value) => value],
|
|
10
|
+
[Boolean, (value) => value],
|
|
11
|
+
[Date, (value) => value.toISOString()],
|
|
12
|
+
[Guid.Guid, (value) => { var _a; return (_a = value === null || value === void 0 ? void 0 : value.toString()) !== null && _a !== void 0 ? _a : ''; }]
|
|
13
|
+
]);
|
|
7
14
|
const typeSerializers = new Map([
|
|
8
15
|
[Number, (value) => value],
|
|
9
16
|
[String, (value) => value],
|
|
@@ -11,6 +18,16 @@ const typeSerializers = new Map([
|
|
|
11
18
|
[Date, (value) => new Date(value)],
|
|
12
19
|
[Guid.Guid, (value) => Guid.Guid.parse(value.toString())],
|
|
13
20
|
]);
|
|
21
|
+
const serializeValueForType = (type, value) => {
|
|
22
|
+
if (!value)
|
|
23
|
+
return value;
|
|
24
|
+
if (typeConverters.has(type)) {
|
|
25
|
+
return typeConverters.get(type)(value);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
return convertTypesOnInstance(value);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
14
31
|
const deserializeValueFromType = (type, value) => {
|
|
15
32
|
if (typeSerializers.has(type)) {
|
|
16
33
|
return typeSerializers.get(type)(value);
|
|
@@ -32,7 +49,28 @@ const deserializeValueFromField = (field, value) => {
|
|
|
32
49
|
return JsonSerializer.deserialize(type, JSON.stringify(value));
|
|
33
50
|
}
|
|
34
51
|
};
|
|
52
|
+
const convertTypesOnInstance = (instance) => {
|
|
53
|
+
const properties = Object.getOwnPropertyNames(instance);
|
|
54
|
+
const converted = {};
|
|
55
|
+
properties.forEach(property => {
|
|
56
|
+
let value = instance[property];
|
|
57
|
+
if (value !== undefined) {
|
|
58
|
+
if (Array.isArray(value)) {
|
|
59
|
+
value = value.map(_ => convertTypesOnInstance(_));
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
value = serializeValueForType(value.__proto__.constructor, value);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
converted[property] = value;
|
|
66
|
+
});
|
|
67
|
+
return converted;
|
|
68
|
+
};
|
|
35
69
|
class JsonSerializer {
|
|
70
|
+
static serialize(value) {
|
|
71
|
+
const converted = convertTypesOnInstance(value);
|
|
72
|
+
return JSON.stringify(converted);
|
|
73
|
+
}
|
|
36
74
|
static deserialize(targetType, json) {
|
|
37
75
|
const parsed = JSON.parse(json);
|
|
38
76
|
return this.deserializeFromInstance(targetType, parsed);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsonSerializer.js","sources":["../../JsonSerializer.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Constructor } from './Constructor';\nimport { Field } from './Field';\nimport { Fields } from './Fields';\nimport { DerivedType } from './DerivedType';\nimport { Guid } from './Guid';\n\ntype typeSerializer = (value: any) => any;\n\nconst typeSerializers: Map<Constructor, typeSerializer> = new Map<Constructor, typeSerializer>([\n [Number, (value: any) => value],\n [String, (value: any) => value],\n [Boolean, (value: any) => value],\n [Date, (value: any) => new Date(value)],\n [Guid, (value: any) => Guid.parse(value.toString())],\n]);\n\nconst deserializeValueFromType = (type: Constructor, value: any) => {\n if (typeSerializers.has(type)) {\n return typeSerializers.get(type)!(value);\n } else {\n return JsonSerializer.deserialize(type, JSON.stringify(value));\n }\n};\n\nconst deserializeValueFromField = (field: Field, value: any) => {\n if (typeSerializers.has(field.type)) {\n return typeSerializers.get(field.type)!(value);\n } else {\n let type = field.type;\n if (field.derivatives.length > 0 && value[JsonSerializer.DerivedTypeIdProperty]) {\n const derivedTypeId = value[JsonSerializer.DerivedTypeIdProperty];\n type = field.derivatives.find(_ => DerivedType.get(_) == derivedTypeId) || type;\n }\n\n return JsonSerializer.deserialize(type, JSON.stringify(value));\n }\n};\n\n/**\n * Represents a serializer for JSON.\n */\nexport class JsonSerializer {\n static readonly DerivedTypeIdProperty: string = \"_derivedTypeId\";\n\n /**\n * Deserialize a JSON string to the specific type.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {string} json Actual JSON to deserialize.\n * @returns An instance of the target type.\n */\n static deserialize<TResult extends {}>(targetType: Constructor<TResult>, json: string): TResult {\n const parsed = JSON.parse(json);\n return this.deserializeFromInstance<TResult>(targetType, parsed);\n }\n\n /**\n * Deserialize a array JSON string to an array of the specific instance type.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {string} json Actual JSON to deserialize.\n * @returns An array of instances of the target type.\n */\n static deserializeArray<TResult extends {}>(targetType: Constructor<TResult>, json: string): TResult[] {\n const parsed = JSON.parse(json);\n return this.deserializeArrayFromInstance(targetType, parsed);\n }\n\n /**\n * Deserialize an any instance to a specific instance type.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {*} instance Actual instance to deserialize.\n * @returns An instance of the target type.\n */\n static deserializeFromInstance<TResult extends {}>(targetType: Constructor<TResult>, instance: any): TResult {\n const fields = Fields.getFieldsForType(targetType as Constructor);\n\n if( typeSerializers.has(targetType) ) {\n return deserializeValueFromType(targetType, instance);\n }\n\n const deserialized = new targetType();\n for (const field of fields) {\n let value = instance[field.name];\n if (value) {\n if (field.enumerable) {\n value = value.map(_ => deserializeValueFromField(field, _));\n } else {\n value = deserializeValueFromField(field, value);\n }\n }\n\n deserialized[field.name] = value;\n }\n\n if ((targetType as Constructor) == Object) {\n const objectFields = Object.keys(instance).filter((value, index, arr) => {\n return !fields.some(_ => _.name == value);\n });\n\n for (const field of objectFields) {\n deserialized[field] = instance[field];\n }\n }\n\n return deserialized;\n }\n\n /**\n * Deserialize an array of any instances to an array of specific instance types.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {instances} instances Actual instances to deserialize.\n * @returns An array of instances of the target type.\n */\n static deserializeArrayFromInstance<TResult extends {}>(targetType: Constructor<TResult>, instances: any): TResult[] {\n const deserialized: TResult[] = [];\n\n for (const instance of instances) {\n deserialized.push(this.deserializeFromInstance<TResult>(targetType, instance));\n }\n\n return deserialized;\n }\n}\n"],"names":["Guid","DerivedType","Fields"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"JsonSerializer.js","sources":["../../JsonSerializer.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Constructor } from './Constructor';\nimport { DerivedType } from './DerivedType';\nimport { Field } from './Field';\nimport { Fields } from './Fields';\nimport { Guid } from './Guid';\n\ntype typeSerializer = (value: any) => any;\n\nconst typeConverters: Map<Constructor, typeSerializer> = new Map<Constructor, typeSerializer>([\n [Number, (value: number) => value],\n [String, (value: string) => value],\n [Boolean, (value: boolean) => value],\n [Date, (value: Date) => value.toISOString()],\n [Guid, (value: Guid) => value?.toString() ?? '']\n]);\n\nconst typeSerializers: Map<Constructor, typeSerializer> = new Map<Constructor, typeSerializer>([\n [Number, (value: any) => value],\n [String, (value: any) => value],\n [Boolean, (value: any) => value],\n [Date, (value: any) => new Date(value)],\n [Guid, (value: any) => Guid.parse(value.toString())],\n]);\n\nconst serializeValueForType = (type: Constructor, value: any) => {\n if (!value) return value;\n\n if (typeConverters.has(type)) {\n return typeConverters.get(type)!(value);\n } else {\n return convertTypesOnInstance(value);\n }\n};\n\nconst deserializeValueFromType = (type: Constructor, value: any) => {\n if (typeSerializers.has(type)) {\n return typeSerializers.get(type)!(value);\n } else {\n return JsonSerializer.deserialize(type, JSON.stringify(value));\n }\n};\n\nconst deserializeValueFromField = (field: Field, value: any) => {\n if (typeSerializers.has(field.type)) {\n return typeSerializers.get(field.type)!(value);\n } else {\n let type = field.type;\n if (field.derivatives.length > 0 && value[JsonSerializer.DerivedTypeIdProperty]) {\n const derivedTypeId = value[JsonSerializer.DerivedTypeIdProperty];\n type = field.derivatives.find(_ => DerivedType.get(_) == derivedTypeId) || type;\n }\n\n return JsonSerializer.deserialize(type, JSON.stringify(value));\n }\n};\n\nconst convertTypesOnInstance = (instance: any) => {\n const properties = Object.getOwnPropertyNames(instance);\n const converted: any = {};\n properties.forEach(property => {\n let value = instance[property];\n if (value !== undefined) {\n if (Array.isArray(value)) {\n value = value.map(_ => convertTypesOnInstance(_));\n } else {\n value = serializeValueForType(value.__proto__.constructor, value);\n }\n }\n\n converted[property] = value;\n });\n\n return converted;\n};\n\n/**\n * Represents a serializer for JSON.\n */\nexport class JsonSerializer {\n static readonly DerivedTypeIdProperty: string = \"_derivedTypeId\";\n\n /**\n * Serialize with strong type information.\n * @param {*} value The value to serialize.\n * @returns A JSON string.\n */\n static serialize(value: any): string {\n const converted = convertTypesOnInstance(value);\n return JSON.stringify(converted);\n }\n\n /**\n * Deserialize a JSON string to the specific type.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {string} json Actual JSON to deserialize.\n * @returns An instance of the target type.\n */\n static deserialize<TResult extends {}>(targetType: Constructor<TResult>, json: string): TResult {\n const parsed = JSON.parse(json);\n return this.deserializeFromInstance<TResult>(targetType, parsed);\n }\n\n /**\n * Deserialize a array JSON string to an array of the specific instance type.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {string} json Actual JSON to deserialize.\n * @returns An array of instances of the target type.\n */\n static deserializeArray<TResult extends {}>(targetType: Constructor<TResult>, json: string): TResult[] {\n const parsed = JSON.parse(json);\n return this.deserializeArrayFromInstance(targetType, parsed);\n }\n\n /**\n * Deserialize an any instance to a specific instance type.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {*} instance Actual instance to deserialize.\n * @returns An instance of the target type.\n */\n static deserializeFromInstance<TResult extends {}>(targetType: Constructor<TResult>, instance: any): TResult {\n const fields = Fields.getFieldsForType(targetType as Constructor);\n\n if (typeSerializers.has(targetType)) {\n return deserializeValueFromType(targetType, instance);\n }\n\n const deserialized = new targetType();\n for (const field of fields) {\n let value = instance[field.name];\n if (value) {\n if (field.enumerable) {\n value = value.map(_ => deserializeValueFromField(field, _));\n } else {\n value = deserializeValueFromField(field, value);\n }\n }\n\n deserialized[field.name] = value;\n }\n\n if ((targetType as Constructor) == Object) {\n const objectFields = Object.keys(instance).filter((value, index, arr) => {\n return !fields.some(_ => _.name == value);\n });\n\n for (const field of objectFields) {\n deserialized[field] = instance[field];\n }\n }\n\n return deserialized;\n }\n\n /**\n * Deserialize an array of any instances to an array of specific instance types.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {instances} instances Actual instances to deserialize.\n * @returns An array of instances of the target type.\n */\n static deserializeArrayFromInstance<TResult extends {}>(targetType: Constructor<TResult>, instances: any): TResult[] {\n const deserialized: TResult[] = [];\n\n for (const instance of instances) {\n deserialized.push(this.deserializeFromInstance<TResult>(targetType, instance));\n }\n\n return deserialized;\n }\n}\n"],"names":["Guid","DerivedType","Fields"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Constructor } from './Constructor';
|
|
2
2
|
export declare class JsonSerializer {
|
|
3
3
|
static readonly DerivedTypeIdProperty: string;
|
|
4
|
+
static serialize(value: any): string;
|
|
4
5
|
static deserialize<TResult extends {}>(targetType: Constructor<TResult>, json: string): TResult;
|
|
5
6
|
static deserializeArray<TResult extends {}>(targetType: Constructor<TResult>, json: string): TResult[];
|
|
6
7
|
static deserializeFromInstance<TResult extends {}>(targetType: Constructor<TResult>, instance: any): TResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsonSerializer.d.ts","sourceRoot":"","sources":["../../JsonSerializer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"JsonSerializer.d.ts","sourceRoot":"","sources":["../../JsonSerializer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AA8E5C,qBAAa,cAAc;IACvB,MAAM,CAAC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAoB;IAOjE,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM;IAWpC,MAAM,CAAC,WAAW,CAAC,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAW/F,MAAM,CAAC,gBAAgB,CAAC,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE;IAWtG,MAAM,CAAC,uBAAuB,CAAC,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,GAAG,GAAG,OAAO;IAwC5G,MAAM,CAAC,4BAA4B,CAAC,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,GAAG,GAAG,OAAO,EAAE;CASvH"}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
import { Fields } from './Fields.js';
|
|
2
1
|
import { DerivedType } from './DerivedType.js';
|
|
2
|
+
import { Fields } from './Fields.js';
|
|
3
3
|
import { Guid } from './Guid.js';
|
|
4
4
|
|
|
5
|
+
const typeConverters = new Map([
|
|
6
|
+
[Number, (value) => value],
|
|
7
|
+
[String, (value) => value],
|
|
8
|
+
[Boolean, (value) => value],
|
|
9
|
+
[Date, (value) => value.toISOString()],
|
|
10
|
+
[Guid, (value) => { var _a; return (_a = value === null || value === void 0 ? void 0 : value.toString()) !== null && _a !== void 0 ? _a : ''; }]
|
|
11
|
+
]);
|
|
5
12
|
const typeSerializers = new Map([
|
|
6
13
|
[Number, (value) => value],
|
|
7
14
|
[String, (value) => value],
|
|
@@ -9,6 +16,16 @@ const typeSerializers = new Map([
|
|
|
9
16
|
[Date, (value) => new Date(value)],
|
|
10
17
|
[Guid, (value) => Guid.parse(value.toString())],
|
|
11
18
|
]);
|
|
19
|
+
const serializeValueForType = (type, value) => {
|
|
20
|
+
if (!value)
|
|
21
|
+
return value;
|
|
22
|
+
if (typeConverters.has(type)) {
|
|
23
|
+
return typeConverters.get(type)(value);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
return convertTypesOnInstance(value);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
12
29
|
const deserializeValueFromType = (type, value) => {
|
|
13
30
|
if (typeSerializers.has(type)) {
|
|
14
31
|
return typeSerializers.get(type)(value);
|
|
@@ -30,7 +47,28 @@ const deserializeValueFromField = (field, value) => {
|
|
|
30
47
|
return JsonSerializer.deserialize(type, JSON.stringify(value));
|
|
31
48
|
}
|
|
32
49
|
};
|
|
50
|
+
const convertTypesOnInstance = (instance) => {
|
|
51
|
+
const properties = Object.getOwnPropertyNames(instance);
|
|
52
|
+
const converted = {};
|
|
53
|
+
properties.forEach(property => {
|
|
54
|
+
let value = instance[property];
|
|
55
|
+
if (value !== undefined) {
|
|
56
|
+
if (Array.isArray(value)) {
|
|
57
|
+
value = value.map(_ => convertTypesOnInstance(_));
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
value = serializeValueForType(value.__proto__.constructor, value);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
converted[property] = value;
|
|
64
|
+
});
|
|
65
|
+
return converted;
|
|
66
|
+
};
|
|
33
67
|
class JsonSerializer {
|
|
68
|
+
static serialize(value) {
|
|
69
|
+
const converted = convertTypesOnInstance(value);
|
|
70
|
+
return JSON.stringify(converted);
|
|
71
|
+
}
|
|
34
72
|
static deserialize(targetType, json) {
|
|
35
73
|
const parsed = JSON.parse(json);
|
|
36
74
|
return this.deserializeFromInstance(targetType, parsed);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsonSerializer.js","sources":["../../JsonSerializer.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Constructor } from './Constructor';\nimport { Field } from './Field';\nimport { Fields } from './Fields';\nimport { DerivedType } from './DerivedType';\nimport { Guid } from './Guid';\n\ntype typeSerializer = (value: any) => any;\n\nconst typeSerializers: Map<Constructor, typeSerializer> = new Map<Constructor, typeSerializer>([\n [Number, (value: any) => value],\n [String, (value: any) => value],\n [Boolean, (value: any) => value],\n [Date, (value: any) => new Date(value)],\n [Guid, (value: any) => Guid.parse(value.toString())],\n]);\n\nconst deserializeValueFromType = (type: Constructor, value: any) => {\n if (typeSerializers.has(type)) {\n return typeSerializers.get(type)!(value);\n } else {\n return JsonSerializer.deserialize(type, JSON.stringify(value));\n }\n};\n\nconst deserializeValueFromField = (field: Field, value: any) => {\n if (typeSerializers.has(field.type)) {\n return typeSerializers.get(field.type)!(value);\n } else {\n let type = field.type;\n if (field.derivatives.length > 0 && value[JsonSerializer.DerivedTypeIdProperty]) {\n const derivedTypeId = value[JsonSerializer.DerivedTypeIdProperty];\n type = field.derivatives.find(_ => DerivedType.get(_) == derivedTypeId) || type;\n }\n\n return JsonSerializer.deserialize(type, JSON.stringify(value));\n }\n};\n\n/**\n * Represents a serializer for JSON.\n */\nexport class JsonSerializer {\n static readonly DerivedTypeIdProperty: string = \"_derivedTypeId\";\n\n /**\n * Deserialize a JSON string to the specific type.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {string} json Actual JSON to deserialize.\n * @returns An instance of the target type.\n */\n static deserialize<TResult extends {}>(targetType: Constructor<TResult>, json: string): TResult {\n const parsed = JSON.parse(json);\n return this.deserializeFromInstance<TResult>(targetType, parsed);\n }\n\n /**\n * Deserialize a array JSON string to an array of the specific instance type.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {string} json Actual JSON to deserialize.\n * @returns An array of instances of the target type.\n */\n static deserializeArray<TResult extends {}>(targetType: Constructor<TResult>, json: string): TResult[] {\n const parsed = JSON.parse(json);\n return this.deserializeArrayFromInstance(targetType, parsed);\n }\n\n /**\n * Deserialize an any instance to a specific instance type.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {*} instance Actual instance to deserialize.\n * @returns An instance of the target type.\n */\n static deserializeFromInstance<TResult extends {}>(targetType: Constructor<TResult>, instance: any): TResult {\n const fields = Fields.getFieldsForType(targetType as Constructor);\n\n if( typeSerializers.has(targetType) ) {\n return deserializeValueFromType(targetType, instance);\n }\n\n const deserialized = new targetType();\n for (const field of fields) {\n let value = instance[field.name];\n if (value) {\n if (field.enumerable) {\n value = value.map(_ => deserializeValueFromField(field, _));\n } else {\n value = deserializeValueFromField(field, value);\n }\n }\n\n deserialized[field.name] = value;\n }\n\n if ((targetType as Constructor) == Object) {\n const objectFields = Object.keys(instance).filter((value, index, arr) => {\n return !fields.some(_ => _.name == value);\n });\n\n for (const field of objectFields) {\n deserialized[field] = instance[field];\n }\n }\n\n return deserialized;\n }\n\n /**\n * Deserialize an array of any instances to an array of specific instance types.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {instances} instances Actual instances to deserialize.\n * @returns An array of instances of the target type.\n */\n static deserializeArrayFromInstance<TResult extends {}>(targetType: Constructor<TResult>, instances: any): TResult[] {\n const deserialized: TResult[] = [];\n\n for (const instance of instances) {\n deserialized.push(this.deserializeFromInstance<TResult>(targetType, instance));\n }\n\n return deserialized;\n }\n}\n"],"names":[],"mappings":";;;;AAWA,MAAM,eAAe,GAAqC,IAAI,GAAG,CAA8B;IAC3F,CAAC,MAAM,EAAE,CAAC,KAAU,KAAK,KAAK,CAAC;IAC/B,CAAC,MAAM,EAAE,CAAC,KAAU,KAAK,KAAK,CAAC;IAC/B,CAAC,OAAO,EAAE,CAAC,KAAU,KAAK,KAAK,CAAC;AAChC,IAAA,CAAC,IAAI,EAAE,CAAC,KAAU,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;AACvC,IAAA,CAAC,IAAI,EAAE,CAAC,KAAU,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;AACvD,CAAA,CAAC,CAAC;AAEH,MAAM,wBAAwB,GAAG,CAAC,IAAiB,EAAE,KAAU,KAAI;AAC/D,IAAA,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QAC3B,OAAO,eAAe,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,KAAK,CAAC,CAAC;KAC5C;SAAM;AACH,QAAA,OAAO,cAAc,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;KAClE;AACL,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG,CAAC,KAAY,EAAE,KAAU,KAAI;IAC3D,IAAI,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;QACjC,OAAO,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC,KAAK,CAAC,CAAC;KAClD;SAAM;AACH,QAAA,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;AACtB,QAAA,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,qBAAqB,CAAC,EAAE;YAC7E,MAAM,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC,qBAAqB,CAAC,CAAC;YAClE,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,IAAI,IAAI,CAAC;SACnF;AAED,QAAA,OAAO,cAAc,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;KAClE;AACL,CAAC,CAAC;MAKW,cAAc,CAAA;AASvB,IAAA,OAAO,WAAW,CAAqB,UAAgC,EAAE,IAAY,EAAA;QACjF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC,uBAAuB,CAAU,UAAU,EAAE,MAAM,CAAC,CAAC;KACpE;AAQD,IAAA,OAAO,gBAAgB,CAAqB,UAAgC,EAAE,IAAY,EAAA;QACtF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC,4BAA4B,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;KAChE;AAQD,IAAA,OAAO,uBAAuB,CAAqB,UAAgC,EAAE,QAAa,EAAA;QAC9F,MAAM,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC,UAAyB,CAAC,CAAC;AAElE,QAAA,IAAI,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,EAAG;AAClC,YAAA,OAAO,wBAAwB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;SACzD;AAED,QAAA,MAAM,YAAY,GAAG,IAAI,UAAU,EAAE,CAAC;AACtC,QAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;YACxB,IAAI,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACjC,IAAI,KAAK,EAAE;AACP,gBAAA,IAAI,KAAK,CAAC,UAAU,EAAE;AAClB,oBAAA,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,yBAAyB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;iBAC/D;qBAAM;AACH,oBAAA,KAAK,GAAG,yBAAyB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;iBACnD;aACJ;AAED,YAAA,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;SACpC;AAED,QAAA,IAAK,UAA0B,IAAI,MAAM,EAAE;AACvC,YAAA,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,KAAI;AACpE,gBAAA,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC;AAC9C,aAAC,CAAC,CAAC;AAEH,YAAA,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE;gBAC9B,YAAY,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;aACzC;SACJ;AAED,QAAA,OAAO,YAAY,CAAC;KACvB;AAQD,IAAA,OAAO,4BAA4B,CAAqB,UAAgC,EAAE,SAAc,EAAA;QACpG,MAAM,YAAY,GAAc,EAAE,CAAC;AAEnC,QAAA,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;AAC9B,YAAA,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAU,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;SAClF;AAED,QAAA,OAAO,YAAY,CAAC;KACvB;;AA9Ee,cAAqB,CAAA,qBAAA,GAAW,gBAAgB;;;;"}
|
|
1
|
+
{"version":3,"file":"JsonSerializer.js","sources":["../../JsonSerializer.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Constructor } from './Constructor';\nimport { DerivedType } from './DerivedType';\nimport { Field } from './Field';\nimport { Fields } from './Fields';\nimport { Guid } from './Guid';\n\ntype typeSerializer = (value: any) => any;\n\nconst typeConverters: Map<Constructor, typeSerializer> = new Map<Constructor, typeSerializer>([\n [Number, (value: number) => value],\n [String, (value: string) => value],\n [Boolean, (value: boolean) => value],\n [Date, (value: Date) => value.toISOString()],\n [Guid, (value: Guid) => value?.toString() ?? '']\n]);\n\nconst typeSerializers: Map<Constructor, typeSerializer> = new Map<Constructor, typeSerializer>([\n [Number, (value: any) => value],\n [String, (value: any) => value],\n [Boolean, (value: any) => value],\n [Date, (value: any) => new Date(value)],\n [Guid, (value: any) => Guid.parse(value.toString())],\n]);\n\nconst serializeValueForType = (type: Constructor, value: any) => {\n if (!value) return value;\n\n if (typeConverters.has(type)) {\n return typeConverters.get(type)!(value);\n } else {\n return convertTypesOnInstance(value);\n }\n};\n\nconst deserializeValueFromType = (type: Constructor, value: any) => {\n if (typeSerializers.has(type)) {\n return typeSerializers.get(type)!(value);\n } else {\n return JsonSerializer.deserialize(type, JSON.stringify(value));\n }\n};\n\nconst deserializeValueFromField = (field: Field, value: any) => {\n if (typeSerializers.has(field.type)) {\n return typeSerializers.get(field.type)!(value);\n } else {\n let type = field.type;\n if (field.derivatives.length > 0 && value[JsonSerializer.DerivedTypeIdProperty]) {\n const derivedTypeId = value[JsonSerializer.DerivedTypeIdProperty];\n type = field.derivatives.find(_ => DerivedType.get(_) == derivedTypeId) || type;\n }\n\n return JsonSerializer.deserialize(type, JSON.stringify(value));\n }\n};\n\nconst convertTypesOnInstance = (instance: any) => {\n const properties = Object.getOwnPropertyNames(instance);\n const converted: any = {};\n properties.forEach(property => {\n let value = instance[property];\n if (value !== undefined) {\n if (Array.isArray(value)) {\n value = value.map(_ => convertTypesOnInstance(_));\n } else {\n value = serializeValueForType(value.__proto__.constructor, value);\n }\n }\n\n converted[property] = value;\n });\n\n return converted;\n};\n\n/**\n * Represents a serializer for JSON.\n */\nexport class JsonSerializer {\n static readonly DerivedTypeIdProperty: string = \"_derivedTypeId\";\n\n /**\n * Serialize with strong type information.\n * @param {*} value The value to serialize.\n * @returns A JSON string.\n */\n static serialize(value: any): string {\n const converted = convertTypesOnInstance(value);\n return JSON.stringify(converted);\n }\n\n /**\n * Deserialize a JSON string to the specific type.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {string} json Actual JSON to deserialize.\n * @returns An instance of the target type.\n */\n static deserialize<TResult extends {}>(targetType: Constructor<TResult>, json: string): TResult {\n const parsed = JSON.parse(json);\n return this.deserializeFromInstance<TResult>(targetType, parsed);\n }\n\n /**\n * Deserialize a array JSON string to an array of the specific instance type.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {string} json Actual JSON to deserialize.\n * @returns An array of instances of the target type.\n */\n static deserializeArray<TResult extends {}>(targetType: Constructor<TResult>, json: string): TResult[] {\n const parsed = JSON.parse(json);\n return this.deserializeArrayFromInstance(targetType, parsed);\n }\n\n /**\n * Deserialize an any instance to a specific instance type.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {*} instance Actual instance to deserialize.\n * @returns An instance of the target type.\n */\n static deserializeFromInstance<TResult extends {}>(targetType: Constructor<TResult>, instance: any): TResult {\n const fields = Fields.getFieldsForType(targetType as Constructor);\n\n if (typeSerializers.has(targetType)) {\n return deserializeValueFromType(targetType, instance);\n }\n\n const deserialized = new targetType();\n for (const field of fields) {\n let value = instance[field.name];\n if (value) {\n if (field.enumerable) {\n value = value.map(_ => deserializeValueFromField(field, _));\n } else {\n value = deserializeValueFromField(field, value);\n }\n }\n\n deserialized[field.name] = value;\n }\n\n if ((targetType as Constructor) == Object) {\n const objectFields = Object.keys(instance).filter((value, index, arr) => {\n return !fields.some(_ => _.name == value);\n });\n\n for (const field of objectFields) {\n deserialized[field] = instance[field];\n }\n }\n\n return deserialized;\n }\n\n /**\n * Deserialize an array of any instances to an array of specific instance types.\n * @param {Constructor} targetType Type to deserialize to.\n * @param {instances} instances Actual instances to deserialize.\n * @returns An array of instances of the target type.\n */\n static deserializeArrayFromInstance<TResult extends {}>(targetType: Constructor<TResult>, instances: any): TResult[] {\n const deserialized: TResult[] = [];\n\n for (const instance of instances) {\n deserialized.push(this.deserializeFromInstance<TResult>(targetType, instance));\n }\n\n return deserialized;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { field } from '../fieldDecorator';
|
|
5
|
+
import { derivedType } from '../derivedTypeDecorator';
|
|
6
|
+
import { Guid } from '../Guid';
|
|
7
|
+
|
|
8
|
+
export class OtherType {
|
|
9
|
+
@field(Number)
|
|
10
|
+
someNumber!: number;
|
|
11
|
+
|
|
12
|
+
@field(String)
|
|
13
|
+
someString!: string;
|
|
14
|
+
|
|
15
|
+
@field(Date)
|
|
16
|
+
someDate!: Date;
|
|
17
|
+
|
|
18
|
+
@field(Guid)
|
|
19
|
+
someGuid!: Guid;
|
|
20
|
+
|
|
21
|
+
@field(Date)
|
|
22
|
+
collectionOfDates!: Date[];
|
|
23
|
+
|
|
24
|
+
@field(Number)
|
|
25
|
+
collectionOfNumbers!: number[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
29
|
+
export interface ITargetType { }
|
|
30
|
+
|
|
31
|
+
@derivedType('ad7593d1-71be-4e26-9026-aedb32fc43d3')
|
|
32
|
+
export class FirstDerivative implements ITargetType {
|
|
33
|
+
@field(Number)
|
|
34
|
+
firstDerivativeProperty!: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@derivedType('a038ca48-360e-46a7-8cb2-882ff21bb623')
|
|
38
|
+
export class SecondDerivative implements ITargetType {
|
|
39
|
+
@field(Number)
|
|
40
|
+
secondDerivativeProperty!: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export class TopLevel {
|
|
44
|
+
@field(Number)
|
|
45
|
+
someNumber!: number;
|
|
46
|
+
|
|
47
|
+
@field(String)
|
|
48
|
+
someString!: string;
|
|
49
|
+
|
|
50
|
+
@field(Date)
|
|
51
|
+
someDate!: Date;
|
|
52
|
+
|
|
53
|
+
@field(Boolean)
|
|
54
|
+
someBoolean!: boolean;
|
|
55
|
+
|
|
56
|
+
@field(Guid)
|
|
57
|
+
someGuid!: Guid;
|
|
58
|
+
|
|
59
|
+
@field(OtherType)
|
|
60
|
+
otherType!: OtherType;
|
|
61
|
+
|
|
62
|
+
@field(OtherType, true)
|
|
63
|
+
collectionOfOtherType!: OtherType[];
|
|
64
|
+
|
|
65
|
+
@field(Object, true, [FirstDerivative, SecondDerivative])
|
|
66
|
+
collectionOfDerivedTypes!: ITargetType[];
|
|
67
|
+
}
|
package/for_JsonSerializer/when_deserializing_complex_nested_object_with_multiple_wellknown_types.ts
CHANGED
|
@@ -1,85 +1,34 @@
|
|
|
1
1
|
// Copyright (c) Cratis. All rights reserved.
|
|
2
2
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
3
|
|
|
4
|
-
import { field } from '../fieldDecorator';
|
|
5
4
|
import { JsonSerializer } from '../JsonSerializer';
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
class OtherType {
|
|
9
|
-
@field(Number)
|
|
10
|
-
someNumber!: number;
|
|
11
|
-
|
|
12
|
-
@field(String)
|
|
13
|
-
someString!: string;
|
|
14
|
-
|
|
15
|
-
@field(Date)
|
|
16
|
-
someDate!: Date;
|
|
17
|
-
|
|
18
|
-
@field(Date)
|
|
19
|
-
collectionOfDates!: Date[];
|
|
20
|
-
|
|
21
|
-
@field(Number)
|
|
22
|
-
collectionOfNumbers!: number[];
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
26
|
-
interface ITargetType { }
|
|
27
|
-
|
|
28
|
-
@derivedType('ad7593d1-71be-4e26-9026-aedb32fc43d3')
|
|
29
|
-
class FirstDerivative implements ITargetType {
|
|
30
|
-
@field(Number)
|
|
31
|
-
firstDerivativeProperty!: number;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
@derivedType('a038ca48-360e-46a7-8cb2-882ff21bb623')
|
|
35
|
-
class SecondDerivative implements ITargetType {
|
|
36
|
-
@field(Number)
|
|
37
|
-
secondDerivativeProperty!: number;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
class TopLevel {
|
|
41
|
-
@field(Number)
|
|
42
|
-
someNumber!: number;
|
|
43
|
-
|
|
44
|
-
@field(String)
|
|
45
|
-
someString!: string;
|
|
46
|
-
|
|
47
|
-
@field(Date)
|
|
48
|
-
someDate!: Date;
|
|
49
|
-
|
|
50
|
-
@field(Boolean)
|
|
51
|
-
someBoolean!: boolean;
|
|
52
|
-
|
|
53
|
-
@field(OtherType)
|
|
54
|
-
otherType!: OtherType;
|
|
55
|
-
|
|
56
|
-
@field(OtherType, true)
|
|
57
|
-
collectionOfOtherType!: OtherType[];
|
|
58
|
-
|
|
59
|
-
@field(Object, true, [FirstDerivative, SecondDerivative])
|
|
60
|
-
collectionOfDerivedTypes!: ITargetType[];
|
|
61
|
-
}
|
|
5
|
+
import { Guid } from '../Guid';
|
|
6
|
+
import { FirstDerivative, SecondDerivative, TopLevel } from './Types';
|
|
62
7
|
|
|
63
8
|
const json = '{' +
|
|
64
9
|
' "someNumber": 42,' +
|
|
65
10
|
' "someString": "forty two",' +
|
|
66
11
|
' "someDate": "2022-10-07 15:51",' +
|
|
67
12
|
' "someBoolean": true,' +
|
|
13
|
+
' "someGuid": "f0fa7c5e-9f7b-4688-8851-e0b6eeebe28b",' +
|
|
68
14
|
' "otherType": {' +
|
|
69
15
|
' "someNumber": 43,' +
|
|
70
16
|
' "someString": "forty three",' +
|
|
71
|
-
' "someDate": "2022-11-07 15:51"' +
|
|
17
|
+
' "someDate": "2022-11-07 15:51",' +
|
|
18
|
+
' "someGuid": "a97f20cb-7f13-4f05-ab15-efb2b43c2457"' +
|
|
72
19
|
' },' +
|
|
73
20
|
' "collectionOfOtherType": [' +
|
|
74
21
|
' {' +
|
|
75
22
|
' "someNumber": 44,' +
|
|
76
23
|
' "someString": "forty four",' +
|
|
77
|
-
' "someDate": "2022-12-07 15:51"' +
|
|
24
|
+
' "someDate": "2022-12-07 15:51",' +
|
|
25
|
+
' "someGuid": "6d96dcba-3f71-4cb1-ab2c-cd6e52b7e7fd"' +
|
|
78
26
|
' },' +
|
|
79
27
|
' {' +
|
|
80
28
|
' "someNumber": 45,' +
|
|
81
29
|
' "someString": "forty five",' +
|
|
82
|
-
' "someDate": "
|
|
30
|
+
' "someDate": "2023-01-07 15:51",' +
|
|
31
|
+
' "someGuid": "3d7666c9-8929-4d41-9293-768100d0a019"' +
|
|
83
32
|
' }' +
|
|
84
33
|
' ],' +
|
|
85
34
|
' "collectionOfDerivedTypes": [' +
|
|
@@ -96,15 +45,30 @@ describe('when deserializing complex nested object with multiple wellknown types
|
|
|
96
45
|
it('should hold correct number for first level number', () => result.someNumber.should.equal(42));
|
|
97
46
|
it('should hold correct string for first level string', () => result.someString.should.equal('forty two'));
|
|
98
47
|
it('should hold correct bool value for first level boolean', () => result.someBoolean.should.be.true);
|
|
48
|
+
it('should hold correct guid value for first level guid', () => result.someGuid.toString().should.equal('f0fa7c5e-9f7b-4688-8851-e0b6eeebe28b'));
|
|
49
|
+
it('should hold correct type for first level guid', () => result.someGuid.constructor.should.equal(Guid));
|
|
99
50
|
it('should hold correct type for first level date', () => result.someDate.constructor.should.equal(Date));
|
|
100
51
|
it('should hold correct value for first level date', () => result.someDate.toString().should.equal(new Date('2022-10-07 15:51').toString()));
|
|
101
52
|
|
|
102
53
|
it('should hold correct number for second level number', () => result.otherType.someNumber.should.equal(43));
|
|
103
54
|
it('should hold correct string for second level string', () => result.otherType.someString.should.equal('forty three'));
|
|
104
55
|
it('should hold correct type for second level date', () => result.otherType.someDate.constructor.should.equal(Date));
|
|
56
|
+
it('should hold correct guid value for second level guid', () => result.otherType.someGuid.toString().should.equal('a97f20cb-7f13-4f05-ab15-efb2b43c2457'));
|
|
57
|
+
it('should hold correct type for second level guid', () => result.otherType.someGuid.constructor.should.equal(Guid));
|
|
105
58
|
it('should hold correct value for second level date', () => result.otherType.someDate.toString().should.equal(new Date('2022-11-07 15:51').toString()));
|
|
106
59
|
|
|
107
60
|
it('should have 2 items in the children', () => result.collectionOfOtherType.length.should.equal(2));
|
|
61
|
+
it('should hold correct number for number in first child', () => result.collectionOfOtherType[0].someNumber.should.equal(44));
|
|
62
|
+
it('should hold correct string for string in first child', () => result.collectionOfOtherType[0].someString.should.equal('forty four'));
|
|
63
|
+
it('should hold correct type for date in first child', () => result.collectionOfOtherType[0].someDate.constructor.should.equal(Date));
|
|
64
|
+
it('should hold correct value for date in first child', () => result.collectionOfOtherType[0].someDate.toString().should.equal(new Date('2022-12-07 15:51').toString()));
|
|
65
|
+
it('should hold correct guid value for guid in first child', () => result.collectionOfOtherType[0].someGuid.toString().should.equal('6d96dcba-3f71-4cb1-ab2c-cd6e52b7e7fd'));
|
|
66
|
+
|
|
67
|
+
it('should hold correct number for number in second child', () => result.collectionOfOtherType[1].someNumber.should.equal(45));
|
|
68
|
+
it('should hold correct string for string in second child', () => result.collectionOfOtherType[1].someString.should.equal('forty five'));
|
|
69
|
+
it('should hold correct type for date in second child', () => result.collectionOfOtherType[1].someDate.constructor.should.equal(Date));
|
|
70
|
+
it('should hold correct value for date in second child', () => result.collectionOfOtherType[1].someDate.toString().should.equal(new Date('2023-01-07 15:51').toString()));
|
|
71
|
+
it('should hold correct guid value for guid in second child', () => result.collectionOfOtherType[1].someGuid.toString().should.equal('3d7666c9-8929-4d41-9293-768100d0a019'));
|
|
108
72
|
|
|
109
73
|
it('should have 2 items in the derived types collection', () => result.collectionOfDerivedTypes.length.should.equal(2));
|
|
110
74
|
it('should have correct type for first derivative', () => result.collectionOfDerivedTypes[0].constructor.should.equal(FirstDerivative));
|
package/for_JsonSerializer/when_serializing_complex_nested_object_with_multiple_wellknown_types.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { JsonSerializer } from '../JsonSerializer';
|
|
5
|
+
import { Guid } from '../Guid';
|
|
6
|
+
import { OtherType, TopLevel } from './Types';
|
|
7
|
+
|
|
8
|
+
describe('when serializing complex nested object with multiple wellknown types', () => {
|
|
9
|
+
const instance = new TopLevel();
|
|
10
|
+
instance.someNumber = 42;
|
|
11
|
+
instance.someString = 'forty two';
|
|
12
|
+
instance.someDate = new Date('2022-10-07 15:51');
|
|
13
|
+
instance.someBoolean = true;
|
|
14
|
+
instance.someGuid = Guid.parse('f0fa7c5e-9f7b-4688-8851-e0b6eeebe28b');
|
|
15
|
+
instance.otherType = new OtherType();
|
|
16
|
+
instance.otherType.someNumber = 43;
|
|
17
|
+
instance.otherType.someString = 'forty three';
|
|
18
|
+
instance.otherType.someDate = new Date('2022-11-07 15:51');
|
|
19
|
+
instance.otherType.someGuid = Guid.parse('a97f20cb-7f13-4f05-ab15-efb2b43c2457');
|
|
20
|
+
instance.collectionOfOtherType = [
|
|
21
|
+
new OtherType(),
|
|
22
|
+
new OtherType()
|
|
23
|
+
];
|
|
24
|
+
instance.collectionOfOtherType[0].someNumber = 44;
|
|
25
|
+
instance.collectionOfOtherType[0].someString = 'forty four';
|
|
26
|
+
instance.collectionOfOtherType[0].someGuid = Guid.parse('b8987c5c-6506-4da7-8f19-a50cfc218c54');
|
|
27
|
+
instance.collectionOfOtherType[0].someDate = new Date('2022-12-07 15:51');
|
|
28
|
+
instance.collectionOfOtherType[1].someNumber = 45;
|
|
29
|
+
instance.collectionOfOtherType[1].someString = 'forty five';
|
|
30
|
+
instance.collectionOfOtherType[1].someGuid = Guid.parse('ee503799-63a7-4666-84b8-46eb1641206a');
|
|
31
|
+
instance.collectionOfOtherType[1].someDate = new Date('2023-01-07 15:51');
|
|
32
|
+
|
|
33
|
+
const result = JsonSerializer.serialize(instance);
|
|
34
|
+
const deserialized = JSON.parse(result);
|
|
35
|
+
|
|
36
|
+
it('should hold correct number for first level number', () => deserialized.someNumber.should.equal(42));
|
|
37
|
+
it('should hold correct string for first level string', () => deserialized.someString.should.equal('forty two'));
|
|
38
|
+
it('should hold correct bool value for first level boolean', () => deserialized.someBoolean.should.be.true);
|
|
39
|
+
it('should hold correct guid value for first level guid', () => deserialized.someGuid.should.equal(instance.someGuid.toString()));
|
|
40
|
+
it('should hold correct value for first level date', () => deserialized.someDate.toString().should.equal(JSON.stringify(instance.someDate).slice(1, -1)));
|
|
41
|
+
|
|
42
|
+
it('should hold correct number for second level number', () => deserialized.otherType.someNumber.should.equal(43));
|
|
43
|
+
it('should hold correct string for second level string', () => deserialized.otherType.someString.should.equal('forty three'));
|
|
44
|
+
it('should hold correct guid value for second level guid', () => deserialized.otherType.someGuid.should.equal(instance.otherType.someGuid.toString()));
|
|
45
|
+
it('should hold correct value for second level date', () => deserialized.otherType.someDate.toString().should.equal(JSON.stringify(instance.otherType.someDate).slice(1, -1)));
|
|
46
|
+
|
|
47
|
+
it('should have 2 items in the children', () => deserialized.collectionOfOtherType.length.should.equal(2));
|
|
48
|
+
it('should hold correct number for number in first child', () => deserialized.collectionOfOtherType[0].someNumber.should.equal(44));
|
|
49
|
+
it('should hold correct string for string in first child', () => deserialized.collectionOfOtherType[0].someString.should.equal('forty four'));
|
|
50
|
+
it('should hold correct value for date in first child', () => deserialized.collectionOfOtherType[0].someDate.toString().should.equal(JSON.stringify(instance.collectionOfOtherType[0].someDate).slice(1, -1)));
|
|
51
|
+
it('should hold correct guid value for guid in first child', () => deserialized.collectionOfOtherType[0].someGuid.toString().should.equal(instance.collectionOfOtherType[0].someGuid.toString()));
|
|
52
|
+
|
|
53
|
+
it('should hold correct number for number in second child', () => deserialized.collectionOfOtherType[1].someNumber.should.equal(45));
|
|
54
|
+
it('should hold correct string for string in second child', () => deserialized.collectionOfOtherType[1].someString.should.equal('forty five'));
|
|
55
|
+
it('should hold correct value for date in second child', () => deserialized.collectionOfOtherType[1].someDate.toString().should.equal(JSON.stringify(instance.collectionOfOtherType[1].someDate).slice(1, -1)));
|
|
56
|
+
it('should hold correct guid value for guid in second child', () => deserialized.collectionOfOtherType[1].someGuid.toString().should.equal(instance.collectionOfOtherType[1].someGuid.toString()));
|
|
57
|
+
});
|