From 60447ee746acf3bf72bb3c88785f8a005c836b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20D=C4=99bski?= Date: Thu, 14 Mar 2019 23:16:01 +0100 Subject: [PATCH] Move parser class to separate file --- js/parser.d.ts | 129 +++ js/typedjson.d.ts | 130 +-- js/typedjson.js | 1885 ++++++++++++++++++++------------------- js/typedjson.js.map | 2 +- js/typedjson.min.js | 4 +- js/typedjson.min.js.map | 2 +- src/parser.ts | 534 +++++++++++ src/typedjson.ts | 536 +---------- 8 files changed, 1613 insertions(+), 1609 deletions(-) create mode 100644 js/parser.d.ts create mode 100644 src/parser.ts diff --git a/js/parser.d.ts b/js/parser.d.ts new file mode 100644 index 0000000..7dd3c2e --- /dev/null +++ b/js/parser.d.ts @@ -0,0 +1,129 @@ +import { Constructor } from "./typedjson/types"; +export declare type JsonTypes = Object | boolean | string | number | null | undefined; +export interface ITypedJSONSettings { + /** + * Sets the handler callback to invoke on errors during serializing and deserializing. + * Re-throwing errors in this function will halt serialization/deserialization. + * The default behavior is to log errors to the console. + */ + errorHandler?: (e: Error) => void; + /** + * Sets a callback that determines the constructor of the correct sub-type of polymorphic + * objects while deserializing. + * The default behavior is to read the type-name from the '__type' property of 'sourceObject', + * and look it up in 'knownTypes'. + * The constructor of the sub-type should be returned. + */ + typeResolver?: (sourceObject: Object, knownTypes: Map) => Function; + nameResolver?: (ctor: Function) => string; + /** + * Sets a callback that writes type-hints to serialized objects. + * The default behavior is to write the type-name to the '__type' property, if a derived type + * is present in place of a base type. + */ + typeHintEmitter?: (targetObject: Object, sourceObject: Object, expectedSourceType: Function) => void; + /** + * Sets the amount of indentation to use in produced JSON strings. + * Default value is 0, or no indentation. + */ + indent?: number; + replacer?: (key: string, value: any) => any; + knownTypes?: Array>; +} +export declare class TypedJSON { + static parse(object: any, rootType: Constructor, settings?: ITypedJSONSettings): T | undefined; + static parseAsArray(object: any, elementType: Constructor, settings?: ITypedJSONSettings, dimensions?: 1): T[]; + static parseAsArray(object: any, elementType: Constructor, settings: ITypedJSONSettings | undefined, dimensions: 2): T[][]; + static parseAsArray(object: any, elementType: Constructor, settings: ITypedJSONSettings | undefined, dimensions: 3): T[][][]; + static parseAsArray(object: any, elementType: Constructor, settings: ITypedJSONSettings | undefined, dimensions: 4): T[][][][]; + static parseAsArray(object: any, elementType: Constructor, settings: ITypedJSONSettings | undefined, dimensions: 5): T[][][][][]; + static parseAsSet(object: any, elementType: Constructor, settings?: ITypedJSONSettings): Set; + static parseAsMap(object: any, keyType: Constructor, valueType: Constructor, settings?: ITypedJSONSettings): Map; + static toPlainJson(object: T, rootType: Constructor, settings?: ITypedJSONSettings): JsonTypes; + static toPlainArray(object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings): Object[]; + static toPlainArray(object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings): Object[][]; + static toPlainArray(object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings): Object[][][]; + static toPlainArray(object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings): Object[][][][]; + static toPlainArray(object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings): Object[][][][][]; + static toPlainArray(object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings): any[]; + static toPlainSet(object: Set, elementType: Constructor, settings?: ITypedJSONSettings): string; + static toPlainMap(object: Map, keyCtor: Constructor, valueCtor: Constructor, settings?: ITypedJSONSettings): string; + static stringify(object: T, rootType: Constructor, settings?: ITypedJSONSettings): string; + static stringifyAsArray(object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings): string; + static stringifyAsArray(object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings): string; + static stringifyAsArray(object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings): string; + static stringifyAsArray(object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings): string; + static stringifyAsArray(object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings): string; + static stringifyAsArray(object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings): string; + static stringifyAsSet(object: Set, elementType: Constructor, settings?: ITypedJSONSettings): string; + static stringifyAsMap(object: Map, keyCtor: Constructor, valueCtor: Constructor, settings?: ITypedJSONSettings): string; + private static _globalConfig; + static setGlobalConfig(config: ITypedJSONSettings): void; + private serializer; + private deserializer; + private globalKnownTypes; + private indent; + private rootConstructor; + private errorHandler; + private nameResolver; + private replacer?; + /** + * Creates a new TypedJSON instance to serialize (stringify) and deserialize (parse) object + * instances of the specified root class type. + * @param rootType The constructor of the root class type. + * @param settings Additional configuration settings. + */ + constructor(rootConstructor: Constructor, settings?: ITypedJSONSettings); + /** + * Configures TypedJSON through a settings object. + * @param settings The configuration settings object. + */ + config(settings: ITypedJSONSettings): void; + /** + * Converts a JSON string to the root class type. + * @param object The JSON to parse and convert. + * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown). + * @returns Deserialized T or undefined if there were errors. + */ + parse(object: any): T | undefined; + parseAsArray(object: any, dimensions?: 1): T[]; + parseAsArray(object: any, dimensions: 2): T[][]; + parseAsArray(object: any, dimensions: 3): T[][][]; + parseAsArray(object: any, dimensions: 4): T[][][][]; + parseAsArray(object: any, dimensions: 5): T[][][][][]; + parseAsArray(object: any, dimensions: number): any[]; + parseAsSet(object: any): Set; + parseAsMap(object: any, keyConstructor: Constructor): Map; + /** + * Converts an instance of the specified class type to a plain JSON object. + * @param object The instance to convert to a JSON string. + * @returns Serialized object or undefined if an error has occured. + */ + toPlainJson(object: T): JsonTypes; + toPlainArray(object: T[], dimensions?: 1): Object[]; + toPlainArray(object: T[][], dimensions: 2): Object[][]; + toPlainArray(object: T[][][], dimensions: 3): Object[][][]; + toPlainArray(object: T[][][][], dimensions: 4): Object[][][][]; + toPlainArray(object: T[][][][][], dimensions: 5): Object[][][][][]; + toPlainSet(object: Set): Object[] | undefined; + toPlainMap(object: Map, keyConstructor: Constructor): { + key: any; + value: any; + }[] | undefined; + /** + * Converts an instance of the specified class type to a JSON string. + * @param object The instance to convert to a JSON string. + * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown). + * @returns String with the serialized object or an empty string if an error has occured, but + * the errorHandler did not throw. + */ + stringify(object: T): string; + stringifyAsArray(object: T[], dimensions?: 1): string; + stringifyAsArray(object: T[][], dimensions: 2): string; + stringifyAsArray(object: T[][][], dimensions: 3): string; + stringifyAsArray(object: T[][][][], dimensions: 4): string; + stringifyAsArray(object: T[][][][][], dimensions: 5): string; + stringifyAsSet(object: Set): string; + stringifyAsMap(object: Map, keyConstructor: Constructor): string; + private _mapKnownTypes; +} diff --git a/js/typedjson.d.ts b/js/typedjson.d.ts index 6a7daf6..3a20c19 100644 --- a/js/typedjson.d.ts +++ b/js/typedjson.d.ts @@ -1,132 +1,4 @@ -import { Constructor } from "./typedjson/types"; -export declare type JsonTypes = Object | boolean | string | number | null | undefined; -export interface ITypedJSONSettings { - /** - * Sets the handler callback to invoke on errors during serializing and deserializing. - * Re-throwing errors in this function will halt serialization/deserialization. - * The default behavior is to log errors to the console. - */ - errorHandler?: (e: Error) => void; - /** - * Sets a callback that determines the constructor of the correct sub-type of polymorphic - * objects while deserializing. - * The default behavior is to read the type-name from the '__type' property of 'sourceObject', - * and look it up in 'knownTypes'. - * The constructor of the sub-type should be returned. - */ - typeResolver?: (sourceObject: Object, knownTypes: Map) => Function; - nameResolver?: (ctor: Function) => string; - /** - * Sets a callback that writes type-hints to serialized objects. - * The default behavior is to write the type-name to the '__type' property, if a derived type - * is present in place of a base type. - */ - typeHintEmitter?: (targetObject: Object, sourceObject: Object, expectedSourceType: Function) => void; - /** - * Sets the amount of indentation to use in produced JSON strings. - * Default value is 0, or no indentation. - */ - indent?: number; - replacer?: (key: string, value: any) => any; - knownTypes?: Array>; -} -export declare class TypedJSON { - static parse(object: any, rootType: Constructor, settings?: ITypedJSONSettings): T | undefined; - static parseAsArray(object: any, elementType: Constructor, settings?: ITypedJSONSettings, dimensions?: 1): T[]; - static parseAsArray(object: any, elementType: Constructor, settings: ITypedJSONSettings | undefined, dimensions: 2): T[][]; - static parseAsArray(object: any, elementType: Constructor, settings: ITypedJSONSettings | undefined, dimensions: 3): T[][][]; - static parseAsArray(object: any, elementType: Constructor, settings: ITypedJSONSettings | undefined, dimensions: 4): T[][][][]; - static parseAsArray(object: any, elementType: Constructor, settings: ITypedJSONSettings | undefined, dimensions: 5): T[][][][][]; - static parseAsSet(object: any, elementType: Constructor, settings?: ITypedJSONSettings): Set; - static parseAsMap(object: any, keyType: Constructor, valueType: Constructor, settings?: ITypedJSONSettings): Map; - static toPlainJson(object: T, rootType: Constructor, settings?: ITypedJSONSettings): JsonTypes; - static toPlainArray(object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings): Object[]; - static toPlainArray(object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings): Object[][]; - static toPlainArray(object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings): Object[][][]; - static toPlainArray(object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings): Object[][][][]; - static toPlainArray(object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings): Object[][][][][]; - static toPlainArray(object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings): any[]; - static toPlainSet(object: Set, elementType: Constructor, settings?: ITypedJSONSettings): string; - static toPlainMap(object: Map, keyCtor: Constructor, valueCtor: Constructor, settings?: ITypedJSONSettings): string; - static stringify(object: T, rootType: Constructor, settings?: ITypedJSONSettings): string; - static stringifyAsArray(object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings): string; - static stringifyAsArray(object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings): string; - static stringifyAsArray(object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings): string; - static stringifyAsArray(object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings): string; - static stringifyAsArray(object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings): string; - static stringifyAsArray(object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings): string; - static stringifyAsSet(object: Set, elementType: Constructor, settings?: ITypedJSONSettings): string; - static stringifyAsMap(object: Map, keyCtor: Constructor, valueCtor: Constructor, settings?: ITypedJSONSettings): string; - private static _globalConfig; - static setGlobalConfig(config: ITypedJSONSettings): void; - private serializer; - private deserializer; - private globalKnownTypes; - private indent; - private rootConstructor; - private errorHandler; - private nameResolver; - private replacer?; - /** - * Creates a new TypedJSON instance to serialize (stringify) and deserialize (parse) object - * instances of the specified root class type. - * @param rootType The constructor of the root class type. - * @param settings Additional configuration settings. - */ - constructor(rootConstructor: Constructor, settings?: ITypedJSONSettings); - /** - * Configures TypedJSON through a settings object. - * @param settings The configuration settings object. - */ - config(settings: ITypedJSONSettings): void; - /** - * Converts a JSON string to the root class type. - * @param object The JSON to parse and convert. - * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown). - * @returns Deserialized T or undefined if there were errors. - */ - parse(object: any): T | undefined; - parseAsArray(object: any, dimensions?: 1): T[]; - parseAsArray(object: any, dimensions: 2): T[][]; - parseAsArray(object: any, dimensions: 3): T[][][]; - parseAsArray(object: any, dimensions: 4): T[][][][]; - parseAsArray(object: any, dimensions: 5): T[][][][][]; - parseAsArray(object: any, dimensions: number): any[]; - parseAsSet(object: any): Set; - parseAsMap(object: any, keyConstructor: Constructor): Map; - /** - * Converts an instance of the specified class type to a plain JSON object. - * @param object The instance to convert to a JSON string. - * @returns Serialized object or undefined if an error has occured. - */ - toPlainJson(object: T): JsonTypes; - toPlainArray(object: T[], dimensions?: 1): Object[]; - toPlainArray(object: T[][], dimensions: 2): Object[][]; - toPlainArray(object: T[][][], dimensions: 3): Object[][][]; - toPlainArray(object: T[][][][], dimensions: 4): Object[][][][]; - toPlainArray(object: T[][][][][], dimensions: 5): Object[][][][][]; - toPlainSet(object: Set): Object[] | undefined; - toPlainMap(object: Map, keyConstructor: Constructor): { - key: any; - value: any; - }[] | undefined; - /** - * Converts an instance of the specified class type to a JSON string. - * @param object The instance to convert to a JSON string. - * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown). - * @returns String with the serialized object or an empty string if an error has occured, but - * the errorHandler did not throw. - */ - stringify(object: T): string; - stringifyAsArray(object: T[], dimensions?: 1): string; - stringifyAsArray(object: T[][], dimensions: 2): string; - stringifyAsArray(object: T[][][], dimensions: 3): string; - stringifyAsArray(object: T[][][][], dimensions: 4): string; - stringifyAsArray(object: T[][][][][], dimensions: 5): string; - stringifyAsSet(object: Set): string; - stringifyAsMap(object: Map, keyConstructor: Constructor): string; - private _mapKnownTypes; -} +export { TypedJSON, ITypedJSONSettings, JsonTypes } from "./parser"; export { jsonObject } from "./typedjson/json-object"; export { jsonMember } from "./typedjson/json-member"; export { jsonArrayMember } from "./typedjson/json-array-member"; diff --git a/js/typedjson.js b/js/typedjson.js index 5e00eaa..a64259a 100644 --- a/js/typedjson.js +++ b/js/typedjson.js @@ -1,4 +1,4 @@ -// [typedjson] Version: 1.2.3 - 2019-03-13 +// [typedjson] Version: 1.2.3 - 2019-03-14 (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); @@ -357,985 +357,694 @@ function injectMetadataInformation(constructor, propKey, metadata) { objectMetadata.dataMembers.set(metadata.name, metadata); } -// CONCATENATED MODULE: ./src/typedjson/deserializer.ts +// CONCATENATED MODULE: ./src/typedjson/serializer.ts +var __assign = (undefined && undefined.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +function isArrayTypeInfo(typeInfo) { + return typeInfo.selfType === Array; +} +function isSetTypeInfo(typeInfo) { + return typeInfo.selfType === Set; +} +function isMapTypeInfo(typeInfo) { + return typeInfo.selfType === Map; +} /** - * Utility class, converts a simple/untyped javascript object-tree to a typed object-tree. - * It is used after parsing a JSON-string. + * Utility class, converts a typed object tree (i.e. a tree of class instances, arrays of class instances, and so on) to an untyped javascript object (also + * called "simple javascript object"), and emits any necessary type hints in the process (for polymorphism). + * + * The converted object tree is what will be given to `JSON.stringify` to convert to string as the last step, the serialization is basically like: + * + * (1) typed object-tree -> (2) simple JS object-tree -> (3) JSON-string */ -var deserializer_Deserializer = /** @class */ (function () { - function Deserializer() { - this._typeResolver = function (sourceObject, knownTypes) { - if (sourceObject.__type) - return knownTypes.get(sourceObject.__type); +var serializer_Serializer = /** @class */ (function () { + function Serializer() { + this._typeHintEmitter = function (targetObject, sourceObject, expectedSourceType, sourceTypeMetadata) { + // By default, we put a "__type" property on the output object if the actual object is not the same as the expected one, so that deserialization + // will know what to deserialize into (given the required known-types are defined, and the object is a valid subtype of the expected type). + if (sourceObject.constructor !== expectedSourceType) { + var name_1 = sourceTypeMetadata && sourceTypeMetadata.name + ? sourceTypeMetadata.name + : nameof(sourceObject.constructor); + // TODO: Perhaps this can work correctly without string-literal access? + // tslint:disable-next-line:no-string-literal + targetObject["__type"] = name_1; + } }; this._errorHandler = function (error) { return logError(error); }; } - Deserializer.prototype.setNameResolver = function (nameResolverCallback) { - this._nameResolver = nameResolverCallback; - }; - Deserializer.prototype.setTypeResolver = function (typeResolverCallback) { - if (typeof typeResolverCallback !== "function") - throw new TypeError("'typeResolverCallback' is not a function."); - this._typeResolver = typeResolverCallback; + Serializer.prototype.setTypeHintEmitter = function (typeEmitterCallback) { + if (typeof typeEmitterCallback !== "function") { + throw new TypeError("'typeEmitterCallback' is not a function."); + } + this._typeHintEmitter = typeEmitterCallback; }; - Deserializer.prototype.setErrorHandler = function (errorHandlerCallback) { + Serializer.prototype.setErrorHandler = function (errorHandlerCallback) { if (typeof errorHandlerCallback !== "function") { throw new TypeError("'errorHandlerCallback' is not a function."); } this._errorHandler = errorHandlerCallback; }; - Deserializer.prototype.convertAsObject = function (sourceObject, sourceObjectTypeInfo, objectName) { - var _this = this; - if (objectName === void 0) { objectName = "object"; } - if (typeof sourceObject !== "object" || sourceObject === null) { - this._errorHandler(new TypeError("Cannot deserialize " + objectName + ": 'sourceObject' must be a defined object.")); - return undefined; + /** + * Convert a value of any supported serializable type. + * The value type will be detected, and the correct serialization method will be called. + */ + Serializer.prototype.convertSingleValue = function (sourceObject, typeInfo, memberName) { + if (memberName === void 0) { memberName = "object"; } + if (!isValueDefined(sourceObject)) + return; + if (!isInstanceOf(sourceObject, typeInfo.selfType)) { + var expectedName = nameof(typeInfo.selfType); + var actualName = nameof(sourceObject.constructor); + this._errorHandler(new TypeError("Could not serialize '" + memberName + "': expected '" + expectedName + "', got '" + actualName + "'.")); + return; } - var expectedSelfType = sourceObjectTypeInfo.selfConstructor; - var sourceObjectMetadata = metadata_JsonObjectMetadata.getFromConstructor(expectedSelfType); - var knownTypeConstructors = sourceObjectTypeInfo.knownTypes; - if (sourceObjectMetadata) { - // Merge known types received from "above" with known types defined on the current type. - knownTypeConstructors = this._mergeKnownTypes(knownTypeConstructors, this._createKnownTypesMap(sourceObjectMetadata.knownTypes)); + if (isDirectlySerializableNativeType(typeInfo.selfType)) { + return sourceObject; } - // Check if a type-hint is available from the source object. - var typeFromTypeHint = this._typeResolver(sourceObject, knownTypeConstructors); - if (typeFromTypeHint) { - // Check if type hint is a valid subtype of the expected source type. - if (isSubtypeOf(typeFromTypeHint, expectedSelfType)) { - // Hell yes. - expectedSelfType = typeFromTypeHint; - sourceObjectMetadata = metadata_JsonObjectMetadata.getFromConstructor(typeFromTypeHint); - if (sourceObjectMetadata) { - // Also merge new known types from subtype. - knownTypeConstructors = this._mergeKnownTypes(knownTypeConstructors, this._createKnownTypesMap(sourceObjectMetadata.knownTypes)); - } - } + else if (typeInfo.selfType === ArrayBuffer) { + return this.convertAsArrayBuffer(sourceObject); } - if (sourceObjectMetadata && sourceObjectMetadata.isExplicitlyMarked) { - var sourceMetadata_1 = sourceObjectMetadata; - // Strong-typed deserialization available, get to it. - // First deserialize properties into a temporary object. - var sourceObjectWithDeserializedProperties_1 = {}; - // Deserialize by expected properties. - sourceMetadata_1.dataMembers.forEach(function (memberMetadata, propKey) { - var memberValue = sourceObject[propKey]; - var memberNameForDebug = nameof(sourceMetadata_1.classType) + "." + propKey; - var revivedValue; - if (memberMetadata.deserializer) { - revivedValue = memberMetadata.deserializer(memberValue); + else if (typeInfo.selfType === DataView) { + return this.convertAsDataView(sourceObject); + } + else if (isArrayTypeInfo(typeInfo)) { + return this.convertAsArray(sourceObject, typeInfo.elementTypes, memberName); + } + else if (isSetTypeInfo(typeInfo)) { + return this.convertAsSet(sourceObject, typeInfo.elementTypes[0], memberName); + } + else if (isMapTypeInfo(typeInfo)) { + return this.convertAsMap(sourceObject, typeInfo.keyType, typeInfo.elementTypes[0], memberName); + } + else if (isTypeTypedArray(typeInfo.selfType)) { + return this.convertAsTypedArray(sourceObject); + } + else if (typeof sourceObject === "object") { + return this.convertAsObject(sourceObject, typeInfo, memberName); + } + }; + /** + * Performs the conversion of a typed object (usually a class instance) to a simple javascript object for serialization. + */ + Serializer.prototype.convertAsObject = function (sourceObject, typeInfo, memberName) { + var _this = this; + var sourceTypeMetadata; + var targetObject; + if (sourceObject.constructor !== typeInfo.selfType && sourceObject instanceof typeInfo.selfType) { + // The source object is not of the expected type, but it is a valid subtype. + // This is OK, and we'll proceed to gather object metadata from the subtype instead. + sourceTypeMetadata = metadata_JsonObjectMetadata.getFromConstructor(sourceObject.constructor); + } + else { + sourceTypeMetadata = metadata_JsonObjectMetadata.getFromConstructor(typeInfo.selfType); + } + if (sourceTypeMetadata) { + var sourceMeta_1 = sourceTypeMetadata; + // Strong-typed serialization available. + // We'll serialize by members that have been marked with @jsonMember (including array/set/map members), and perform recursive conversion on + // each of them. The converted objects are put on the 'targetObject', which is what will be put into 'JSON.stringify' finally. + targetObject = {}; + sourceTypeMetadata.dataMembers.forEach(function (memberMetadata) { + if (memberMetadata.serializer) { + targetObject[memberMetadata.name] = + memberMetadata.serializer(sourceObject[memberMetadata.key]); } else if (memberMetadata.ctor) { - revivedValue = _this.convertSingleValue(memberValue, { - selfConstructor: memberMetadata.ctor, - elementConstructor: memberMetadata.elementType, - keyConstructor: memberMetadata.keyType, - knownTypes: knownTypeConstructors - }, memberNameForDebug); + targetObject[memberMetadata.name] = _this.convertSingleValue(sourceObject[memberMetadata.key], { + selfType: memberMetadata.ctor, + elementTypes: memberMetadata.elementType, + keyType: memberMetadata.keyType, + }, nameof(sourceMeta_1.classType) + "." + memberMetadata.key); } else { - throw new TypeError("Cannot deserialize " + memberNameForDebug + " thers is" - + " no constructor nor deserlization function to use."); - } - if (isValueDefined(revivedValue)) { - sourceObjectWithDeserializedProperties_1[memberMetadata.key] = revivedValue; - } - else if (memberMetadata.isRequired) { - _this._errorHandler(new TypeError("Missing required member '" + memberNameForDebug + "'.")); + throw new TypeError("Could not serialize " + memberMetadata.name + ", there is" + + " no constructor nor serialization function to use."); } }); - // Next, instantiate target object. - var targetObject = void 0; - if (typeof sourceObjectMetadata.initializerCallback === "function") { - try { - targetObject = sourceObjectMetadata.initializerCallback(sourceObjectWithDeserializedProperties_1, sourceObject); - // Check the validity of user-defined initializer callback. - if (!targetObject) { - throw new TypeError("Cannot deserialize " + objectName + ":" - + " 'initializer' function returned undefined/null" - + (", but '" + nameof(sourceObjectMetadata.classType) + "' was expected.")); - } - else if (!(targetObject instanceof sourceObjectMetadata.classType)) { - throw new TypeError("Cannot deserialize " + objectName + ":" - + ("'initializer' returned '" + nameof(targetObject.constructor) + "'") - + (", but '" + nameof(sourceObjectMetadata.classType) + "' was expected,") - + ("and '" + nameof(targetObject.constructor) + "' is not a subtype of") - + (" '" + nameof(sourceObjectMetadata.classType) + "'")); - } - } - catch (e) { - this._errorHandler(e); - return undefined; - } - } - else { - targetObject = this._instantiateType(expectedSelfType); - } - // Finally, assign deserialized properties to target object. - Object.assign(targetObject, sourceObjectWithDeserializedProperties_1); - // Call onDeserialized method (if any). - if (sourceObjectMetadata.onDeserializedMethodName) { - if (typeof targetObject.constructor[sourceObjectMetadata.onDeserializedMethodName] === "function") { - targetObject.constructor[sourceObjectMetadata.onDeserializedMethodName](); - } - else { - this._errorHandler(new TypeError("onDeserialized callback '" + nameof(sourceObjectMetadata.classType) + "." + sourceObjectMetadata.onDeserializedMethodName + "' is not a method.")); - } - } - return targetObject; } else { - // Untyped deserialization into Object instance. - var targetObject_1 = {}; - Object.keys(sourceObject).forEach(function (sourceKey) { - targetObject_1[sourceKey] = _this.convertSingleValue(sourceObject[sourceKey], { - selfConstructor: sourceObject[sourceKey].constructor, - knownTypes: sourceObjectTypeInfo.knownTypes, - elementConstructor: sourceObjectTypeInfo.elementConstructor, - keyConstructor: sourceObjectTypeInfo.keyConstructor - }, sourceKey); - }); - return targetObject_1; + // Untyped serialization, "as-is", we'll just pass the object on. + // We'll clone the source object, because type hints are added to the object itself, and we don't want to modify to the original object. + targetObject = __assign({}, sourceObject); } + // Add type-hint. + this._typeHintEmitter(targetObject, sourceObject, typeInfo.selfType, sourceTypeMetadata); + return targetObject; }; - Deserializer.prototype.convertSingleValue = function (sourceObject, typeInfo, memberName) { + /** + * Performs the conversion of an array of typed objects (or primitive values) to an array of simple javascript objects (or primitive values) for + * serialization. + * @param expectedElementType The expected type of elements. If the array is supposed to be multi-dimensional, subsequent elements define lower dimensions. + * @param memberName Name of the object being serialized, used for debugging purposes. + */ + Serializer.prototype.convertAsArray = function (sourceObject, expectedElementType, memberName) { + var _this = this; if (memberName === void 0) { memberName = "object"; } - var expectedSelfType = typeInfo.selfConstructor; - var srcTypeNameForDebug = sourceObject ? nameof(sourceObject.constructor) : "undefined"; - if (!isValueDefined(sourceObject)) { - return sourceObject; - } - else if (this._isDirectlyDeserializableNativeType(expectedSelfType)) { - if (sourceObject.constructor === expectedSelfType) { - return sourceObject; - } - else { - throw new TypeError(this._makeTypeErrorMessage(nameof(expectedSelfType), sourceObject.constructor, memberName)); + if (expectedElementType.length === 0 || !expectedElementType[0]) + throw new TypeError("Could not serialize " + memberName + " as Array: missing element type definition."); + // Check the type of each element, individually. + // If at least one array element type is incorrect, we return undefined, which results in no value emitted during serialization. + // This is so that invalid element types don't unexpectedly alter the ordering of other, valid elements, and that no unexpected undefined values are in + // the emitted array. + sourceObject.forEach(function (element, i) { + if (!isInstanceOf(element, expectedElementType[0])) { + var expectedTypeName = nameof(expectedElementType[0]); + var actualTypeName = nameof(element.constructor); + throw new TypeError("Could not serialize " + memberName + "[" + i + "]: expected '" + expectedTypeName + "', got '" + actualTypeName + "'."); } + }); + var typeInfoForElements = { + selfType: expectedElementType[0], + elementTypes: expectedElementType.length > 1 ? expectedElementType.slice(1) : [], + }; + if (memberName) { + // Just for debugging purposes. + memberName += "[]"; } - else if (expectedSelfType === Date) { - // Support for Date with ISO 8601 format, or with numeric timestamp (milliseconds elapsed since the Epoch). - // ISO 8601 spec.: https://www.w3.org/TR/NOTE-datetime - if (typeof sourceObject === "string" || (typeof sourceObject === "number" && sourceObject > 0)) - return new Date(sourceObject); - else - this._throwTypeMismatchError("Date", "an ISO-8601 string", srcTypeNameForDebug, memberName); - } - else if (expectedSelfType === Float32Array) { - // Deserialize Float32Array from number[]. - if (sourceObject instanceof Array && sourceObject.every(function (elem) { return !isNaN(elem); })) - return new Float32Array(sourceObject); - else - this._throwTypeMismatchError("Float32Array", "a numeric source array", srcTypeNameForDebug, memberName); - } - else if (expectedSelfType === Float64Array) { - // Deserialize Float64Array from number[]. - if (sourceObject instanceof Array && sourceObject.every(function (elem) { return !isNaN(elem); })) - return new Float64Array(sourceObject); - else - this._throwTypeMismatchError("Float64Array", "a numeric source array", srcTypeNameForDebug, memberName); - } - else if (expectedSelfType === Uint8Array) { - // Deserialize Uint8Array from number[]. - if (sourceObject instanceof Array && sourceObject.every(function (elem) { return !isNaN(elem); })) - return new Uint8Array(sourceObject.map(function (value) { return ~~value; })); - else - this._throwTypeMismatchError("Uint8Array", "a numeric source array", srcTypeNameForDebug, memberName); - } - else if (expectedSelfType === Uint8ClampedArray) { - // Deserialize Uint8Array from number[]. - if (sourceObject instanceof Array && sourceObject.every(function (elem) { return !isNaN(elem); })) - return new Uint8ClampedArray(sourceObject.map(function (value) { return ~~value; })); - else - this._throwTypeMismatchError("Uint8ClampedArray", "a numeric source array", srcTypeNameForDebug, memberName); - } - else if (expectedSelfType === Uint16Array) { - // Deserialize Uint16Array from number[]. - if (sourceObject instanceof Array && sourceObject.every(function (elem) { return !isNaN(elem); })) - return new Uint16Array(sourceObject.map(function (value) { return ~~value; })); - else - this._throwTypeMismatchError("Uint16Array", "a numeric source array", srcTypeNameForDebug, memberName); - } - else if (expectedSelfType === Uint32Array) { - // Deserialize Uint32Array from number[]. - if (sourceObject instanceof Array && sourceObject.every(function (elem) { return !isNaN(elem); })) - return new Uint32Array(sourceObject.map(function (value) { return ~~value; })); - else - this._throwTypeMismatchError("Uint32Array", "a numeric source array", srcTypeNameForDebug, memberName); - } - else if (expectedSelfType === ArrayBuffer) { - if (typeof sourceObject === "string") - return this._stringToArrayBuffer(sourceObject); - else - this._throwTypeMismatchError("ArrayBuffer", "a string source", srcTypeNameForDebug, memberName); - } - else if (expectedSelfType === DataView) { - if (typeof sourceObject === "string") - return this._stringToDataView(sourceObject); - else - this._throwTypeMismatchError("DataView", "a string source", srcTypeNameForDebug, memberName); - } - else if (expectedSelfType === Array) { - if (sourceObject instanceof Array) - return this.convertAsArray(sourceObject, typeInfo, memberName); - else - throw new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)); - } - else if (expectedSelfType === Set) { - if (sourceObject instanceof Array) - return this.convertAsSet(sourceObject, typeInfo, memberName); - else - this._throwTypeMismatchError("Set", "Array", srcTypeNameForDebug, memberName); - } - else if (expectedSelfType === Map) { - if (sourceObject instanceof Array) - return this.convertAsMap(sourceObject, typeInfo, memberName); - else - this._throwTypeMismatchError("Map", "a source array of key-value-pair objects", srcTypeNameForDebug, memberName); - } - else if (sourceObject && typeof sourceObject === "object") { - return this.convertAsObject(sourceObject, typeInfo, memberName); - } + return sourceObject.map(function (element) { return _this.convertSingleValue(element, typeInfoForElements, memberName); }); }; - Deserializer.prototype.convertAsArray = function (sourceObject, typeInfo, memberName) { + /** + * Performs the conversion of a set of typed objects (or primitive values) into an array of simple javascript objects. + * + * @param sourceObject + * @param expectedElementType The constructor of the expected Set elements (e.g. `Number` for `Set`, or `MyClass` for `Set`). + * @param memberName Name of the object being serialized, used for debugging purposes. + * @returns + */ + Serializer.prototype.convertAsSet = function (sourceObject, expectedElementType, memberName) { var _this = this; if (memberName === void 0) { memberName = "object"; } - if (!(sourceObject instanceof Array)) { - this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName))); - return []; - } - if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length) { - this._errorHandler(new TypeError("Could not deserialize " + memberName + " as Array: missing constructor reference of Array elements.")); - return []; - } + if (!expectedElementType) + throw new TypeError("Could not serialize " + memberName + " as Set: missing element type definition."); var elementTypeInfo = { - selfConstructor: typeInfo.elementConstructor[0], - elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [], - knownTypes: typeInfo.knownTypes + selfType: expectedElementType, }; - return sourceObject.map(function (element) { - // If an array element fails to deserialize, substitute with undefined. This is so that the original ordering is not interrupted by faulty - // entries, as an Array is ordered. - try { - return _this.convertSingleValue(element, elementTypeInfo); - } - catch (e) { - _this._errorHandler(e); - // Keep filling the array here with undefined to keep original ordering. - // Note: this is just aesthetics, not returning anything produces the same result. - return undefined; + // For debugging and error tracking. + if (memberName) + memberName += "[]"; + var resultArray = []; + // Convert each element of the set, and put it into an output array. + // The output array is the one serialized, as JSON.stringify does not support Set serialization. (TODO: clarification needed) + sourceObject.forEach(function (element) { + var resultElement = _this.convertSingleValue(element, elementTypeInfo, memberName); + // Add to output if the source element was undefined, OR the converted element is defined. This will add intentionally undefined values to output, + // but not values that became undefined DURING serializing (usually because of a type-error). + if (!isValueDefined(element) || isValueDefined(resultElement)) { + resultArray.push(resultElement); } }); + return resultArray; }; - Deserializer.prototype.convertAsSet = function (sourceObject, typeInfo, memberName) { + /** + * Performs the conversion of a map of typed objects (or primitive values) into an array of simple javascript objects with `key` and `value` properties. + * + * @param sourceObject + * @param expectedKeyType The constructor of the expected Map keys (e.g. `Number` for `Map`, or `MyClass` for `Map`). + * @param expectedElementType The constructor of the expected Map values (e.g. `Number` for `Map`, or `MyClass` for `Map`). + * @param memberName Name of the object being serialized, used for debugging purposes. + */ + Serializer.prototype.convertAsMap = function (sourceObject, expectedKeyType, expectedElementType, memberName) { var _this = this; if (memberName === void 0) { memberName = "object"; } - if (!(sourceObject instanceof Array)) { - this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName))); - return new Set(); - } - if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length) { - this._errorHandler(new TypeError("Could not deserialize " + memberName + " as Set: missing constructor reference of Set elements.")); - return new Set(); - } + if (!expectedElementType) + throw new TypeError("Could not serialize " + memberName + " as Map: missing value type definition."); + if (!expectedKeyType) + throw new TypeError("Could not serialize " + memberName + " as Map: missing key type definition."); var elementTypeInfo = { - selfConstructor: typeInfo.elementConstructor[0], - elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [], - knownTypes: typeInfo.knownTypes + selfType: expectedElementType, + elementTypes: [expectedElementType] }; - var resultSet = new Set(); - sourceObject.forEach(function (element, i) { - try { - resultSet.add(_this.convertSingleValue(element, elementTypeInfo, memberName + ("[" + i + "]"))); - } - catch (e) { - // Faulty entries are skipped, because a Set is not ordered, and skipping an entry does not affect others. - _this._errorHandler(e); - } - }); - return resultSet; - }; - Deserializer.prototype.convertAsMap = function (sourceObject, typeInfo, memberName) { - var _this = this; - if (memberName === void 0) { memberName = "object"; } - if (!(sourceObject instanceof Array)) - this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName))); - if (!typeInfo.keyConstructor) { - this._errorHandler(new TypeError("Could not deserialize " + memberName + " as Map: missing key constructor.")); - return new Map(); - } - if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length) { - this._errorHandler(new TypeError("Could not deserialize " + memberName + " as Map: missing value constructor.")); - return new Map(); - } var keyTypeInfo = { - selfConstructor: typeInfo.keyConstructor, - knownTypes: typeInfo.knownTypes - }; - var valueTypeInfo = { - selfConstructor: typeInfo.elementConstructor[0], - elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [], - knownTypes: typeInfo.knownTypes + selfType: expectedKeyType }; - var resultMap = new Map(); - sourceObject.forEach(function (element) { - try { - var key = _this.convertSingleValue(element.key, keyTypeInfo); - // Undefined/null keys not supported, skip if so. - if (isValueDefined(key)) { - resultMap.set(key, _this.convertSingleValue(element.value, valueTypeInfo, memberName + "[" + key + "]")); - } - } - catch (e) { - // Faulty entries are skipped, because a Map is not ordered, - // and skipping an entry does not affect others. - _this._errorHandler(e); + if (memberName) + memberName += "[]"; + var resultArray = []; + // Convert each *entry* in the map to a simple javascript object with key and value properties. + sourceObject.forEach(function (value, key) { + var resultKeyValuePairObj = { + key: _this.convertSingleValue(key, keyTypeInfo, memberName), + value: _this.convertSingleValue(value, elementTypeInfo, memberName) + }; + // We are not going to emit entries with undefined keys OR undefined values. + if (isValueDefined(resultKeyValuePairObj.key) && isValueDefined(resultKeyValuePairObj.value)) { + resultArray.push(resultKeyValuePairObj); } }); - return resultMap; + return resultArray; }; - Deserializer.prototype._throwTypeMismatchError = function (targetType, expectedSourceType, actualSourceType, memberName) { - if (memberName === void 0) { memberName = "object"; } - throw new TypeError("Could not deserialize " + memberName + " as " + targetType + ":" - + (" expected " + expectedSourceType + ", got " + actualSourceType + ".")); + /** + * Performs the conversion of a typed javascript array to a simple untyped javascript array. + * This is needed because typed arrays are otherwise serialized as objects, so we'll end up with something like "{ 0: 0, 1: 1, ... }". + * + * @param sourceObject + * @returns + */ + Serializer.prototype.convertAsTypedArray = function (sourceObject) { + return Array.from(sourceObject); }; - Deserializer.prototype._makeTypeErrorMessage = function (expectedType, actualType, memberName) { - if (memberName === void 0) { memberName = "object"; } - var expectedTypeName = (typeof expectedType === "function") ? nameof(expectedType) : expectedType; - var actualTypeName = (typeof actualType === "function") ? nameof(actualType) : actualType; - return "Could not deserialize " + memberName + ": expected '" + expectedTypeName + "', got '" + actualTypeName + "'."; - }; - Deserializer.prototype._instantiateType = function (ctor) { - return new ctor(); - }; - Deserializer.prototype._mergeKnownTypes = function () { - var _this = this; - var knownTypeMaps = []; - for (var _i = 0; _i < arguments.length; _i++) { - knownTypeMaps[_i] = arguments[_i]; - } - var result = new Map(); - knownTypeMaps.forEach(function (knownTypes) { - knownTypes.forEach(function (ctor, name) { - if (_this._nameResolver) { - result.set(_this._nameResolver(ctor), ctor); - } - else { - result.set(name, ctor); - } - }); - }); - return result; - }; - Deserializer.prototype._createKnownTypesMap = function (knowTypes) { - var _this = this; - var map = new Map(); - knowTypes.forEach(function (ctor) { - if (_this._nameResolver) { - map.set(_this._nameResolver(ctor), ctor); - } - else { - var knownTypeMeta = metadata_JsonObjectMetadata.getFromConstructor(ctor); - var name_1 = knownTypeMeta && knownTypeMeta.isExplicitlyMarked && knownTypeMeta.name - ? knownTypeMeta.name - : ctor.name; - map.set(name_1, ctor); - } - }); - return map; - }; - Deserializer.prototype._isDirectlyDeserializableNativeType = function (ctor) { - return ~([Number, String, Boolean].indexOf(ctor)); - }; - Deserializer.prototype.convertNativeObject = function (sourceObject) { - return sourceObject; - }; - Deserializer.prototype._stringToArrayBuffer = function (str) { - var buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char - var bufView = new Uint16Array(buf); - for (var i = 0, strLen = str.length; i < strLen; i++) { - bufView[i] = str.charCodeAt(i); - } - return buf; + /** + * Performs the conversion of a raw ArrayBuffer to a string. + */ + Serializer.prototype.convertAsArrayBuffer = function (buffer) { + // ArrayBuffer -> 16-bit character codes -> character array -> joined string. + return Array.from(new Uint16Array(buffer)).map(function (charCode) { return String.fromCharCode(charCode); }).join(""); }; - Deserializer.prototype._stringToDataView = function (str) { - return new DataView(this._stringToArrayBuffer(str)); + /** + * Performs the conversion of DataView, converting its internal ArrayBuffer to a string and returning that string. + */ + Serializer.prototype.convertAsDataView = function (dataView) { + return this.convertAsArrayBuffer(dataView.buffer); }; - return Deserializer; + return Serializer; }()); -// CONCATENATED MODULE: ./src/typedjson/serializer.ts -var __assign = (undefined && undefined.__assign) || function () { - __assign = Object.assign || function(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) - t[p] = s[p]; - } - return t; - }; - return __assign.apply(this, arguments); -}; +// CONCATENATED MODULE: ./src/typedjson/deserializer.ts -function isArrayTypeInfo(typeInfo) { - return typeInfo.selfType === Array; -} -function isSetTypeInfo(typeInfo) { - return typeInfo.selfType === Set; -} -function isMapTypeInfo(typeInfo) { - return typeInfo.selfType === Map; -} /** - * Utility class, converts a typed object tree (i.e. a tree of class instances, arrays of class instances, and so on) to an untyped javascript object (also - * called "simple javascript object"), and emits any necessary type hints in the process (for polymorphism). - * - * The converted object tree is what will be given to `JSON.stringify` to convert to string as the last step, the serialization is basically like: - * - * (1) typed object-tree -> (2) simple JS object-tree -> (3) JSON-string + * Utility class, converts a simple/untyped javascript object-tree to a typed object-tree. + * It is used after parsing a JSON-string. */ -var serializer_Serializer = /** @class */ (function () { - function Serializer() { - this._typeHintEmitter = function (targetObject, sourceObject, expectedSourceType, sourceTypeMetadata) { - // By default, we put a "__type" property on the output object if the actual object is not the same as the expected one, so that deserialization - // will know what to deserialize into (given the required known-types are defined, and the object is a valid subtype of the expected type). - if (sourceObject.constructor !== expectedSourceType) { - var name_1 = sourceTypeMetadata && sourceTypeMetadata.name - ? sourceTypeMetadata.name - : nameof(sourceObject.constructor); - // TODO: Perhaps this can work correctly without string-literal access? - // tslint:disable-next-line:no-string-literal - targetObject["__type"] = name_1; - } +var deserializer_Deserializer = /** @class */ (function () { + function Deserializer() { + this._typeResolver = function (sourceObject, knownTypes) { + if (sourceObject.__type) + return knownTypes.get(sourceObject.__type); }; this._errorHandler = function (error) { return logError(error); }; } - Serializer.prototype.setTypeHintEmitter = function (typeEmitterCallback) { - if (typeof typeEmitterCallback !== "function") { - throw new TypeError("'typeEmitterCallback' is not a function."); - } - this._typeHintEmitter = typeEmitterCallback; + Deserializer.prototype.setNameResolver = function (nameResolverCallback) { + this._nameResolver = nameResolverCallback; }; - Serializer.prototype.setErrorHandler = function (errorHandlerCallback) { + Deserializer.prototype.setTypeResolver = function (typeResolverCallback) { + if (typeof typeResolverCallback !== "function") + throw new TypeError("'typeResolverCallback' is not a function."); + this._typeResolver = typeResolverCallback; + }; + Deserializer.prototype.setErrorHandler = function (errorHandlerCallback) { if (typeof errorHandlerCallback !== "function") { throw new TypeError("'errorHandlerCallback' is not a function."); } this._errorHandler = errorHandlerCallback; }; - /** - * Convert a value of any supported serializable type. - * The value type will be detected, and the correct serialization method will be called. - */ - Serializer.prototype.convertSingleValue = function (sourceObject, typeInfo, memberName) { - if (memberName === void 0) { memberName = "object"; } - if (!isValueDefined(sourceObject)) - return; - if (!isInstanceOf(sourceObject, typeInfo.selfType)) { - var expectedName = nameof(typeInfo.selfType); - var actualName = nameof(sourceObject.constructor); - this._errorHandler(new TypeError("Could not serialize '" + memberName + "': expected '" + expectedName + "', got '" + actualName + "'.")); - return; - } - if (isDirectlySerializableNativeType(typeInfo.selfType)) { - return sourceObject; - } - else if (typeInfo.selfType === ArrayBuffer) { - return this.convertAsArrayBuffer(sourceObject); - } - else if (typeInfo.selfType === DataView) { - return this.convertAsDataView(sourceObject); - } - else if (isArrayTypeInfo(typeInfo)) { - return this.convertAsArray(sourceObject, typeInfo.elementTypes, memberName); - } - else if (isSetTypeInfo(typeInfo)) { - return this.convertAsSet(sourceObject, typeInfo.elementTypes[0], memberName); - } - else if (isMapTypeInfo(typeInfo)) { - return this.convertAsMap(sourceObject, typeInfo.keyType, typeInfo.elementTypes[0], memberName); - } - else if (isTypeTypedArray(typeInfo.selfType)) { - return this.convertAsTypedArray(sourceObject); - } - else if (typeof sourceObject === "object") { - return this.convertAsObject(sourceObject, typeInfo, memberName); - } - }; - /** - * Performs the conversion of a typed object (usually a class instance) to a simple javascript object for serialization. - */ - Serializer.prototype.convertAsObject = function (sourceObject, typeInfo, memberName) { + Deserializer.prototype.convertAsObject = function (sourceObject, sourceObjectTypeInfo, objectName) { var _this = this; - var sourceTypeMetadata; - var targetObject; - if (sourceObject.constructor !== typeInfo.selfType && sourceObject instanceof typeInfo.selfType) { - // The source object is not of the expected type, but it is a valid subtype. - // This is OK, and we'll proceed to gather object metadata from the subtype instead. - sourceTypeMetadata = metadata_JsonObjectMetadata.getFromConstructor(sourceObject.constructor); + if (objectName === void 0) { objectName = "object"; } + if (typeof sourceObject !== "object" || sourceObject === null) { + this._errorHandler(new TypeError("Cannot deserialize " + objectName + ": 'sourceObject' must be a defined object.")); + return undefined; } - else { - sourceTypeMetadata = metadata_JsonObjectMetadata.getFromConstructor(typeInfo.selfType); + var expectedSelfType = sourceObjectTypeInfo.selfConstructor; + var sourceObjectMetadata = metadata_JsonObjectMetadata.getFromConstructor(expectedSelfType); + var knownTypeConstructors = sourceObjectTypeInfo.knownTypes; + if (sourceObjectMetadata) { + // Merge known types received from "above" with known types defined on the current type. + knownTypeConstructors = this._mergeKnownTypes(knownTypeConstructors, this._createKnownTypesMap(sourceObjectMetadata.knownTypes)); } - if (sourceTypeMetadata) { - var sourceMeta_1 = sourceTypeMetadata; - // Strong-typed serialization available. - // We'll serialize by members that have been marked with @jsonMember (including array/set/map members), and perform recursive conversion on - // each of them. The converted objects are put on the 'targetObject', which is what will be put into 'JSON.stringify' finally. - targetObject = {}; - sourceTypeMetadata.dataMembers.forEach(function (memberMetadata) { - if (memberMetadata.serializer) { - targetObject[memberMetadata.name] = - memberMetadata.serializer(sourceObject[memberMetadata.key]); + // Check if a type-hint is available from the source object. + var typeFromTypeHint = this._typeResolver(sourceObject, knownTypeConstructors); + if (typeFromTypeHint) { + // Check if type hint is a valid subtype of the expected source type. + if (isSubtypeOf(typeFromTypeHint, expectedSelfType)) { + // Hell yes. + expectedSelfType = typeFromTypeHint; + sourceObjectMetadata = metadata_JsonObjectMetadata.getFromConstructor(typeFromTypeHint); + if (sourceObjectMetadata) { + // Also merge new known types from subtype. + knownTypeConstructors = this._mergeKnownTypes(knownTypeConstructors, this._createKnownTypesMap(sourceObjectMetadata.knownTypes)); + } + } + } + if (sourceObjectMetadata && sourceObjectMetadata.isExplicitlyMarked) { + var sourceMetadata_1 = sourceObjectMetadata; + // Strong-typed deserialization available, get to it. + // First deserialize properties into a temporary object. + var sourceObjectWithDeserializedProperties_1 = {}; + // Deserialize by expected properties. + sourceMetadata_1.dataMembers.forEach(function (memberMetadata, propKey) { + var memberValue = sourceObject[propKey]; + var memberNameForDebug = nameof(sourceMetadata_1.classType) + "." + propKey; + var revivedValue; + if (memberMetadata.deserializer) { + revivedValue = memberMetadata.deserializer(memberValue); } else if (memberMetadata.ctor) { - targetObject[memberMetadata.name] = _this.convertSingleValue(sourceObject[memberMetadata.key], { - selfType: memberMetadata.ctor, - elementTypes: memberMetadata.elementType, - keyType: memberMetadata.keyType, - }, nameof(sourceMeta_1.classType) + "." + memberMetadata.key); + revivedValue = _this.convertSingleValue(memberValue, { + selfConstructor: memberMetadata.ctor, + elementConstructor: memberMetadata.elementType, + keyConstructor: memberMetadata.keyType, + knownTypes: knownTypeConstructors + }, memberNameForDebug); } else { - throw new TypeError("Could not serialize " + memberMetadata.name + ", there is" - + " no constructor nor serialization function to use."); + throw new TypeError("Cannot deserialize " + memberNameForDebug + " thers is" + + " no constructor nor deserlization function to use."); + } + if (isValueDefined(revivedValue)) { + sourceObjectWithDeserializedProperties_1[memberMetadata.key] = revivedValue; + } + else if (memberMetadata.isRequired) { + _this._errorHandler(new TypeError("Missing required member '" + memberNameForDebug + "'.")); } }); - } - else { - // Untyped serialization, "as-is", we'll just pass the object on. - // We'll clone the source object, because type hints are added to the object itself, and we don't want to modify to the original object. - targetObject = __assign({}, sourceObject); - } - // Add type-hint. - this._typeHintEmitter(targetObject, sourceObject, typeInfo.selfType, sourceTypeMetadata); - return targetObject; + // Next, instantiate target object. + var targetObject = void 0; + if (typeof sourceObjectMetadata.initializerCallback === "function") { + try { + targetObject = sourceObjectMetadata.initializerCallback(sourceObjectWithDeserializedProperties_1, sourceObject); + // Check the validity of user-defined initializer callback. + if (!targetObject) { + throw new TypeError("Cannot deserialize " + objectName + ":" + + " 'initializer' function returned undefined/null" + + (", but '" + nameof(sourceObjectMetadata.classType) + "' was expected.")); + } + else if (!(targetObject instanceof sourceObjectMetadata.classType)) { + throw new TypeError("Cannot deserialize " + objectName + ":" + + ("'initializer' returned '" + nameof(targetObject.constructor) + "'") + + (", but '" + nameof(sourceObjectMetadata.classType) + "' was expected,") + + ("and '" + nameof(targetObject.constructor) + "' is not a subtype of") + + (" '" + nameof(sourceObjectMetadata.classType) + "'")); + } + } + catch (e) { + this._errorHandler(e); + return undefined; + } + } + else { + targetObject = this._instantiateType(expectedSelfType); + } + // Finally, assign deserialized properties to target object. + Object.assign(targetObject, sourceObjectWithDeserializedProperties_1); + // Call onDeserialized method (if any). + if (sourceObjectMetadata.onDeserializedMethodName) { + if (typeof targetObject.constructor[sourceObjectMetadata.onDeserializedMethodName] === "function") { + targetObject.constructor[sourceObjectMetadata.onDeserializedMethodName](); + } + else { + this._errorHandler(new TypeError("onDeserialized callback '" + nameof(sourceObjectMetadata.classType) + "." + sourceObjectMetadata.onDeserializedMethodName + "' is not a method.")); + } + } + return targetObject; + } + else { + // Untyped deserialization into Object instance. + var targetObject_1 = {}; + Object.keys(sourceObject).forEach(function (sourceKey) { + targetObject_1[sourceKey] = _this.convertSingleValue(sourceObject[sourceKey], { + selfConstructor: sourceObject[sourceKey].constructor, + knownTypes: sourceObjectTypeInfo.knownTypes, + elementConstructor: sourceObjectTypeInfo.elementConstructor, + keyConstructor: sourceObjectTypeInfo.keyConstructor + }, sourceKey); + }); + return targetObject_1; + } }; - /** - * Performs the conversion of an array of typed objects (or primitive values) to an array of simple javascript objects (or primitive values) for - * serialization. - * @param expectedElementType The expected type of elements. If the array is supposed to be multi-dimensional, subsequent elements define lower dimensions. - * @param memberName Name of the object being serialized, used for debugging purposes. - */ - Serializer.prototype.convertAsArray = function (sourceObject, expectedElementType, memberName) { - var _this = this; + Deserializer.prototype.convertSingleValue = function (sourceObject, typeInfo, memberName) { if (memberName === void 0) { memberName = "object"; } - if (expectedElementType.length === 0 || !expectedElementType[0]) - throw new TypeError("Could not serialize " + memberName + " as Array: missing element type definition."); - // Check the type of each element, individually. - // If at least one array element type is incorrect, we return undefined, which results in no value emitted during serialization. - // This is so that invalid element types don't unexpectedly alter the ordering of other, valid elements, and that no unexpected undefined values are in - // the emitted array. - sourceObject.forEach(function (element, i) { - if (!isInstanceOf(element, expectedElementType[0])) { - var expectedTypeName = nameof(expectedElementType[0]); - var actualTypeName = nameof(element.constructor); - throw new TypeError("Could not serialize " + memberName + "[" + i + "]: expected '" + expectedTypeName + "', got '" + actualTypeName + "'."); + var expectedSelfType = typeInfo.selfConstructor; + var srcTypeNameForDebug = sourceObject ? nameof(sourceObject.constructor) : "undefined"; + if (!isValueDefined(sourceObject)) { + return sourceObject; + } + else if (this._isDirectlyDeserializableNativeType(expectedSelfType)) { + if (sourceObject.constructor === expectedSelfType) { + return sourceObject; + } + else { + throw new TypeError(this._makeTypeErrorMessage(nameof(expectedSelfType), sourceObject.constructor, memberName)); } - }); - var typeInfoForElements = { - selfType: expectedElementType[0], - elementTypes: expectedElementType.length > 1 ? expectedElementType.slice(1) : [], - }; - if (memberName) { - // Just for debugging purposes. - memberName += "[]"; } - return sourceObject.map(function (element) { return _this.convertSingleValue(element, typeInfoForElements, memberName); }); + else if (expectedSelfType === Date) { + // Support for Date with ISO 8601 format, or with numeric timestamp (milliseconds elapsed since the Epoch). + // ISO 8601 spec.: https://www.w3.org/TR/NOTE-datetime + if (typeof sourceObject === "string" || (typeof sourceObject === "number" && sourceObject > 0)) + return new Date(sourceObject); + else + this._throwTypeMismatchError("Date", "an ISO-8601 string", srcTypeNameForDebug, memberName); + } + else if (expectedSelfType === Float32Array) { + // Deserialize Float32Array from number[]. + if (sourceObject instanceof Array && sourceObject.every(function (elem) { return !isNaN(elem); })) + return new Float32Array(sourceObject); + else + this._throwTypeMismatchError("Float32Array", "a numeric source array", srcTypeNameForDebug, memberName); + } + else if (expectedSelfType === Float64Array) { + // Deserialize Float64Array from number[]. + if (sourceObject instanceof Array && sourceObject.every(function (elem) { return !isNaN(elem); })) + return new Float64Array(sourceObject); + else + this._throwTypeMismatchError("Float64Array", "a numeric source array", srcTypeNameForDebug, memberName); + } + else if (expectedSelfType === Uint8Array) { + // Deserialize Uint8Array from number[]. + if (sourceObject instanceof Array && sourceObject.every(function (elem) { return !isNaN(elem); })) + return new Uint8Array(sourceObject.map(function (value) { return ~~value; })); + else + this._throwTypeMismatchError("Uint8Array", "a numeric source array", srcTypeNameForDebug, memberName); + } + else if (expectedSelfType === Uint8ClampedArray) { + // Deserialize Uint8Array from number[]. + if (sourceObject instanceof Array && sourceObject.every(function (elem) { return !isNaN(elem); })) + return new Uint8ClampedArray(sourceObject.map(function (value) { return ~~value; })); + else + this._throwTypeMismatchError("Uint8ClampedArray", "a numeric source array", srcTypeNameForDebug, memberName); + } + else if (expectedSelfType === Uint16Array) { + // Deserialize Uint16Array from number[]. + if (sourceObject instanceof Array && sourceObject.every(function (elem) { return !isNaN(elem); })) + return new Uint16Array(sourceObject.map(function (value) { return ~~value; })); + else + this._throwTypeMismatchError("Uint16Array", "a numeric source array", srcTypeNameForDebug, memberName); + } + else if (expectedSelfType === Uint32Array) { + // Deserialize Uint32Array from number[]. + if (sourceObject instanceof Array && sourceObject.every(function (elem) { return !isNaN(elem); })) + return new Uint32Array(sourceObject.map(function (value) { return ~~value; })); + else + this._throwTypeMismatchError("Uint32Array", "a numeric source array", srcTypeNameForDebug, memberName); + } + else if (expectedSelfType === ArrayBuffer) { + if (typeof sourceObject === "string") + return this._stringToArrayBuffer(sourceObject); + else + this._throwTypeMismatchError("ArrayBuffer", "a string source", srcTypeNameForDebug, memberName); + } + else if (expectedSelfType === DataView) { + if (typeof sourceObject === "string") + return this._stringToDataView(sourceObject); + else + this._throwTypeMismatchError("DataView", "a string source", srcTypeNameForDebug, memberName); + } + else if (expectedSelfType === Array) { + if (sourceObject instanceof Array) + return this.convertAsArray(sourceObject, typeInfo, memberName); + else + throw new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)); + } + else if (expectedSelfType === Set) { + if (sourceObject instanceof Array) + return this.convertAsSet(sourceObject, typeInfo, memberName); + else + this._throwTypeMismatchError("Set", "Array", srcTypeNameForDebug, memberName); + } + else if (expectedSelfType === Map) { + if (sourceObject instanceof Array) + return this.convertAsMap(sourceObject, typeInfo, memberName); + else + this._throwTypeMismatchError("Map", "a source array of key-value-pair objects", srcTypeNameForDebug, memberName); + } + else if (sourceObject && typeof sourceObject === "object") { + return this.convertAsObject(sourceObject, typeInfo, memberName); + } }; - /** - * Performs the conversion of a set of typed objects (or primitive values) into an array of simple javascript objects. - * - * @param sourceObject - * @param expectedElementType The constructor of the expected Set elements (e.g. `Number` for `Set`, or `MyClass` for `Set`). - * @param memberName Name of the object being serialized, used for debugging purposes. - * @returns - */ - Serializer.prototype.convertAsSet = function (sourceObject, expectedElementType, memberName) { + Deserializer.prototype.convertAsArray = function (sourceObject, typeInfo, memberName) { var _this = this; if (memberName === void 0) { memberName = "object"; } - if (!expectedElementType) - throw new TypeError("Could not serialize " + memberName + " as Set: missing element type definition."); + if (!(sourceObject instanceof Array)) { + this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName))); + return []; + } + if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length) { + this._errorHandler(new TypeError("Could not deserialize " + memberName + " as Array: missing constructor reference of Array elements.")); + return []; + } var elementTypeInfo = { - selfType: expectedElementType, + selfConstructor: typeInfo.elementConstructor[0], + elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [], + knownTypes: typeInfo.knownTypes }; - // For debugging and error tracking. - if (memberName) - memberName += "[]"; - var resultArray = []; - // Convert each element of the set, and put it into an output array. - // The output array is the one serialized, as JSON.stringify does not support Set serialization. (TODO: clarification needed) - sourceObject.forEach(function (element) { - var resultElement = _this.convertSingleValue(element, elementTypeInfo, memberName); - // Add to output if the source element was undefined, OR the converted element is defined. This will add intentionally undefined values to output, - // but not values that became undefined DURING serializing (usually because of a type-error). - if (!isValueDefined(element) || isValueDefined(resultElement)) { - resultArray.push(resultElement); + return sourceObject.map(function (element) { + // If an array element fails to deserialize, substitute with undefined. This is so that the original ordering is not interrupted by faulty + // entries, as an Array is ordered. + try { + return _this.convertSingleValue(element, elementTypeInfo); + } + catch (e) { + _this._errorHandler(e); + // Keep filling the array here with undefined to keep original ordering. + // Note: this is just aesthetics, not returning anything produces the same result. + return undefined; } }); - return resultArray; }; - /** - * Performs the conversion of a map of typed objects (or primitive values) into an array of simple javascript objects with `key` and `value` properties. - * - * @param sourceObject - * @param expectedKeyType The constructor of the expected Map keys (e.g. `Number` for `Map`, or `MyClass` for `Map`). - * @param expectedElementType The constructor of the expected Map values (e.g. `Number` for `Map`, or `MyClass` for `Map`). - * @param memberName Name of the object being serialized, used for debugging purposes. - */ - Serializer.prototype.convertAsMap = function (sourceObject, expectedKeyType, expectedElementType, memberName) { + Deserializer.prototype.convertAsSet = function (sourceObject, typeInfo, memberName) { var _this = this; if (memberName === void 0) { memberName = "object"; } - if (!expectedElementType) - throw new TypeError("Could not serialize " + memberName + " as Map: missing value type definition."); - if (!expectedKeyType) - throw new TypeError("Could not serialize " + memberName + " as Map: missing key type definition."); + if (!(sourceObject instanceof Array)) { + this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName))); + return new Set(); + } + if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length) { + this._errorHandler(new TypeError("Could not deserialize " + memberName + " as Set: missing constructor reference of Set elements.")); + return new Set(); + } var elementTypeInfo = { - selfType: expectedElementType, - elementTypes: [expectedElementType] + selfConstructor: typeInfo.elementConstructor[0], + elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [], + knownTypes: typeInfo.knownTypes }; - var keyTypeInfo = { - selfType: expectedKeyType - }; - if (memberName) - memberName += "[]"; - var resultArray = []; - // Convert each *entry* in the map to a simple javascript object with key and value properties. - sourceObject.forEach(function (value, key) { - var resultKeyValuePairObj = { - key: _this.convertSingleValue(key, keyTypeInfo, memberName), - value: _this.convertSingleValue(value, elementTypeInfo, memberName) - }; - // We are not going to emit entries with undefined keys OR undefined values. - if (isValueDefined(resultKeyValuePairObj.key) && isValueDefined(resultKeyValuePairObj.value)) { - resultArray.push(resultKeyValuePairObj); + var resultSet = new Set(); + sourceObject.forEach(function (element, i) { + try { + resultSet.add(_this.convertSingleValue(element, elementTypeInfo, memberName + ("[" + i + "]"))); + } + catch (e) { + // Faulty entries are skipped, because a Set is not ordered, and skipping an entry does not affect others. + _this._errorHandler(e); } }); - return resultArray; - }; - /** - * Performs the conversion of a typed javascript array to a simple untyped javascript array. - * This is needed because typed arrays are otherwise serialized as objects, so we'll end up with something like "{ 0: 0, 1: 1, ... }". - * - * @param sourceObject - * @returns - */ - Serializer.prototype.convertAsTypedArray = function (sourceObject) { - return Array.from(sourceObject); - }; - /** - * Performs the conversion of a raw ArrayBuffer to a string. - */ - Serializer.prototype.convertAsArrayBuffer = function (buffer) { - // ArrayBuffer -> 16-bit character codes -> character array -> joined string. - return Array.from(new Uint16Array(buffer)).map(function (charCode) { return String.fromCharCode(charCode); }).join(""); - }; - /** - * Performs the conversion of DataView, converting its internal ArrayBuffer to a string and returning that string. - */ - Serializer.prototype.convertAsDataView = function (dataView) { - return this.convertAsArrayBuffer(dataView.buffer); + return resultSet; }; - return Serializer; -}()); - - -// CONCATENATED MODULE: ./src/typedjson/json-object.ts - - -function jsonObject(optionsOrTarget) { - var options; - if (typeof optionsOrTarget === "function") { - // jsonObject is being used as a decorator, directly. - options = {}; - } - else { - // jsonObject is being used as a decorator factory. - options = optionsOrTarget || {}; - } - function decorator(target) { - var objectMetadata; - // Create or obtain JsonObjectMetadata object. - if (!target.prototype.hasOwnProperty(METADATA_FIELD_KEY)) { - // Target has no JsonObjectMetadata associated with it yet, create it now. - objectMetadata = new metadata_JsonObjectMetadata(target); - // Inherit json members and known types from parent @jsonObject (if any). - var parentMetadata = target.prototype[METADATA_FIELD_KEY]; - if (parentMetadata) { - parentMetadata.dataMembers - .forEach(function (memberMetadata, propKey) { - return objectMetadata.dataMembers.set(propKey, memberMetadata); - }); - parentMetadata.knownTypes - .forEach(function (knownType) { return objectMetadata.knownTypes.add(knownType); }); - } - Object.defineProperty(target.prototype, METADATA_FIELD_KEY, { - enumerable: false, - configurable: false, - writable: false, - value: objectMetadata - }); - } - else { - // Target already has JsonObjectMetadata associated with it. - objectMetadata = target.prototype[METADATA_FIELD_KEY]; - objectMetadata.classType = target; - } - // Fill JsonObjectMetadata. - objectMetadata.isExplicitlyMarked = true; - objectMetadata.onDeserializedMethodName = options.onDeserialized; - // T extend Object so it is fine - objectMetadata.initializerCallback = options.initializer; - if (options.name) { - objectMetadata.name = options.name; - } - // Obtain known-types. - if (typeof options.knownTypes === "string") { - objectMetadata.knownTypeMethodName = options.knownTypes; - } - else if (options.knownTypes instanceof Array) { - options.knownTypes - .filter(function (knownType) { return !!knownType; }) - .forEach(function (knownType) { return objectMetadata.knownTypes.add(knownType); }); - } - } - if (typeof optionsOrTarget === "function") { - // jsonObject is being used as a decorator, directly. - decorator(optionsOrTarget); - } - else { - // jsonObject is being used as a decorator factory. - return decorator; - } -} - -// CONCATENATED MODULE: ./src/typedjson/json-member.ts - - -function jsonMember(optionsOrTarget, propKey) { - if (optionsOrTarget instanceof Object && (typeof propKey === "string" || typeof propKey === "symbol")) { - var target = optionsOrTarget; - // For error messages. - var decoratorName = "@jsonMember on " + nameof(target.constructor) + "." + String(propKey); - // jsonMember used directly, no additional information directly available besides target and propKey. - // Obtain property constructor through ReflectDecorators. - if (isReflectMetadataSupported) { - var reflectPropCtor = Reflect.getMetadata("design:type", target, propKey); - if (!reflectPropCtor) { - logError(decoratorName + ": could not resolve detected property constructor at runtime."); - return; - } - if (isSpecialPropertyType(decoratorName, reflectPropCtor)) { - return; - } - injectMetadataInformation(target, propKey, { - ctor: reflectPropCtor, - key: propKey.toString(), - name: propKey.toString(), - }); + Deserializer.prototype.convertAsMap = function (sourceObject, typeInfo, memberName) { + var _this = this; + if (memberName === void 0) { memberName = "object"; } + if (!(sourceObject instanceof Array)) + this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName))); + if (!typeInfo.keyConstructor) { + this._errorHandler(new TypeError("Could not deserialize " + memberName + " as Map: missing key constructor.")); + return new Map(); } - else { - logError(decoratorName + ": ReflectDecorators is required if no 'constructor' option is specified."); - return; + if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length) { + this._errorHandler(new TypeError("Could not deserialize " + memberName + " as Map: missing value constructor.")); + return new Map(); } - } - else { - // jsonMember used as a decorator factory. - return function (target, _propKey) { - var options = optionsOrTarget || {}; - var propCtor; - var decoratorName = "@jsonMember on " + nameof(target.constructor) + "." + String(_propKey); // For error messages. - if (options.hasOwnProperty("constructor")) { - if (!isValueDefined(options.constructor)) { - logError(decoratorName + ": cannot resolve specified property constructor at runtime."); - return; - } - // Property constructor has been specified. Use ReflectDecorators (if available) to check whether that constructor is correct. Warn if not. - if (isReflectMetadataSupported && !isSubtypeOf(options.constructor, Reflect.getMetadata("design:type", target, _propKey))) { - logWarning(decoratorName + ": detected property type does not match 'constructor' option."); - } - propCtor = options.constructor; - } - else { - // Use ReflectDecorators to obtain property constructor. - if (isReflectMetadataSupported) { - propCtor = Reflect.getMetadata("design:type", target, _propKey); - if (!propCtor) { - logError(decoratorName + ": cannot resolve detected property constructor at runtime."); - return; - } - } - else if (!options.deserializer) { - logError(decoratorName + ": ReflectDecorators is required if no 'constructor' option is specified."); - return; + var keyTypeInfo = { + selfConstructor: typeInfo.keyConstructor, + knownTypes: typeInfo.knownTypes + }; + var valueTypeInfo = { + selfConstructor: typeInfo.elementConstructor[0], + elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [], + knownTypes: typeInfo.knownTypes + }; + var resultMap = new Map(); + sourceObject.forEach(function (element) { + try { + var key = _this.convertSingleValue(element.key, keyTypeInfo); + // Undefined/null keys not supported, skip if so. + if (isValueDefined(key)) { + resultMap.set(key, _this.convertSingleValue(element.value, valueTypeInfo, memberName + "[" + key + "]")); } } - if (isSpecialPropertyType(decoratorName, propCtor)) { - return; + catch (e) { + // Faulty entries are skipped, because a Map is not ordered, + // and skipping an entry does not affect others. + _this._errorHandler(e); } - injectMetadataInformation(target, _propKey, { - ctor: propCtor, - emitDefaultValue: options.emitDefaultValue || false, - isRequired: options.isRequired || false, - key: _propKey.toString(), - name: options.name || _propKey.toString(), - deserializer: options.deserializer, - serializer: options.serializer, - }); - }; - } -} -function isSpecialPropertyType(decoratorName, propCtor) { - if (propCtor === Array) { - logError(decoratorName + ": property is an Array. Use the jsonArrayMember decorator to" - + " serialize this property."); - return true; - } - if (propCtor === Set) { - logError(decoratorName + ": property is a Set. Use the jsonSetMember decorator to" - + " serialize this property."); - return true; - } - if (propCtor === Map) { - logError(decoratorName + ": property is a Map. Use the jsonMapMember decorator to" - + " serialize this property."); - return true; - } - return false; -} - -// CONCATENATED MODULE: ./src/typedjson/json-array-member.ts - - -/** - * Specifies that a property, of type array, is part of an object when serializing. - * @param elementConstructor Constructor of array elements (e.g. 'Number' for 'number[]', or 'Date' for 'Date[]'). - * @param options Additional options. - */ -function jsonArrayMember(elementConstructor, options) { - if (options === void 0) { options = {}; } - return function (target, propKey) { - var decoratorName = "@jsonArrayMember on " + nameof(target.constructor) + "." + String(propKey); // For error messages. - if (typeof elementConstructor !== "function") { - logError(decoratorName + ": could not resolve constructor of array elements at runtime."); - return; - } - var dimensions = options.dimensions === undefined ? 1 : options.dimensions; - if (!isNaN(dimensions) && dimensions < 1) { - logError(decoratorName + ": 'dimensions' option must be at least 1."); - return; - } - // If ReflectDecorators is available, use it to check whether 'jsonArrayMember' has been used on an array. - if (isReflectMetadataSupported && Reflect.getMetadata("design:type", target, propKey) !== Array) { - logError(decoratorName + ": property is not an Array."); - return; - } - injectMetadataInformation(target, propKey, { - ctor: Array, - elementType: createArrayElementType(elementConstructor, dimensions), - emitDefaultValue: options.emitDefaultValue || false, - isRequired: options.isRequired || false, - key: propKey.toString(), - name: options.name || propKey.toString(), - deserializer: options.deserializer, - serializer: options.serializer, }); + return resultMap; }; -} -function createArrayElementType(elementCtor, dimensions) { - var elementTypes = new Array(dimensions).fill(Array, 0, -1); - elementTypes[dimensions - 1] = elementCtor; - return elementTypes; -} - -// CONCATENATED MODULE: ./src/typedjson/json-set-member.ts - - - -/** - * Specifies that the property is part of the object when serializing. - * Use this decorator on properties of type Set. - * @param elementConstructor Constructor of set elements (e.g. 'Number' for Set or 'Date' for Set). - * @param options Additional options. - */ -function jsonSetMember(elementConstructor, options) { - if (options === void 0) { options = {}; } - return function (target, propKey) { - var decoratorName = "@jsonSetMember on " + nameof(target.constructor) + "." + String(propKey); // For error messages. - if (typeof elementConstructor !== "function") { - logError(decoratorName + ": could not resolve constructor of set elements at runtime."); - return; - } - // If ReflectDecorators is available, use it to check whether 'jsonSetMember' has been used on a set. Warn if not. - if (isReflectMetadataSupported && Reflect.getMetadata("design:type", target, propKey) !== Set) { - logError(decoratorName + ": property is not a Set."); - return; + Deserializer.prototype._throwTypeMismatchError = function (targetType, expectedSourceType, actualSourceType, memberName) { + if (memberName === void 0) { memberName = "object"; } + throw new TypeError("Could not deserialize " + memberName + " as " + targetType + ":" + + (" expected " + expectedSourceType + ", got " + actualSourceType + ".")); + }; + Deserializer.prototype._makeTypeErrorMessage = function (expectedType, actualType, memberName) { + if (memberName === void 0) { memberName = "object"; } + var expectedTypeName = (typeof expectedType === "function") ? nameof(expectedType) : expectedType; + var actualTypeName = (typeof actualType === "function") ? nameof(actualType) : actualType; + return "Could not deserialize " + memberName + ": expected '" + expectedTypeName + "', got '" + actualTypeName + "'."; + }; + Deserializer.prototype._instantiateType = function (ctor) { + return new ctor(); + }; + Deserializer.prototype._mergeKnownTypes = function () { + var _this = this; + var knownTypeMaps = []; + for (var _i = 0; _i < arguments.length; _i++) { + knownTypeMaps[_i] = arguments[_i]; } - injectMetadataInformation(target, propKey, { - ctor: Set, - elementType: [elementConstructor], - emitDefaultValue: options.emitDefaultValue || false, - isRequired: options.isRequired || false, - key: propKey.toString(), - name: options.name || propKey.toString(), - deserializer: options.deserializer, - serializer: options.serializer, + var result = new Map(); + knownTypeMaps.forEach(function (knownTypes) { + knownTypes.forEach(function (ctor, name) { + if (_this._nameResolver) { + result.set(_this._nameResolver(ctor), ctor); + } + else { + result.set(name, ctor); + } + }); }); + return result; }; -} - -// CONCATENATED MODULE: ./src/typedjson/json-map-member.ts - - -/** - * Specifies that the property is part of the object when serializing. - * Use this decorator on properties of type Map. - * @param keyConstructor Constructor of map keys (e.g. 'Number' for 'Map'). - * @param valueConstructor Constructor of map values (e.g. 'Date' for 'Map'). - * @param options Additional options. - */ -function jsonMapMember(keyConstructor, valueConstructor, options) { - if (options === void 0) { options = {}; } - return function (target, propKey) { - var decoratorName = "@jsonMapMember on " + nameof(target.constructor) + "." + String(propKey); // For error messages. - if (typeof keyConstructor !== "function") { - logError(decoratorName + ": could not resolve constructor of map keys at runtime."); - return; - } - if (typeof valueConstructor !== "function") { - logError(decoratorName + ": could not resolve constructor of map values at runtime."); - return; - } - // If ReflectDecorators is available, use it to check whether 'jsonMapMember' has been used on a map. Warn if not. - if (isReflectMetadataSupported && Reflect.getMetadata("design:type", target, propKey) !== Map) { - logError(decoratorName + ": property is not a Map."); - return; - } - injectMetadataInformation(target, propKey, { - ctor: Map, - elementType: [valueConstructor], - keyType: keyConstructor, - emitDefaultValue: options.emitDefaultValue || false, - isRequired: options.isRequired || false, - key: propKey.toString(), - name: options.name || propKey.toString(), - deserializer: options.deserializer, - serializer: options.serializer, + Deserializer.prototype._createKnownTypesMap = function (knowTypes) { + var _this = this; + var map = new Map(); + knowTypes.forEach(function (ctor) { + if (_this._nameResolver) { + map.set(_this._nameResolver(ctor), ctor); + } + else { + var knownTypeMeta = metadata_JsonObjectMetadata.getFromConstructor(ctor); + var name_1 = knownTypeMeta && knownTypeMeta.isExplicitlyMarked && knownTypeMeta.name + ? knownTypeMeta.name + : ctor.name; + map.set(name_1, ctor); + } }); + return map; }; -} + Deserializer.prototype._isDirectlyDeserializableNativeType = function (ctor) { + return ~([Number, String, Boolean].indexOf(ctor)); + }; + Deserializer.prototype.convertNativeObject = function (sourceObject) { + return sourceObject; + }; + Deserializer.prototype._stringToArrayBuffer = function (str) { + var buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char + var bufView = new Uint16Array(buf); + for (var i = 0, strLen = str.length; i < strLen; i++) { + bufView[i] = str.charCodeAt(i); + } + return buf; + }; + Deserializer.prototype._stringToDataView = function (str) { + return new DataView(this._stringToArrayBuffer(str)); + }; + return Deserializer; +}()); -// CONCATENATED MODULE: ./src/typedjson.ts -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TypedJSON", function() { return typedjson_TypedJSON; }); -/* concated harmony reexport jsonObject */__webpack_require__.d(__webpack_exports__, "jsonObject", function() { return jsonObject; }); -/* concated harmony reexport jsonMember */__webpack_require__.d(__webpack_exports__, "jsonMember", function() { return jsonMember; }); -/* concated harmony reexport jsonArrayMember */__webpack_require__.d(__webpack_exports__, "jsonArrayMember", function() { return jsonArrayMember; }); -/* concated harmony reexport jsonSetMember */__webpack_require__.d(__webpack_exports__, "jsonSetMember", function() { return jsonSetMember; }); -/* concated harmony reexport jsonMapMember */__webpack_require__.d(__webpack_exports__, "jsonMapMember", function() { return jsonMapMember; }); -var typedjson_assign = (undefined && undefined.__assign) || function () { - typedjson_assign = Object.assign || function(t) { + +// CONCATENATED MODULE: ./src/parser.ts +var parser_assign = (undefined && undefined.__assign) || function () { + parser_assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) @@ -1343,13 +1052,13 @@ var typedjson_assign = (undefined && undefined.__assign) || function () { } return t; }; - return typedjson_assign.apply(this, arguments); + return parser_assign.apply(this, arguments); }; -var typedjson_TypedJSON = /** @class */ (function () { +var parser_TypedJSON = /** @class */ (function () { /** * Creates a new TypedJSON instance to serialize (stringify) and deserialize (parse) object * instances of the specified root class type. @@ -1427,7 +1136,7 @@ var typedjson_TypedJSON = /** @class */ (function () { */ TypedJSON.prototype.config = function (settings) { if (TypedJSON._globalConfig) { - settings = typedjson_assign({}, TypedJSON._globalConfig, settings); + settings = parser_assign({}, TypedJSON._globalConfig, settings); if (settings.knownTypes && TypedJSON._globalConfig.knownTypes) { // Merge known-types (also de-duplicate them, so Array -> Set -> Array). settings.knownTypes = Array.from(new Set(settings.knownTypes.concat(TypedJSON._globalConfig.knownTypes))); @@ -1539,83 +1248,377 @@ var typedjson_TypedJSON = /** @class */ (function () { }); } else { - this.errorHandler(new TypeError("Expected 'json' to define a Set (using an Array)" - + (", but got " + typeof json + "."))); + this.errorHandler(new TypeError("Expected 'json' to define a Set (using an Array)" + + (", but got " + typeof json + "."))); + } + return new Map(); + }; + /** + * Converts an instance of the specified class type to a plain JSON object. + * @param object The instance to convert to a JSON string. + * @returns Serialized object or undefined if an error has occured. + */ + TypedJSON.prototype.toPlainJson = function (object) { + try { + return this.serializer.convertSingleValue(object, { + selfType: this.rootConstructor + }); + } + catch (e) { + this.errorHandler(e); + } + }; + TypedJSON.prototype.toPlainArray = function (object, dimensions) { + if (dimensions === void 0) { dimensions = 1; } + try { + var elementConstructorArray = new Array(dimensions - 1).fill(Array).concat(this.rootConstructor); + return this.serializer.convertAsArray(object, elementConstructorArray); + } + catch (e) { + this.errorHandler(e); + } + }; + TypedJSON.prototype.toPlainSet = function (object) { + try { + return this.serializer.convertAsSet(object, this.rootConstructor); + } + catch (e) { + this.errorHandler(e); + } + }; + TypedJSON.prototype.toPlainMap = function (object, keyConstructor) { + try { + return this.serializer.convertAsMap(object, keyConstructor, this.rootConstructor); + } + catch (e) { + this.errorHandler(e); + } + }; + /** + * Converts an instance of the specified class type to a JSON string. + * @param object The instance to convert to a JSON string. + * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown). + * @returns String with the serialized object or an empty string if an error has occured, but + * the errorHandler did not throw. + */ + TypedJSON.prototype.stringify = function (object) { + var result = this.toPlainJson(object); + if (result === undefined) { + return ''; + } + return JSON.stringify(result, this.replacer, this.indent); + }; + TypedJSON.prototype.stringifyAsArray = function (object, dimensions) { + return JSON.stringify(this.toPlainArray(object, dimensions), this.replacer, this.indent); + }; + TypedJSON.prototype.stringifyAsSet = function (object) { + return JSON.stringify(this.toPlainSet(object), this.replacer, this.indent); + }; + TypedJSON.prototype.stringifyAsMap = function (object, keyConstructor) { + return JSON.stringify(this.toPlainMap(object, keyConstructor), this.replacer, this.indent); + }; + TypedJSON.prototype._mapKnownTypes = function (constructors) { + var _this = this; + var map = new Map(); + constructors.filter(function (ctor) { return ctor; }).forEach(function (ctor) { return map.set(_this.nameResolver(ctor), ctor); }); + return map; + }; + return TypedJSON; +}()); + + +// CONCATENATED MODULE: ./src/typedjson/json-object.ts + + +function jsonObject(optionsOrTarget) { + var options; + if (typeof optionsOrTarget === "function") { + // jsonObject is being used as a decorator, directly. + options = {}; + } + else { + // jsonObject is being used as a decorator factory. + options = optionsOrTarget || {}; + } + function decorator(target) { + var objectMetadata; + // Create or obtain JsonObjectMetadata object. + if (!target.prototype.hasOwnProperty(METADATA_FIELD_KEY)) { + // Target has no JsonObjectMetadata associated with it yet, create it now. + objectMetadata = new metadata_JsonObjectMetadata(target); + // Inherit json members and known types from parent @jsonObject (if any). + var parentMetadata = target.prototype[METADATA_FIELD_KEY]; + if (parentMetadata) { + parentMetadata.dataMembers + .forEach(function (memberMetadata, propKey) { + return objectMetadata.dataMembers.set(propKey, memberMetadata); + }); + parentMetadata.knownTypes + .forEach(function (knownType) { return objectMetadata.knownTypes.add(knownType); }); + } + Object.defineProperty(target.prototype, METADATA_FIELD_KEY, { + enumerable: false, + configurable: false, + writable: false, + value: objectMetadata + }); + } + else { + // Target already has JsonObjectMetadata associated with it. + objectMetadata = target.prototype[METADATA_FIELD_KEY]; + objectMetadata.classType = target; + } + // Fill JsonObjectMetadata. + objectMetadata.isExplicitlyMarked = true; + objectMetadata.onDeserializedMethodName = options.onDeserialized; + // T extend Object so it is fine + objectMetadata.initializerCallback = options.initializer; + if (options.name) { + objectMetadata.name = options.name; + } + // Obtain known-types. + if (typeof options.knownTypes === "string") { + objectMetadata.knownTypeMethodName = options.knownTypes; + } + else if (options.knownTypes instanceof Array) { + options.knownTypes + .filter(function (knownType) { return !!knownType; }) + .forEach(function (knownType) { return objectMetadata.knownTypes.add(knownType); }); + } + } + if (typeof optionsOrTarget === "function") { + // jsonObject is being used as a decorator, directly. + decorator(optionsOrTarget); + } + else { + // jsonObject is being used as a decorator factory. + return decorator; + } +} + +// CONCATENATED MODULE: ./src/typedjson/json-member.ts + + +function jsonMember(optionsOrTarget, propKey) { + if (optionsOrTarget instanceof Object && (typeof propKey === "string" || typeof propKey === "symbol")) { + var target = optionsOrTarget; + // For error messages. + var decoratorName = "@jsonMember on " + nameof(target.constructor) + "." + String(propKey); + // jsonMember used directly, no additional information directly available besides target and propKey. + // Obtain property constructor through ReflectDecorators. + if (isReflectMetadataSupported) { + var reflectPropCtor = Reflect.getMetadata("design:type", target, propKey); + if (!reflectPropCtor) { + logError(decoratorName + ": could not resolve detected property constructor at runtime."); + return; + } + if (isSpecialPropertyType(decoratorName, reflectPropCtor)) { + return; + } + injectMetadataInformation(target, propKey, { + ctor: reflectPropCtor, + key: propKey.toString(), + name: propKey.toString(), + }); + } + else { + logError(decoratorName + ": ReflectDecorators is required if no 'constructor' option is specified."); + return; } - return new Map(); - }; - /** - * Converts an instance of the specified class type to a plain JSON object. - * @param object The instance to convert to a JSON string. - * @returns Serialized object or undefined if an error has occured. - */ - TypedJSON.prototype.toPlainJson = function (object) { - try { - return this.serializer.convertSingleValue(object, { - selfType: this.rootConstructor + } + else { + // jsonMember used as a decorator factory. + return function (target, _propKey) { + var options = optionsOrTarget || {}; + var propCtor; + var decoratorName = "@jsonMember on " + nameof(target.constructor) + "." + String(_propKey); // For error messages. + if (options.hasOwnProperty("constructor")) { + if (!isValueDefined(options.constructor)) { + logError(decoratorName + ": cannot resolve specified property constructor at runtime."); + return; + } + // Property constructor has been specified. Use ReflectDecorators (if available) to check whether that constructor is correct. Warn if not. + if (isReflectMetadataSupported && !isSubtypeOf(options.constructor, Reflect.getMetadata("design:type", target, _propKey))) { + logWarning(decoratorName + ": detected property type does not match 'constructor' option."); + } + propCtor = options.constructor; + } + else { + // Use ReflectDecorators to obtain property constructor. + if (isReflectMetadataSupported) { + propCtor = Reflect.getMetadata("design:type", target, _propKey); + if (!propCtor) { + logError(decoratorName + ": cannot resolve detected property constructor at runtime."); + return; + } + } + else if (!options.deserializer) { + logError(decoratorName + ": ReflectDecorators is required if no 'constructor' option is specified."); + return; + } + } + if (isSpecialPropertyType(decoratorName, propCtor)) { + return; + } + injectMetadataInformation(target, _propKey, { + ctor: propCtor, + emitDefaultValue: options.emitDefaultValue || false, + isRequired: options.isRequired || false, + key: _propKey.toString(), + name: options.name || _propKey.toString(), + deserializer: options.deserializer, + serializer: options.serializer, }); + }; + } +} +function isSpecialPropertyType(decoratorName, propCtor) { + if (propCtor === Array) { + logError(decoratorName + ": property is an Array. Use the jsonArrayMember decorator to" + + " serialize this property."); + return true; + } + if (propCtor === Set) { + logError(decoratorName + ": property is a Set. Use the jsonSetMember decorator to" + + " serialize this property."); + return true; + } + if (propCtor === Map) { + logError(decoratorName + ": property is a Map. Use the jsonMapMember decorator to" + + " serialize this property."); + return true; + } + return false; +} + +// CONCATENATED MODULE: ./src/typedjson/json-array-member.ts + + +/** + * Specifies that a property, of type array, is part of an object when serializing. + * @param elementConstructor Constructor of array elements (e.g. 'Number' for 'number[]', or 'Date' for 'Date[]'). + * @param options Additional options. + */ +function jsonArrayMember(elementConstructor, options) { + if (options === void 0) { options = {}; } + return function (target, propKey) { + var decoratorName = "@jsonArrayMember on " + nameof(target.constructor) + "." + String(propKey); // For error messages. + if (typeof elementConstructor !== "function") { + logError(decoratorName + ": could not resolve constructor of array elements at runtime."); + return; } - catch (e) { - this.errorHandler(e); - } - }; - TypedJSON.prototype.toPlainArray = function (object, dimensions) { - if (dimensions === void 0) { dimensions = 1; } - try { - var elementConstructorArray = new Array(dimensions - 1).fill(Array).concat(this.rootConstructor); - return this.serializer.convertAsArray(object, elementConstructorArray); + var dimensions = options.dimensions === undefined ? 1 : options.dimensions; + if (!isNaN(dimensions) && dimensions < 1) { + logError(decoratorName + ": 'dimensions' option must be at least 1."); + return; } - catch (e) { - this.errorHandler(e); + // If ReflectDecorators is available, use it to check whether 'jsonArrayMember' has been used on an array. + if (isReflectMetadataSupported && Reflect.getMetadata("design:type", target, propKey) !== Array) { + logError(decoratorName + ": property is not an Array."); + return; } + injectMetadataInformation(target, propKey, { + ctor: Array, + elementType: createArrayElementType(elementConstructor, dimensions), + emitDefaultValue: options.emitDefaultValue || false, + isRequired: options.isRequired || false, + key: propKey.toString(), + name: options.name || propKey.toString(), + deserializer: options.deserializer, + serializer: options.serializer, + }); }; - TypedJSON.prototype.toPlainSet = function (object) { - try { - return this.serializer.convertAsSet(object, this.rootConstructor); +} +function createArrayElementType(elementCtor, dimensions) { + var elementTypes = new Array(dimensions).fill(Array, 0, -1); + elementTypes[dimensions - 1] = elementCtor; + return elementTypes; +} + +// CONCATENATED MODULE: ./src/typedjson/json-set-member.ts + + + +/** + * Specifies that the property is part of the object when serializing. + * Use this decorator on properties of type Set. + * @param elementConstructor Constructor of set elements (e.g. 'Number' for Set or 'Date' for Set). + * @param options Additional options. + */ +function jsonSetMember(elementConstructor, options) { + if (options === void 0) { options = {}; } + return function (target, propKey) { + var decoratorName = "@jsonSetMember on " + nameof(target.constructor) + "." + String(propKey); // For error messages. + if (typeof elementConstructor !== "function") { + logError(decoratorName + ": could not resolve constructor of set elements at runtime."); + return; } - catch (e) { - this.errorHandler(e); + // If ReflectDecorators is available, use it to check whether 'jsonSetMember' has been used on a set. Warn if not. + if (isReflectMetadataSupported && Reflect.getMetadata("design:type", target, propKey) !== Set) { + logError(decoratorName + ": property is not a Set."); + return; } + injectMetadataInformation(target, propKey, { + ctor: Set, + elementType: [elementConstructor], + emitDefaultValue: options.emitDefaultValue || false, + isRequired: options.isRequired || false, + key: propKey.toString(), + name: options.name || propKey.toString(), + deserializer: options.deserializer, + serializer: options.serializer, + }); }; - TypedJSON.prototype.toPlainMap = function (object, keyConstructor) { - try { - return this.serializer.convertAsMap(object, keyConstructor, this.rootConstructor); +} + +// CONCATENATED MODULE: ./src/typedjson/json-map-member.ts + + +/** + * Specifies that the property is part of the object when serializing. + * Use this decorator on properties of type Map. + * @param keyConstructor Constructor of map keys (e.g. 'Number' for 'Map'). + * @param valueConstructor Constructor of map values (e.g. 'Date' for 'Map'). + * @param options Additional options. + */ +function jsonMapMember(keyConstructor, valueConstructor, options) { + if (options === void 0) { options = {}; } + return function (target, propKey) { + var decoratorName = "@jsonMapMember on " + nameof(target.constructor) + "." + String(propKey); // For error messages. + if (typeof keyConstructor !== "function") { + logError(decoratorName + ": could not resolve constructor of map keys at runtime."); + return; } - catch (e) { - this.errorHandler(e); + if (typeof valueConstructor !== "function") { + logError(decoratorName + ": could not resolve constructor of map values at runtime."); + return; } - }; - /** - * Converts an instance of the specified class type to a JSON string. - * @param object The instance to convert to a JSON string. - * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown). - * @returns String with the serialized object or an empty string if an error has occured, but - * the errorHandler did not throw. - */ - TypedJSON.prototype.stringify = function (object) { - var result = this.toPlainJson(object); - if (result === undefined) { - return ''; + // If ReflectDecorators is available, use it to check whether 'jsonMapMember' has been used on a map. Warn if not. + if (isReflectMetadataSupported && Reflect.getMetadata("design:type", target, propKey) !== Map) { + logError(decoratorName + ": property is not a Map."); + return; } - return JSON.stringify(result, this.replacer, this.indent); - }; - TypedJSON.prototype.stringifyAsArray = function (object, dimensions) { - return JSON.stringify(this.toPlainArray(object, dimensions), this.replacer, this.indent); - }; - TypedJSON.prototype.stringifyAsSet = function (object) { - return JSON.stringify(this.toPlainSet(object), this.replacer, this.indent); - }; - TypedJSON.prototype.stringifyAsMap = function (object, keyConstructor) { - return JSON.stringify(this.toPlainMap(object, keyConstructor), this.replacer, this.indent); - }; - TypedJSON.prototype._mapKnownTypes = function (constructors) { - var _this = this; - var map = new Map(); - constructors.filter(function (ctor) { return ctor; }).forEach(function (ctor) { return map.set(_this.nameResolver(ctor), ctor); }); - return map; + injectMetadataInformation(target, propKey, { + ctor: Map, + elementType: [valueConstructor], + keyType: keyConstructor, + emitDefaultValue: options.emitDefaultValue || false, + isRequired: options.isRequired || false, + key: propKey.toString(), + name: options.name || propKey.toString(), + deserializer: options.deserializer, + serializer: options.serializer, + }); }; - return TypedJSON; -}()); +} + +// CONCATENATED MODULE: ./src/typedjson.ts +/* concated harmony reexport TypedJSON */__webpack_require__.d(__webpack_exports__, "TypedJSON", function() { return parser_TypedJSON; }); +/* concated harmony reexport jsonObject */__webpack_require__.d(__webpack_exports__, "jsonObject", function() { return jsonObject; }); +/* concated harmony reexport jsonMember */__webpack_require__.d(__webpack_exports__, "jsonMember", function() { return jsonMember; }); +/* concated harmony reexport jsonArrayMember */__webpack_require__.d(__webpack_exports__, "jsonArrayMember", function() { return jsonArrayMember; }); +/* concated harmony reexport jsonSetMember */__webpack_require__.d(__webpack_exports__, "jsonSetMember", function() { return jsonSetMember; }); +/* concated harmony reexport jsonMapMember */__webpack_require__.d(__webpack_exports__, "jsonMapMember", function() { return jsonMapMember; }); diff --git a/js/typedjson.js.map b/js/typedjson.js.map index 4605935..626d996 100644 --- a/js/typedjson.js.map +++ b/js/typedjson.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack://typedjson/webpack/universalModuleDefinition","webpack://typedjson/webpack/bootstrap","webpack://typedjson/./src/typedjson/helpers.ts","webpack://typedjson/./src/typedjson/metadata.ts","webpack://typedjson/./src/typedjson/deserializer.ts","webpack://typedjson/./src/typedjson/serializer.ts","webpack://typedjson/./src/typedjson/json-object.ts","webpack://typedjson/./src/typedjson/json-member.ts","webpack://typedjson/./src/typedjson/json-array-member.ts","webpack://typedjson/./src/typedjson/json-set-member.ts","webpack://typedjson/./src/typedjson/json-map-member.ts","webpack://typedjson/./src/typedjson.ts"],"names":[],"mappings":"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","file":"typedjson.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"typedjson\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"typedjson\"] = factory();\n\telse\n\t\troot[\"typedjson\"] = factory();\n})((typeof self !== 'undefined' ? self : this), function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","declare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport const METADATA_FIELD_KEY = \"__typedJsonJsonObjectMetadataInformation__\";\n\nexport function getDefaultValue(type: { new (): T }): T|undefined\n{\n switch (type as any)\n {\n case Number:\n return 0 as any;\n\n case String:\n return \"\" as any;\n\n case Boolean:\n return false as any;\n\n case Array:\n return [] as any;\n\n default:\n return undefined;\n }\n}\n\n/**\n * Determines whether the specified type is a type that can be passed on \"as-is\" into `JSON.stringify`.\n * Values of these types don't need special conversion.\n * @param type The constructor of the type (wrapper constructor for primitive types, e.g. `Number` for `number`).\n */\nexport function isDirectlySerializableNativeType(type: Function): boolean\n{\n return !!(~[Date, Number, String, Boolean].indexOf(type as any));\n}\n\nexport function isTypeTypedArray(type: Function): boolean\n{\n return !!(~[Float32Array, Float64Array, Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array]\n .indexOf(type as any));\n}\n\nexport function isPrimitiveValue(obj: any): boolean\n{\n switch (typeof obj)\n {\n case \"string\":\n case \"number\":\n case \"boolean\":\n return true;\n default:\n return (obj instanceof String || obj instanceof Number || obj instanceof Boolean);\n }\n}\n\nexport function isObject(value: any): value is Object\n{\n return typeof value === \"object\";\n}\n\nfunction shouldOmitParseString(jsonStr: string, expectedType: Function): boolean {\n const expectsTypesSerializedAsStrings = expectedType === String\n || expectedType === ArrayBuffer\n || expectedType === DataView;\n\n const hasQuotes = jsonStr.length >= 2 && jsonStr[0] === '\"' && jsonStr[jsonStr.length-1] === '\"';\n const isInteger = /^\\d+$/.test(jsonStr.trim());\n\n return (expectsTypesSerializedAsStrings && !hasQuotes) || ((!hasQuotes && !isInteger) && expectedType === Date);\n}\n\nexport function parseToJSObject(json: any, expectedType: Function): Object {\n if (typeof json !== 'string' || shouldOmitParseString(json, expectedType))\n {\n return json;\n }\n return JSON.parse(json);\n}\n\n/**\n * Determines if 'A' is a sub-type of 'B' (or if 'A' equals 'B').\n * @param A The supposed derived type.\n * @param B The supposed base type.\n */\nexport function isSubtypeOf(A: Function, B: Function)\n{\n return A === B || A.prototype instanceof B;\n}\n\nexport function logError(message?: any, ...optionalParams: any[])\n{\n if (typeof console === \"object\" && typeof console.error === \"function\")\n {\n console.error(message, ...optionalParams);\n }\n else if (typeof console === \"object\" && typeof console.log === \"function\")\n {\n console.log(`ERROR: ${message}`, ...optionalParams);\n }\n}\n\nexport function logMessage(message?: any, ...optionalParams: any[])\n{\n if (typeof console === \"object\" && typeof console.log === \"function\")\n {\n console.log(message, ...optionalParams);\n }\n}\n\nexport function logWarning(message?: any, ...optionalParams: any[])\n{\n if (typeof console === \"object\" && typeof console.warn === \"function\")\n {\n console.warn(message, ...optionalParams);\n } else if (typeof console === \"object\" && typeof console.log === \"function\")\n {\n console.log(`WARNING: ${message}`, ...optionalParams);\n }\n}\n\n/**\n * Checks if the value is considered defined (not undefined and not null).\n * @param value\n */\nexport function isValueDefined(value: T): value is Exclude\n{\n return !(typeof value === \"undefined\" || value === null);\n}\n\nexport function isInstanceOf(value: any, constructor: Function): boolean\n{\n if (typeof value === \"number\")\n {\n return (constructor === Number);\n }\n else if (typeof value === \"string\")\n {\n return (constructor === String);\n }\n else if (typeof value === \"boolean\")\n {\n return (constructor === Boolean);\n }\n else if (isObject(value))\n {\n return (value instanceof constructor);\n }\n\n return false;\n}\n\nexport const isReflectMetadataSupported =\n (typeof Reflect === \"object\" && typeof Reflect.getMetadata === \"function\");\n\n/**\n * Gets the name of a function.\n * @param fn The function whose name to get.\n */\nexport function nameof(fn: Function & { name?: string })\n{\n if (typeof fn.name === \"string\")\n {\n return fn.name;\n }\n else\n {\n return \"undefined\";\n }\n}\n","import { nameof, logError, METADATA_FIELD_KEY, isDirectlySerializableNativeType, isTypeTypedArray } from \"./helpers\";\nimport { IndexedObject } from \"./types\";\n\nexport interface JsonMemberMetadata\n{\n /** If set, a default value will be emitted for uninitialized members. */\n emitDefaultValue?: boolean;\n\n /** Member name as it appears in the serialized JSON. */\n name: string;\n\n /** Property or field key of the json member. */\n key: string;\n\n /** Constuctor (type) reference of the member. */\n ctor?: Function;\n\n /** If set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** If the json member is an array, map or set, sets member options of elements/values. Subsequent values define the types of nested arrays. */\n elementType?: Function[];\n\n /** If the json member is a map, sets member options of array keys. */\n keyType?: Function;\n\n /** Custom deserializer to use. */\n deserializer?: (json: any) => any;\n\n /** Custom serializer to use. */\n serializer?: (value: any) => any;\n}\n\nexport class JsonObjectMetadata\n{\n //#region Static\n /**\n * Gets the name of a class as it appears in a serialized JSON string.\n * @param ctor The constructor of a class (with or without jsonObject).\n */\n public static getJsonObjectName(ctor: Function): string\n {\n const metadata = JsonObjectMetadata.getFromConstructor(ctor);\n return metadata ? nameof(metadata.classType) : nameof(ctor);\n }\n\n /**\n * Gets jsonObject metadata information from a class.\n * @param ctor The constructor class.\n */\n public static getFromConstructor(ctor: Function): JsonObjectMetadata|undefined\n {\n const prototype = ctor.prototype;\n if (!prototype)\n {\n return;\n }\n\n let metadata: JsonObjectMetadata|undefined;\n if (prototype.hasOwnProperty(METADATA_FIELD_KEY))\n {\n // The class prototype contains own jsonObject metadata\n metadata = prototype[METADATA_FIELD_KEY];\n }\n\n // Ignore implicitly added jsonObject (through jsonMember)\n if (metadata && metadata.isExplicitlyMarked)\n {\n return metadata;\n }\n\n // In the end maybe it is something which we can handle directly\n if (JsonObjectMetadata.doesHandleWithoutAnnotation(ctor))\n {\n const primitiveMeta = new JsonObjectMetadata(ctor);\n primitiveMeta.isExplicitlyMarked = true;\n // we do not store the metadata here to not modify builtin prototype\n return primitiveMeta;\n }\n }\n\n /**\n * Gets the known type name of a jsonObject class for type hint.\n * @param constructor The constructor class.\n */\n public static getKnownTypeNameFromType(constructor: Function): string\n {\n const metadata = JsonObjectMetadata.getFromConstructor(constructor);\n return metadata ? nameof(metadata.classType) : nameof(constructor);\n }\n\n private static doesHandleWithoutAnnotation(ctor: Function): boolean\n {\n return isDirectlySerializableNativeType(ctor) || isTypeTypedArray(ctor)\n || ctor === DataView || ctor === ArrayBuffer;\n }\n //#endregion\n\n constructor(\n classType: Function,\n ) {\n this.classType = classType;\n }\n\n public dataMembers: Map = new Map();\n\n public knownTypes: Set = new Set();\n\n public knownTypeMethodName?: string;\n\n /** Gets or sets the constructor function for the jsonObject. */\n public classType: Function;\n\n /**\n * Indicates whether this class was explicitly annotated with @jsonObject\n * or implicitly by @jsonMember\n */\n public isExplicitlyMarked: boolean = false;\n\n /**\n * Indicates whether this type is handled without annotation. This is usually\n * used for the builtin types (except for Maps, Sets, and normal Arrays).\n */\n public isHandledWithoutAnnotation: boolean = false;\n\n /** Name used to encode polymorphic type */\n public name?: string;\n\n public onDeserializedMethodName?: string;\n\n public initializerCallback?: (sourceObject: Object, rawSourceObject: Object) => Object;\n}\n\nexport function injectMetadataInformation(constructor: IndexedObject, propKey: string | symbol, metadata: JsonMemberMetadata)\n{\n const decoratorName = `@jsonMember on ${nameof(constructor.constructor)}.${String(propKey)}`; // For error messages.\n let objectMetadata: JsonObjectMetadata;\n\n // When a property decorator is applied to a static member, 'constructor' is a constructor function.\n // See: https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Decorators.md#property-decorators\n // ... and static members are not supported here, so abort.\n if (typeof constructor === \"function\")\n {\n logError(`${decoratorName}: cannot use a static property.`);\n return;\n }\n\n // Methods cannot be serialized.\n // @ts-ignore symbol indexing is not supported by ts\n if (typeof constructor[propKey] === \"function\")\n {\n logError(`${decoratorName}: cannot use a method property.`);\n return;\n }\n\n if (!metadata || (!metadata.ctor && !metadata.deserializer))\n {\n logError(`${decoratorName}: JsonMemberMetadata has unknown ctor.`);\n return;\n }\n\n // Add jsonObject metadata to 'constructor' if not yet exists ('constructor' is the prototype).\n // NOTE: this will not fire up custom serialization, as 'constructor' must be explicitly marked with '@jsonObject' as well.\n if (!constructor.hasOwnProperty(METADATA_FIELD_KEY))\n {\n // No *own* metadata, create new.\n objectMetadata = new JsonObjectMetadata(constructor.constructor);\n\n // Inherit @JsonMembers from parent @jsonObject (if any).\n const parentMetadata: JsonObjectMetadata = constructor[METADATA_FIELD_KEY];\n if (parentMetadata) // && !constructor.hasOwnProperty(Helpers.METADATA_FIELD_KEY)\n {\n parentMetadata.dataMembers.forEach((_metadata, _propKey) => objectMetadata.dataMembers.set(_propKey, _metadata));\n }\n\n // ('constructor' is the prototype of the involved class, metadata information is added to this class prototype).\n Object.defineProperty(constructor, METADATA_FIELD_KEY, {\n enumerable: false,\n configurable: false,\n writable: false,\n value: objectMetadata\n });\n }\n else\n {\n // JsonObjectMetadata already exists on 'constructor'.\n objectMetadata = constructor[METADATA_FIELD_KEY];\n }\n\n if (!metadata.deserializer)\n {\n // @ts-ignore above is a check (!deser && !ctor)\n objectMetadata.knownTypes.add(metadata.ctor);\n }\n\n if (metadata.keyType)\n objectMetadata.knownTypes.add(metadata.keyType);\n\n if (metadata.elementType)\n metadata.elementType.forEach(elemCtor => objectMetadata.knownTypes.add(elemCtor));\n\n objectMetadata.dataMembers.set(metadata.name, metadata);\n}\n","import { nameof, logError, isSubtypeOf, isValueDefined } from \"./helpers\";\nimport { IndexedObject } from \"./types\";\nimport { JsonObjectMetadata } from \"./metadata\";\n\nexport interface IScopeTypeInfo\n{\n selfConstructor: Function;\n elementConstructor?: Function[];\n keyConstructor?: Function;\n knownTypes: Map;\n}\n\n/**\n * Utility class, converts a simple/untyped javascript object-tree to a typed object-tree.\n * It is used after parsing a JSON-string.\n */\nexport class Deserializer\n{\n private _typeResolver: (sourceObject: Object, knownTypes: Map) => Function|undefined;\n private _nameResolver?: (ctor: Function) => string;\n private _errorHandler: (error: Error) => void;\n\n constructor()\n {\n this._typeResolver = (sourceObject: any, knownTypes: Map) =>\n {\n if (sourceObject.__type) return knownTypes.get(sourceObject.__type);\n };\n\n this._errorHandler = (error) => logError(error);\n }\n\n public setNameResolver(nameResolverCallback: (ctor: Function) => string)\n {\n this._nameResolver = nameResolverCallback;\n }\n\n public setTypeResolver(typeResolverCallback: (sourceObject: Object, knownTypes: Map) => Function)\n {\n if (typeof typeResolverCallback !== \"function\") throw new TypeError(\"'typeResolverCallback' is not a function.\");\n\n this._typeResolver = typeResolverCallback;\n }\n\n public setErrorHandler(errorHandlerCallback: (error: Error) => void)\n {\n if (typeof errorHandlerCallback !== \"function\")\n {\n throw new TypeError(\"'errorHandlerCallback' is not a function.\");\n }\n\n this._errorHandler = errorHandlerCallback;\n }\n\n public convertAsObject(\n sourceObject: IndexedObject,\n sourceObjectTypeInfo: IScopeTypeInfo,\n objectName = \"object\",\n ) {\n if (typeof sourceObject !== \"object\" || sourceObject === null)\n {\n this._errorHandler(new TypeError(`Cannot deserialize ${objectName}: 'sourceObject' must be a defined object.`));\n return undefined;\n }\n\n let expectedSelfType = sourceObjectTypeInfo.selfConstructor;\n let sourceObjectMetadata = JsonObjectMetadata.getFromConstructor(expectedSelfType);\n let knownTypeConstructors = sourceObjectTypeInfo.knownTypes;\n\n if (sourceObjectMetadata)\n {\n // Merge known types received from \"above\" with known types defined on the current type.\n knownTypeConstructors = this._mergeKnownTypes(\n knownTypeConstructors,\n this._createKnownTypesMap(sourceObjectMetadata.knownTypes),\n );\n }\n\n // Check if a type-hint is available from the source object.\n let typeFromTypeHint = this._typeResolver(sourceObject, knownTypeConstructors);\n\n if (typeFromTypeHint)\n {\n // Check if type hint is a valid subtype of the expected source type.\n if (isSubtypeOf(typeFromTypeHint, expectedSelfType))\n {\n // Hell yes.\n expectedSelfType = typeFromTypeHint;\n sourceObjectMetadata = JsonObjectMetadata.getFromConstructor(typeFromTypeHint);\n\n if (sourceObjectMetadata)\n {\n // Also merge new known types from subtype.\n knownTypeConstructors = this._mergeKnownTypes(\n knownTypeConstructors,\n this._createKnownTypesMap(sourceObjectMetadata.knownTypes),\n );\n }\n }\n }\n\n if (sourceObjectMetadata && sourceObjectMetadata.isExplicitlyMarked)\n {\n const sourceMetadata = sourceObjectMetadata;\n // Strong-typed deserialization available, get to it.\n // First deserialize properties into a temporary object.\n const sourceObjectWithDeserializedProperties = {} as IndexedObject;\n\n // Deserialize by expected properties.\n sourceMetadata.dataMembers.forEach((memberMetadata, propKey) =>\n {\n const memberValue = sourceObject[propKey];\n const memberNameForDebug = `${nameof(sourceMetadata.classType)}.${propKey}`;\n\n let revivedValue;\n if (memberMetadata.deserializer) {\n revivedValue = memberMetadata.deserializer(memberValue);\n } else if (memberMetadata.ctor) {\n revivedValue = this.convertSingleValue(\n memberValue,\n {\n selfConstructor: memberMetadata.ctor,\n elementConstructor: memberMetadata.elementType,\n keyConstructor: memberMetadata.keyType,\n knownTypes: knownTypeConstructors\n },\n memberNameForDebug,\n );\n } else {\n throw new TypeError(\n `Cannot deserialize ${memberNameForDebug} thers is`\n + ` no constructor nor deserlization function to use.`,\n );\n }\n\n if (isValueDefined(revivedValue))\n {\n sourceObjectWithDeserializedProperties[memberMetadata.key] = revivedValue;\n }\n else if (memberMetadata.isRequired)\n {\n this._errorHandler(new TypeError(`Missing required member '${memberNameForDebug}'.`));\n }\n });\n\n // Next, instantiate target object.\n let targetObject: IndexedObject;\n\n if (typeof sourceObjectMetadata.initializerCallback === \"function\")\n {\n try\n {\n targetObject = sourceObjectMetadata.initializerCallback(\n sourceObjectWithDeserializedProperties,\n sourceObject,\n );\n\n // Check the validity of user-defined initializer callback.\n if (!targetObject)\n {\n throw new TypeError(\n `Cannot deserialize ${objectName}:`\n + ` 'initializer' function returned undefined/null`\n + `, but '${nameof(sourceObjectMetadata.classType)}' was expected.`,\n );\n }\n else if (!(targetObject instanceof sourceObjectMetadata.classType))\n {\n throw new TypeError(\n `Cannot deserialize ${objectName}:`\n + `'initializer' returned '${nameof(targetObject.constructor)}'`\n + `, but '${nameof(sourceObjectMetadata.classType)}' was expected,`\n + `and '${nameof(targetObject.constructor)}' is not a subtype of`\n + ` '${nameof(sourceObjectMetadata.classType)}'`,\n );\n }\n }\n catch (e)\n {\n this._errorHandler(e);\n return undefined;\n }\n }\n else\n {\n targetObject = this._instantiateType(expectedSelfType);\n }\n\n // Finally, assign deserialized properties to target object.\n Object.assign(targetObject, sourceObjectWithDeserializedProperties);\n\n // Call onDeserialized method (if any).\n if (sourceObjectMetadata.onDeserializedMethodName)\n {\n if (typeof (targetObject.constructor as any)[sourceObjectMetadata.onDeserializedMethodName] === \"function\")\n {\n (targetObject.constructor as any)[sourceObjectMetadata.onDeserializedMethodName]();\n }\n else\n {\n this._errorHandler(new TypeError(\n `onDeserialized callback '${nameof(sourceObjectMetadata.classType)}.${sourceObjectMetadata.onDeserializedMethodName}' is not a method.`\n ));\n }\n }\n\n return targetObject;\n }\n else\n {\n // Untyped deserialization into Object instance.\n let targetObject = {} as IndexedObject;\n\n Object.keys(sourceObject).forEach(sourceKey =>\n {\n targetObject[sourceKey] = this.convertSingleValue(sourceObject[sourceKey], {\n selfConstructor: sourceObject[sourceKey].constructor,\n knownTypes: sourceObjectTypeInfo.knownTypes,\n elementConstructor: sourceObjectTypeInfo.elementConstructor,\n keyConstructor: sourceObjectTypeInfo.keyConstructor\n }, sourceKey);\n });\n\n return targetObject;\n }\n }\n\n public convertSingleValue(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\")\n {\n let expectedSelfType = typeInfo.selfConstructor;\n let srcTypeNameForDebug = sourceObject ? nameof(sourceObject.constructor) : \"undefined\";\n\n if (!isValueDefined(sourceObject))\n {\n return sourceObject;\n }\n else if (this._isDirectlyDeserializableNativeType(expectedSelfType))\n {\n if (sourceObject.constructor === expectedSelfType)\n {\n return sourceObject;\n }\n else\n {\n throw new TypeError(this._makeTypeErrorMessage(nameof(expectedSelfType), sourceObject.constructor, memberName));\n }\n }\n else if (expectedSelfType === Date)\n {\n // Support for Date with ISO 8601 format, or with numeric timestamp (milliseconds elapsed since the Epoch).\n // ISO 8601 spec.: https://www.w3.org/TR/NOTE-datetime\n\n if (typeof sourceObject === \"string\" || (typeof sourceObject === \"number\" && sourceObject > 0))\n return new Date(sourceObject as any);\n else\n this._throwTypeMismatchError(\"Date\", \"an ISO-8601 string\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Float32Array)\n {\n // Deserialize Float32Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Float32Array(sourceObject);\n else\n this._throwTypeMismatchError(\"Float32Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Float64Array)\n {\n // Deserialize Float64Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Float64Array(sourceObject);\n else\n this._throwTypeMismatchError(\"Float64Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint8Array)\n {\n // Deserialize Uint8Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint8Array(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint8Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint8ClampedArray)\n {\n // Deserialize Uint8Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint8ClampedArray(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint8ClampedArray\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint16Array)\n {\n // Deserialize Uint16Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint16Array(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint16Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint32Array)\n {\n // Deserialize Uint32Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint32Array(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint32Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === ArrayBuffer)\n {\n if (typeof sourceObject === \"string\")\n return this._stringToArrayBuffer(sourceObject);\n else\n this._throwTypeMismatchError(\"ArrayBuffer\", \"a string source\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === DataView)\n {\n if (typeof sourceObject === \"string\")\n return this._stringToDataView(sourceObject);\n else\n this._throwTypeMismatchError(\"DataView\", \"a string source\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Array)\n {\n if (sourceObject instanceof Array)\n return this.convertAsArray(sourceObject, typeInfo, memberName);\n else\n throw new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName));\n }\n else if (expectedSelfType === Set)\n {\n if (sourceObject instanceof Array)\n return this.convertAsSet(sourceObject, typeInfo, memberName);\n else\n this._throwTypeMismatchError(\"Set\", \"Array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Map)\n {\n if (sourceObject instanceof Array)\n return this.convertAsMap(sourceObject, typeInfo, memberName);\n else\n this._throwTypeMismatchError(\"Map\", \"a source array of key-value-pair objects\", srcTypeNameForDebug, memberName);\n }\n else if (sourceObject && typeof sourceObject === \"object\")\n {\n return this.convertAsObject(sourceObject, typeInfo, memberName);\n }\n }\n\n public convertAsArray(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\"): any[]\n {\n if (!(sourceObject instanceof Array))\n {\n this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)));\n return [];\n }\n\n if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Array: missing constructor reference of Array elements.`));\n return [];\n }\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.elementConstructor[0],\n elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [],\n knownTypes: typeInfo.knownTypes\n };\n\n return sourceObject.map(element =>\n {\n // If an array element fails to deserialize, substitute with undefined. This is so that the original ordering is not interrupted by faulty\n // entries, as an Array is ordered.\n try\n {\n return this.convertSingleValue(element, elementTypeInfo);\n }\n catch (e)\n {\n this._errorHandler(e);\n\n // Keep filling the array here with undefined to keep original ordering.\n // Note: this is just aesthetics, not returning anything produces the same result.\n return undefined;\n }\n });\n }\n\n public convertAsSet(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\")\n {\n if (!(sourceObject instanceof Array))\n {\n this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)));\n return new Set();\n }\n\n if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Set: missing constructor reference of Set elements.`));\n return new Set();\n }\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.elementConstructor[0],\n elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [],\n knownTypes: typeInfo.knownTypes\n };\n let resultSet = new Set();\n\n sourceObject.forEach((element, i) =>\n {\n try\n {\n resultSet.add(this.convertSingleValue(element, elementTypeInfo, memberName + `[${i}]`));\n }\n catch (e)\n {\n // Faulty entries are skipped, because a Set is not ordered, and skipping an entry does not affect others.\n this._errorHandler(e);\n }\n });\n\n return resultSet;\n }\n\n public convertAsMap(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\")\n {\n if (!(sourceObject instanceof Array))\n this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)));\n\n if (!typeInfo.keyConstructor)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Map: missing key constructor.`));\n return new Map();\n }\n\n if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Map: missing value constructor.`));\n return new Map();\n }\n\n let keyTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.keyConstructor,\n knownTypes: typeInfo.knownTypes\n };\n\n let valueTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.elementConstructor[0],\n elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [],\n knownTypes: typeInfo.knownTypes\n };\n\n let resultMap = new Map();\n\n sourceObject.forEach((element: any) =>\n {\n try\n {\n let key = this.convertSingleValue(element.key, keyTypeInfo);\n\n // Undefined/null keys not supported, skip if so.\n if (isValueDefined(key))\n {\n resultMap.set(key, this.convertSingleValue(\n element.value, valueTypeInfo, `${memberName}[${key}]`,\n ));\n }\n }\n catch (e)\n {\n // Faulty entries are skipped, because a Map is not ordered,\n // and skipping an entry does not affect others.\n this._errorHandler(e);\n }\n });\n\n return resultMap;\n }\n\n private _throwTypeMismatchError(\n targetType: string,\n expectedSourceType: string,\n actualSourceType: string,\n memberName: string = \"object\",\n ) {\n throw new TypeError(\n `Could not deserialize ${memberName} as ${targetType}:`\n + ` expected ${expectedSourceType}, got ${actualSourceType}.`,\n );\n }\n\n private _makeTypeErrorMessage(expectedType: Function | string, actualType: Function | string, memberName = \"object\")\n {\n let expectedTypeName = (typeof expectedType === \"function\") ? nameof(expectedType) : expectedType;\n let actualTypeName = (typeof actualType === \"function\") ? nameof(actualType) : actualType;\n\n return `Could not deserialize ${memberName}: expected '${expectedTypeName}', got '${actualTypeName}'.`;\n }\n\n private _instantiateType(ctor: any)\n {\n return new ctor();\n }\n\n private _mergeKnownTypes(...knownTypeMaps: Array>)\n {\n let result = new Map();\n\n knownTypeMaps.forEach(knownTypes =>\n {\n knownTypes.forEach((ctor, name) =>\n {\n if (this._nameResolver)\n {\n result.set(this._nameResolver(ctor), ctor);\n }\n else\n {\n result.set(name, ctor);\n }\n });\n });\n\n return result;\n }\n\n private _createKnownTypesMap(knowTypes: Set)\n {\n const map = new Map();\n\n knowTypes.forEach(ctor =>\n {\n if (this._nameResolver)\n {\n map.set(this._nameResolver(ctor), ctor);\n }\n else\n {\n const knownTypeMeta = JsonObjectMetadata.getFromConstructor(ctor);\n const name = knownTypeMeta && knownTypeMeta.isExplicitlyMarked && knownTypeMeta.name\n ? knownTypeMeta.name\n : ctor.name;\n map.set(name, ctor);\n }\n });\n\n return map;\n }\n\n private _isDirectlyDeserializableNativeType(ctor: any)\n {\n return ~([Number, String, Boolean].indexOf(ctor));\n }\n\n public convertNativeObject(sourceObject: any)\n {\n return sourceObject;\n }\n\n private _stringToArrayBuffer(str: string)\n {\n let buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char\n let bufView = new Uint16Array(buf);\n\n for (let i = 0, strLen = str.length; i < strLen; i++)\n {\n bufView[i] = str.charCodeAt(i);\n }\n\n return buf;\n }\n\n private _stringToDataView(str: string)\n {\n return new DataView(this._stringToArrayBuffer(str));\n }\n}\n","import { nameof, logError, isValueDefined, isInstanceOf, isTypeTypedArray, isDirectlySerializableNativeType } from \"./helpers\";\nimport { IndexedObject } from \"./types\";\nimport { JsonObjectMetadata } from \"./metadata\";\n\nexport interface IScopeTypeInfo\n{\n selfType: Function;\n elementTypes?: Function[];\n keyType?: Function;\n}\n\nexport interface IScopeArrayTypeInfo extends IScopeTypeInfo\n{\n selfType: new () => Array;\n elementTypes: Function[];\n}\n\nfunction isArrayTypeInfo(typeInfo: IScopeTypeInfo): typeInfo is IScopeArrayTypeInfo {\n return typeInfo.selfType === Array;\n}\n\nexport interface IScopeSetTypeInfo extends IScopeTypeInfo\n{\n selfType: new () => Set;\n elementTypes: [Function];\n}\n\nfunction isSetTypeInfo(typeInfo: IScopeTypeInfo): typeInfo is IScopeSetTypeInfo {\n return typeInfo.selfType === Set;\n}\n\nexport interface IScopeMapTypeInfo extends IScopeTypeInfo\n{\n selfType: new () => Map;\n elementTypes: [Function];\n keyType: Function;\n}\n\nfunction isMapTypeInfo(typeInfo: IScopeTypeInfo): typeInfo is IScopeMapTypeInfo {\n return typeInfo.selfType === Map;\n}\n\n/**\n * Utility class, converts a typed object tree (i.e. a tree of class instances, arrays of class instances, and so on) to an untyped javascript object (also\n * called \"simple javascript object\"), and emits any necessary type hints in the process (for polymorphism).\n *\n * The converted object tree is what will be given to `JSON.stringify` to convert to string as the last step, the serialization is basically like:\n *\n * (1) typed object-tree -> (2) simple JS object-tree -> (3) JSON-string\n */\nexport class Serializer\n{\n private _typeHintEmitter: (targetObject: IndexedObject, sourceObject: IndexedObject, expectedSourceType: Function, sourceTypeMetadata?: JsonObjectMetadata) => void;\n private _errorHandler: (error: Error) => void;\n\n constructor()\n {\n this._typeHintEmitter = (targetObject, sourceObject, expectedSourceType, sourceTypeMetadata?: JsonObjectMetadata) =>\n {\n // By default, we put a \"__type\" property on the output object if the actual object is not the same as the expected one, so that deserialization\n // will know what to deserialize into (given the required known-types are defined, and the object is a valid subtype of the expected type).\n if (sourceObject.constructor !== expectedSourceType)\n {\n const name = sourceTypeMetadata && sourceTypeMetadata.name\n ? sourceTypeMetadata.name\n : nameof(sourceObject.constructor);\n // TODO: Perhaps this can work correctly without string-literal access?\n // tslint:disable-next-line:no-string-literal\n targetObject[\"__type\"] = name;\n }\n };\n\n this._errorHandler = (error) => logError(error);\n }\n\n public setTypeHintEmitter(typeEmitterCallback: (targetObject: Object, sourceObject: Object, expectedSourceType: Function) => void)\n {\n if (typeof typeEmitterCallback !== \"function\")\n {\n throw new TypeError(\"'typeEmitterCallback' is not a function.\");\n }\n\n this._typeHintEmitter = typeEmitterCallback;\n }\n\n public setErrorHandler(errorHandlerCallback: (error: Error) => void)\n {\n if (typeof errorHandlerCallback !== \"function\")\n {\n throw new TypeError(\"'errorHandlerCallback' is not a function.\");\n }\n\n this._errorHandler = errorHandlerCallback;\n }\n\n /**\n * Convert a value of any supported serializable type.\n * The value type will be detected, and the correct serialization method will be called.\n */\n public convertSingleValue(sourceObject: any, typeInfo: IScopeTypeInfo, memberName: string = \"object\"): any\n {\n if (!isValueDefined(sourceObject)) return;\n\n if (!isInstanceOf(sourceObject, typeInfo.selfType))\n {\n let expectedName = nameof(typeInfo.selfType);\n let actualName = nameof(sourceObject.constructor);\n\n this._errorHandler(new TypeError(`Could not serialize '${memberName}': expected '${expectedName}', got '${actualName}'.`));\n return;\n }\n\n if (isDirectlySerializableNativeType(typeInfo.selfType))\n {\n return sourceObject;\n }\n else if (typeInfo.selfType === ArrayBuffer)\n {\n return this.convertAsArrayBuffer(sourceObject);\n }\n else if (typeInfo.selfType === DataView)\n {\n return this.convertAsDataView(sourceObject);\n }\n else if (isArrayTypeInfo(typeInfo))\n {\n return this.convertAsArray(sourceObject, typeInfo.elementTypes, memberName);\n }\n else if (isSetTypeInfo(typeInfo))\n {\n return this.convertAsSet(sourceObject, typeInfo.elementTypes[0], memberName);\n }\n else if (isMapTypeInfo(typeInfo))\n {\n return this.convertAsMap(sourceObject, typeInfo.keyType, typeInfo.elementTypes[0], memberName);\n }\n else if (isTypeTypedArray(typeInfo.selfType))\n {\n return this.convertAsTypedArray(sourceObject);\n }\n else if (typeof sourceObject === \"object\")\n {\n return this.convertAsObject(sourceObject, typeInfo, memberName);\n }\n }\n\n /**\n * Performs the conversion of a typed object (usually a class instance) to a simple javascript object for serialization.\n */\n public convertAsObject(sourceObject: IndexedObject, typeInfo: IScopeTypeInfo, memberName?: string)\n {\n let sourceTypeMetadata: JsonObjectMetadata|undefined;\n let targetObject: IndexedObject;\n\n if (sourceObject.constructor !== typeInfo.selfType && sourceObject instanceof typeInfo.selfType)\n {\n // The source object is not of the expected type, but it is a valid subtype.\n // This is OK, and we'll proceed to gather object metadata from the subtype instead.\n sourceTypeMetadata = JsonObjectMetadata.getFromConstructor(sourceObject.constructor);\n }\n else\n {\n sourceTypeMetadata = JsonObjectMetadata.getFromConstructor(typeInfo.selfType);\n }\n\n if (sourceTypeMetadata)\n {\n const sourceMeta = sourceTypeMetadata;\n // Strong-typed serialization available.\n // We'll serialize by members that have been marked with @jsonMember (including array/set/map members), and perform recursive conversion on\n // each of them. The converted objects are put on the 'targetObject', which is what will be put into 'JSON.stringify' finally.\n targetObject = {};\n\n sourceTypeMetadata.dataMembers.forEach((memberMetadata) =>\n {\n if (memberMetadata.serializer) {\n targetObject[memberMetadata.name] =\n memberMetadata.serializer(sourceObject[memberMetadata.key]);\n } else if (memberMetadata.ctor) {\n targetObject[memberMetadata.name] = this.convertSingleValue(\n sourceObject[memberMetadata.key],\n {\n selfType: memberMetadata.ctor,\n elementTypes: memberMetadata.elementType,\n keyType: memberMetadata.keyType,\n },\n `${nameof(sourceMeta.classType)}.${memberMetadata.key}`,\n );\n } else {\n throw new TypeError(\n `Could not serialize ${memberMetadata.name}, there is`\n + ` no constructor nor serialization function to use.`,\n );\n }\n });\n }\n else\n {\n // Untyped serialization, \"as-is\", we'll just pass the object on.\n // We'll clone the source object, because type hints are added to the object itself, and we don't want to modify to the original object.\n targetObject = { ...sourceObject };\n }\n\n // Add type-hint.\n this._typeHintEmitter(targetObject, sourceObject, typeInfo.selfType, sourceTypeMetadata);\n\n return targetObject;\n }\n\n /**\n * Performs the conversion of an array of typed objects (or primitive values) to an array of simple javascript objects (or primitive values) for\n * serialization.\n * @param expectedElementType The expected type of elements. If the array is supposed to be multi-dimensional, subsequent elements define lower dimensions.\n * @param memberName Name of the object being serialized, used for debugging purposes.\n */\n public convertAsArray(sourceObject: any[], expectedElementType: Function[], memberName = \"object\"): any[]\n {\n if (expectedElementType.length === 0 || !expectedElementType[0])\n throw new TypeError(`Could not serialize ${memberName} as Array: missing element type definition.`);\n\n // Check the type of each element, individually.\n // If at least one array element type is incorrect, we return undefined, which results in no value emitted during serialization.\n // This is so that invalid element types don't unexpectedly alter the ordering of other, valid elements, and that no unexpected undefined values are in\n // the emitted array.\n sourceObject.forEach((element, i) =>\n {\n if (!isInstanceOf(element, expectedElementType[0]))\n {\n const expectedTypeName = nameof(expectedElementType[0]);\n const actualTypeName = nameof(element.constructor);\n throw new TypeError(`Could not serialize ${memberName}[${i}]: expected '${expectedTypeName}', got '${actualTypeName}'.`);\n }\n });\n\n const typeInfoForElements: IScopeTypeInfo = {\n selfType: expectedElementType[0],\n elementTypes: expectedElementType.length > 1 ? expectedElementType.slice(1) : [], // For multidimensional arrays.\n };\n\n if (memberName)\n {\n // Just for debugging purposes.\n memberName += \"[]\";\n }\n\n return sourceObject.map(element => this.convertSingleValue(element, typeInfoForElements, memberName));\n }\n\n /**\n * Performs the conversion of a set of typed objects (or primitive values) into an array of simple javascript objects.\n *\n * @param sourceObject\n * @param expectedElementType The constructor of the expected Set elements (e.g. `Number` for `Set`, or `MyClass` for `Set`).\n * @param memberName Name of the object being serialized, used for debugging purposes.\n * @returns\n */\n public convertAsSet(sourceObject: Set, expectedElementType: Function, memberName = \"object\"): any[]\n {\n if (!expectedElementType)\n throw new TypeError(`Could not serialize ${memberName} as Set: missing element type definition.`);\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfType: expectedElementType,\n };\n\n // For debugging and error tracking.\n if (memberName) memberName += \"[]\";\n\n let resultArray: any[] = [];\n\n // Convert each element of the set, and put it into an output array.\n // The output array is the one serialized, as JSON.stringify does not support Set serialization. (TODO: clarification needed)\n sourceObject.forEach(element =>\n {\n let resultElement = this.convertSingleValue(element, elementTypeInfo, memberName);\n\n // Add to output if the source element was undefined, OR the converted element is defined. This will add intentionally undefined values to output,\n // but not values that became undefined DURING serializing (usually because of a type-error).\n if (!isValueDefined(element) || isValueDefined(resultElement))\n {\n resultArray.push(resultElement);\n }\n });\n\n return resultArray;\n }\n\n /**\n * Performs the conversion of a map of typed objects (or primitive values) into an array of simple javascript objects with `key` and `value` properties.\n *\n * @param sourceObject\n * @param expectedKeyType The constructor of the expected Map keys (e.g. `Number` for `Map`, or `MyClass` for `Map`).\n * @param expectedElementType The constructor of the expected Map values (e.g. `Number` for `Map`, or `MyClass` for `Map`).\n * @param memberName Name of the object being serialized, used for debugging purposes.\n */\n public convertAsMap(sourceObject: Map, expectedKeyType: Function, expectedElementType: Function, memberName = \"object\"): Array<{ key: any, value: any }>\n {\n if (!expectedElementType)\n throw new TypeError(`Could not serialize ${memberName} as Map: missing value type definition.`);\n\n if (!expectedKeyType)\n throw new TypeError(`Could not serialize ${memberName} as Map: missing key type definition.`);\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfType: expectedElementType,\n elementTypes: [expectedElementType]\n };\n\n let keyTypeInfo: IScopeTypeInfo = {\n selfType: expectedKeyType\n };\n\n if (memberName) memberName += \"[]\";\n\n let resultArray: Array<{ key: any, value: any }> = [];\n\n // Convert each *entry* in the map to a simple javascript object with key and value properties.\n sourceObject.forEach((value, key) =>\n {\n let resultKeyValuePairObj = {\n key: this.convertSingleValue(key, keyTypeInfo, memberName),\n value: this.convertSingleValue(value, elementTypeInfo, memberName)\n };\n\n // We are not going to emit entries with undefined keys OR undefined values.\n if (isValueDefined(resultKeyValuePairObj.key) && isValueDefined(resultKeyValuePairObj.value))\n {\n resultArray.push(resultKeyValuePairObj);\n }\n });\n\n return resultArray;\n }\n\n /**\n * Performs the conversion of a typed javascript array to a simple untyped javascript array.\n * This is needed because typed arrays are otherwise serialized as objects, so we'll end up with something like \"{ 0: 0, 1: 1, ... }\".\n *\n * @param sourceObject\n * @returns\n */\n public convertAsTypedArray(sourceObject: ArrayBufferView)\n {\n return Array.from(sourceObject as any);\n }\n\n /**\n * Performs the conversion of a raw ArrayBuffer to a string.\n */\n public convertAsArrayBuffer(buffer: ArrayBuffer)\n {\n // ArrayBuffer -> 16-bit character codes -> character array -> joined string.\n return Array.from(new Uint16Array(buffer)).map(charCode => String.fromCharCode(charCode)).join(\"\");\n }\n\n /**\n * Performs the conversion of DataView, converting its internal ArrayBuffer to a string and returning that string.\n */\n public convertAsDataView(dataView: DataView)\n {\n return this.convertAsArrayBuffer(dataView.buffer);\n }\n}\n","import { Constructor, ParameterlessConstructor } from \"./types\";\nimport { METADATA_FIELD_KEY } from \"./helpers\";\nimport { JsonObjectMetadata } from \"./metadata\";\n\nexport interface IJsonObjectOptionsBase\n{\n /**\n * An array of known types to recognize when encountering type-hints,\n * or the name of a static method used for determining known types.\n */\n knownTypes?: Function[] | string;\n\n /**\n * The name of a static or instance method to call when deserialization\n * of the object is completed.\n */\n onDeserialized?: string;\n\n /**\n * The name used to differentiate between different polymorphic types.\n */\n name?: string;\n}\n\nexport interface IJsonObjectOptionsWithInitializer extends IJsonObjectOptionsBase\n{\n /**\n * The name of a static method to call before deserializing and initializing the object, accepting two arguments: (1) sourceObject, an 'Object' instance\n * with all properties already deserialized, and (2) rawSourceObject, a raw 'Object' instance representation of the current object in the serialized JSON\n * (i.e. without deserialized properties).\n */\n initializer: (sourceObject: T, rawSourceObject: T) => T;\n}\n\nexport interface IJsonObjectOptions extends IJsonObjectOptionsBase\n{\n /**\n * The name of a static method to call before deserializing and initializing the object, accepting two arguments: (1) sourceObject, an 'Object' instance\n * with all properties already deserialized, and (2) rawSourceObject, a raw 'Object' instance representation of the current object in the serialized JSON\n * (i.e. without deserialized properties).\n */\n initializer?: (sourceObject: T, rawSourceObject: T) => T;\n}\n\n/**\n * Marks that a class with a parameterized constructor is serializable using TypedJSON, with additional settings. The 'initializer' setting must be specified.\n * @param options Configuration settings.\n */\nexport function jsonObject(options?: IJsonObjectOptionsWithInitializer): (target: Constructor) => void;\n\n/**\n * Marks that a class is serializable using TypedJSON, with additional settings.\n * @param options Configuration settings.\n */\nexport function jsonObject(options?: IJsonObjectOptions): (target: ParameterlessConstructor) => void;\n\n/**\n * Marks that a class with a parameterless constructor is serializable using TypedJSON.\n */\nexport function jsonObject(target: ParameterlessConstructor): void;\n\nexport function jsonObject(optionsOrTarget?: IJsonObjectOptions | Constructor\n): ((target: Constructor) => void) | void {\n let options: IJsonObjectOptions;\n\n if (typeof optionsOrTarget === \"function\")\n {\n // jsonObject is being used as a decorator, directly.\n options = {};\n }\n else\n {\n // jsonObject is being used as a decorator factory.\n options = optionsOrTarget || {};\n }\n\n function decorator(\n target: Function\n ): void {\n let objectMetadata: JsonObjectMetadata;\n\n // Create or obtain JsonObjectMetadata object.\n if (!target.prototype.hasOwnProperty(METADATA_FIELD_KEY))\n {\n // Target has no JsonObjectMetadata associated with it yet, create it now.\n objectMetadata = new JsonObjectMetadata(target);\n\n // Inherit json members and known types from parent @jsonObject (if any).\n const parentMetadata: JsonObjectMetadata = target.prototype[METADATA_FIELD_KEY];\n if (parentMetadata)\n {\n parentMetadata.dataMembers\n .forEach((memberMetadata, propKey) =>\n objectMetadata.dataMembers.set(propKey, memberMetadata));\n parentMetadata.knownTypes\n .forEach((knownType) => objectMetadata.knownTypes.add(knownType));\n }\n\n Object.defineProperty(target.prototype, METADATA_FIELD_KEY, {\n enumerable: false,\n configurable: false,\n writable: false,\n value: objectMetadata\n });\n }\n else\n {\n // Target already has JsonObjectMetadata associated with it.\n objectMetadata = target.prototype[METADATA_FIELD_KEY];\n objectMetadata.classType = target;\n }\n\n // Fill JsonObjectMetadata.\n objectMetadata.isExplicitlyMarked = true;\n objectMetadata.onDeserializedMethodName = options.onDeserialized;\n // T extend Object so it is fine\n objectMetadata.initializerCallback = options.initializer as any;\n if (options.name)\n {\n objectMetadata.name = options.name;\n }\n\n // Obtain known-types.\n if (typeof options.knownTypes === \"string\")\n {\n objectMetadata.knownTypeMethodName = options.knownTypes;\n }\n else if (options.knownTypes instanceof Array)\n {\n options.knownTypes\n .filter(knownType => !!knownType)\n .forEach(knownType => objectMetadata.knownTypes.add(knownType));\n }\n }\n\n if (typeof optionsOrTarget === \"function\")\n {\n // jsonObject is being used as a decorator, directly.\n decorator(optionsOrTarget);\n }\n else\n {\n // jsonObject is being used as a decorator factory.\n return decorator;\n }\n}\n","import {\n nameof, logError, isReflectMetadataSupported, isValueDefined, logWarning, isSubtypeOf\n} from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonMemberOptions\n{\n /**\n * Sets the constructor of the property.\n * Optional with ReflectDecorators.\n */\n constructor?: Function;\n\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, a default value is emitted if the property is uninitialized/undefined. */\n emitDefaultValue?: boolean;\n\n /** When set, the key on the JSON that should be used instead of the class property name. */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that a property is part of the object when serializing, with additional options.\n * Omitting the 'constructor' option requires ReflectDecorators and that the property type is always explicitly declared.\n * @param options Additional options.\n */\nexport function jsonMember(options: IJsonMemberOptions): PropertyDecorator;\n\n/**\n * Specifies that a property is part of the object when serializing.\n * This call signature requires ReflectDecorators and that the property type is always explicitly declared.\n */\nexport function jsonMember(target: Object, propertyKey: string | symbol): void;\n\nexport function jsonMember(optionsOrTarget?: IJsonMemberOptions | Object, propKey?: string | symbol): PropertyDecorator | void\n{\n if (optionsOrTarget instanceof Object && (typeof propKey === \"string\" || typeof propKey === \"symbol\"))\n {\n const target = optionsOrTarget as Object;\n // For error messages.\n const decoratorName = `@jsonMember on ${nameof(target.constructor)}.${String(propKey)}`;\n\n // jsonMember used directly, no additional information directly available besides target and propKey.\n // Obtain property constructor through ReflectDecorators.\n if (isReflectMetadataSupported)\n {\n const reflectPropCtor = Reflect.getMetadata(\"design:type\", target, propKey) as Function;\n\n if (!reflectPropCtor)\n {\n logError(`${decoratorName}: could not resolve detected property constructor at runtime.`);\n return;\n }\n\n if (isSpecialPropertyType(decoratorName, reflectPropCtor))\n {\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: reflectPropCtor,\n key: propKey.toString(),\n name: propKey.toString(),\n });\n }\n else\n {\n logError(`${decoratorName}: ReflectDecorators is required if no 'constructor' option is specified.`);\n return;\n }\n }\n else\n {\n // jsonMember used as a decorator factory.\n return (target: Object, _propKey: string | symbol) =>\n {\n let options: IJsonMemberOptions = optionsOrTarget || {};\n let propCtor: Function|undefined;\n let decoratorName = `@jsonMember on ${nameof(target.constructor)}.${String(_propKey)}`; // For error messages.\n\n if (options.hasOwnProperty(\"constructor\"))\n {\n if (!isValueDefined(options.constructor))\n {\n logError(`${decoratorName}: cannot resolve specified property constructor at runtime.`);\n return;\n }\n\n // Property constructor has been specified. Use ReflectDecorators (if available) to check whether that constructor is correct. Warn if not.\n if (isReflectMetadataSupported && !isSubtypeOf(options.constructor, Reflect.getMetadata(\"design:type\", target, _propKey)))\n {\n logWarning(`${decoratorName}: detected property type does not match 'constructor' option.`);\n }\n\n propCtor = options.constructor;\n }\n else\n {\n // Use ReflectDecorators to obtain property constructor.\n if (isReflectMetadataSupported)\n {\n propCtor = Reflect.getMetadata(\"design:type\", target, _propKey) as Function;\n\n if (!propCtor)\n {\n logError(`${decoratorName}: cannot resolve detected property constructor at runtime.`);\n return;\n }\n }\n else if (!options.deserializer)\n {\n logError(`${decoratorName}: ReflectDecorators is required if no 'constructor' option is specified.`);\n return;\n }\n }\n\n if (isSpecialPropertyType(decoratorName, propCtor))\n {\n return;\n }\n\n injectMetadataInformation(target, _propKey, {\n ctor: propCtor,\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: _propKey.toString(),\n name: options.name || _propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n }\n}\n\nfunction isSpecialPropertyType(decoratorName: string, propCtor?: Function)\n{\n if (propCtor === Array)\n {\n logError(`${decoratorName}: property is an Array. Use the jsonArrayMember decorator to`\n + ` serialize this property.`);\n return true;\n }\n\n if (propCtor === Set)\n {\n logError(`${decoratorName}: property is a Set. Use the jsonSetMember decorator to`\n + ` serialize this property.`);\n return true;\n }\n\n if (propCtor === Map)\n {\n logError(`${decoratorName}: property is a Map. Use the jsonMapMember decorator to`\n + ` serialize this property.`);\n return true;\n }\n\n return false;\n}\n","import { nameof, logError, isReflectMetadataSupported } from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonArrayMemberOptions\n{\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, an empty array is emitted if the property is undefined/uninitialized. */\n emitDefaultValue?: boolean;\n\n /** Sets array dimensions (e.g. 1 for 'number[]' or 2 for 'number[][]'). Defaults to 1. */\n dimensions?: number;\n\n /** When set, the key on the JSON that should be used instead of the class property name */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that a property, of type array, is part of an object when serializing.\n * @param elementConstructor Constructor of array elements (e.g. 'Number' for 'number[]', or 'Date' for 'Date[]').\n * @param options Additional options.\n */\nexport function jsonArrayMember(elementConstructor: Function, options: IJsonArrayMemberOptions = {})\n{\n return (target: Object, propKey: string | symbol) =>\n {\n let decoratorName = `@jsonArrayMember on ${nameof(target.constructor)}.${String(propKey)}`; // For error messages.\n\n if (typeof elementConstructor !== \"function\")\n {\n logError(`${decoratorName}: could not resolve constructor of array elements at runtime.`);\n return;\n }\n\n const dimensions = options.dimensions === undefined ? 1 : options.dimensions;\n if (!isNaN(dimensions) && dimensions < 1)\n {\n logError(`${decoratorName}: 'dimensions' option must be at least 1.`);\n return;\n }\n\n // If ReflectDecorators is available, use it to check whether 'jsonArrayMember' has been used on an array.\n if (isReflectMetadataSupported && Reflect.getMetadata(\"design:type\", target, propKey) !== Array)\n {\n logError(`${decoratorName}: property is not an Array.`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Array,\n elementType: createArrayElementType(elementConstructor, dimensions),\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: propKey.toString(),\n name: options.name || propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n}\n\nfunction createArrayElementType(elementCtor: Function, dimensions: number) {\n const elementTypes = new Array(dimensions).fill(Array, 0, -1);\n elementTypes[dimensions-1] = elementCtor;\n return elementTypes;\n}\n","import { nameof } from \"./helpers\";\nimport { IJsonMemberOptions } from \"./json-member\";\nimport { JsonMemberMetadata, JsonObjectMetadata, injectMetadataInformation } from \"./metadata\";\nimport * as Helpers from \"./helpers\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonSetMemberOptions\n{\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, a default value is emitted for each uninitialized json member. */\n emitDefaultValue?: boolean;\n\n /** When set, the key on the JSON that should be used instead of the class property name */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that the property is part of the object when serializing.\n * Use this decorator on properties of type Set.\n * @param elementConstructor Constructor of set elements (e.g. 'Number' for Set or 'Date' for Set).\n * @param options Additional options.\n */\nexport function jsonSetMember(elementConstructor: Function, options: IJsonSetMemberOptions = {})\n{\n return (target: Object, propKey: string | symbol) =>\n {\n var decoratorName = `@jsonSetMember on ${nameof(target.constructor)}.${String(propKey)}`; // For error messages.\n\n if (typeof elementConstructor !== \"function\")\n {\n Helpers.logError(`${decoratorName}: could not resolve constructor of set elements at runtime.`);\n return;\n }\n\n // If ReflectDecorators is available, use it to check whether 'jsonSetMember' has been used on a set. Warn if not.\n if (Helpers.isReflectMetadataSupported && Reflect.getMetadata(\"design:type\", target, propKey) !== Set)\n {\n Helpers.logError(`${decoratorName}: property is not a Set.`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Set,\n elementType: [elementConstructor],\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: propKey.toString(),\n name: options.name || propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n}\n","import { nameof, logError, isReflectMetadataSupported } from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonMapMemberOptions\n{\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, a default value is emitted for each uninitialized json member. */\n emitDefaultValue?: boolean;\n\n /** When set, the key on the JSON that should be used instead of the class property name */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that the property is part of the object when serializing.\n * Use this decorator on properties of type Map.\n * @param keyConstructor Constructor of map keys (e.g. 'Number' for 'Map').\n * @param valueConstructor Constructor of map values (e.g. 'Date' for 'Map').\n * @param options Additional options.\n */\nexport function jsonMapMember(keyConstructor: Function, valueConstructor: Function, options: IJsonMapMemberOptions = {})\n{\n return (target: Object, propKey: string | symbol) =>\n {\n let decoratorName = `@jsonMapMember on ${nameof(target.constructor)}.${String(propKey)}`; // For error messages.\n\n if (typeof keyConstructor !== \"function\")\n {\n logError(`${decoratorName}: could not resolve constructor of map keys at runtime.`);\n return;\n }\n\n if (typeof valueConstructor !== \"function\")\n {\n logError(`${decoratorName}: could not resolve constructor of map values at runtime.`);\n return;\n }\n\n // If ReflectDecorators is available, use it to check whether 'jsonMapMember' has been used on a map. Warn if not.\n if (isReflectMetadataSupported && Reflect.getMetadata(\"design:type\", target, propKey) !== Map)\n {\n logError(`${decoratorName}: property is not a Map.`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Map,\n elementType: [valueConstructor],\n keyType: keyConstructor,\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: propKey.toString(),\n name: options.name || propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n}\n","import { nameof, logError, logWarning, parseToJSObject } from './typedjson/helpers';\nimport { Constructor } from \"./typedjson/types\";\nimport { JsonObjectMetadata } from \"./typedjson/metadata\";\nimport { Deserializer } from \"./typedjson/deserializer\";\nimport { Serializer } from \"./typedjson/serializer\";\n\nexport type JsonTypes = Object|boolean|string|number|null|undefined;\n\nexport interface ITypedJSONSettings\n{\n /**\n * Sets the handler callback to invoke on errors during serializing and deserializing.\n * Re-throwing errors in this function will halt serialization/deserialization.\n * The default behavior is to log errors to the console.\n */\n errorHandler?: (e: Error) => void;\n\n /**\n * Sets a callback that determines the constructor of the correct sub-type of polymorphic\n * objects while deserializing.\n * The default behavior is to read the type-name from the '__type' property of 'sourceObject',\n * and look it up in 'knownTypes'.\n * The constructor of the sub-type should be returned.\n */\n typeResolver?: (sourceObject: Object, knownTypes: Map) => Function;\n\n nameResolver?: (ctor: Function) => string;\n\n /**\n * Sets a callback that writes type-hints to serialized objects.\n * The default behavior is to write the type-name to the '__type' property, if a derived type\n * is present in place of a base type.\n */\n typeHintEmitter?:\n (targetObject: Object, sourceObject: Object, expectedSourceType: Function) => void;\n\n /**\n * Sets the amount of indentation to use in produced JSON strings.\n * Default value is 0, or no indentation.\n */\n indent?: number;\n\n replacer?: (key: string, value: any) => any;\n\n knownTypes?: Array>;\n}\n\nexport class TypedJSON\n{\n //#region Static\n public static parse(\n object: any, rootType: Constructor, settings?: ITypedJSONSettings,\n ): T|undefined {\n return new TypedJSON(rootType, settings).parse(object);\n }\n\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings?: ITypedJSONSettings,\n dimensions?: 1\n ): T[];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 2\n ): T[][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 3\n ): T[][][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 4\n ): T[][][][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 5\n ): T[][][][][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings?: ITypedJSONSettings,\n dimensions?: number\n ): any[] {\n return new TypedJSON(elementType, settings).parseAsArray(object, dimensions as any);\n }\n\n public static parseAsSet(\n object: any, elementType: Constructor, settings?: ITypedJSONSettings,\n ): Set {\n return new TypedJSON(elementType, settings).parseAsSet(object);\n }\n\n public static parseAsMap(\n object: any,\n keyType: Constructor,\n valueType: Constructor,\n settings?: ITypedJSONSettings,\n ): Map {\n return new TypedJSON(valueType, settings).parseAsMap(object, keyType);\n }\n\n public static toPlainJson(\n object: T, rootType: Constructor, settings?: ITypedJSONSettings,\n ): JsonTypes {\n return new TypedJSON(rootType, settings).toPlainJson(object);\n }\n\n public static toPlainArray(\n object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings,\n ): Object[];\n public static toPlainArray(\n object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings,\n ): Object[][];\n public static toPlainArray(\n object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings,\n ): Object[][][];\n public static toPlainArray(\n object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings,\n ): Object[][][][];\n public static toPlainArray(\n object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings,\n ): Object[][][][][];\n public static toPlainArray(\n object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings,\n ): any[];\n public static toPlainArray(\n object: any[], elementType: Constructor, dimensions?: any, settings?: ITypedJSONSettings,\n ): any[] {\n return new TypedJSON(elementType, settings).toPlainArray(object, dimensions);\n }\n\n public static toPlainSet(\n object: Set, elementType: Constructor, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(elementType, settings).stringifyAsSet(object);\n }\n\n public static toPlainMap(\n object: Map,\n keyCtor: Constructor,\n valueCtor: Constructor,\n settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(valueCtor, settings).stringifyAsMap(object, keyCtor);\n }\n\n public static stringify(\n object: T, rootType: Constructor, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(rootType, settings).stringify(object);\n }\n\n public static stringifyAsArray(\n object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: any[], elementType: Constructor, dimensions?: any, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(elementType, settings).stringifyAsArray(object, dimensions);\n }\n\n public static stringifyAsSet(\n object: Set, elementType: Constructor, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(elementType, settings).stringifyAsSet(object);\n }\n\n public static stringifyAsMap(\n object: Map,\n keyCtor: Constructor,\n valueCtor: Constructor,\n settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(valueCtor, settings).stringifyAsMap(object, keyCtor);\n }\n\n private static _globalConfig: ITypedJSONSettings;\n\n public static setGlobalConfig(config: ITypedJSONSettings)\n {\n if (this._globalConfig)\n {\n Object.assign(this._globalConfig, config);\n }\n else\n {\n this._globalConfig = config;\n }\n }\n\n //#endregion\n\n private serializer: Serializer = new Serializer();\n private deserializer: Deserializer = new Deserializer();\n private globalKnownTypes: Array> = [];\n private indent: number = 0;\n private rootConstructor: Constructor;\n private errorHandler: (e: Error) => void;\n private nameResolver: (ctor: Function) => string;\n private replacer?: (key: string, value: any) => any;\n\n /**\n * Creates a new TypedJSON instance to serialize (stringify) and deserialize (parse) object\n * instances of the specified root class type.\n * @param rootType The constructor of the root class type.\n * @param settings Additional configuration settings.\n */\n constructor(rootConstructor: Constructor, settings?: ITypedJSONSettings)\n {\n let rootMetadata = JsonObjectMetadata.getFromConstructor(rootConstructor);\n\n if (!rootMetadata || (!rootMetadata.isExplicitlyMarked && !rootMetadata.isHandledWithoutAnnotation))\n {\n throw new TypeError(\"The TypedJSON root data type must have the @jsonObject decorator used.\");\n }\n\n this.nameResolver = (ctor) => nameof(ctor);\n this.rootConstructor = rootConstructor;\n this.errorHandler = (error) => logError(error);\n\n if (settings)\n {\n this.config(settings);\n }\n else if (TypedJSON._globalConfig)\n {\n this.config({});\n }\n }\n\n /**\n * Configures TypedJSON through a settings object.\n * @param settings The configuration settings object.\n */\n public config(settings: ITypedJSONSettings)\n {\n if (TypedJSON._globalConfig)\n {\n settings = {\n ...TypedJSON._globalConfig,\n ...settings\n };\n\n if (settings.knownTypes && TypedJSON._globalConfig.knownTypes)\n {\n // Merge known-types (also de-duplicate them, so Array -> Set -> Array).\n settings.knownTypes = Array.from(new Set(\n settings.knownTypes.concat(TypedJSON._globalConfig.knownTypes),\n ));\n }\n }\n\n if (settings.errorHandler)\n {\n this.errorHandler = settings.errorHandler;\n this.deserializer.setErrorHandler(settings.errorHandler);\n this.serializer.setErrorHandler(settings.errorHandler);\n }\n\n if (settings.replacer) this.replacer = settings.replacer;\n if (settings.typeResolver) this.deserializer.setTypeResolver(settings.typeResolver);\n if (settings.typeHintEmitter) this.serializer.setTypeHintEmitter(settings.typeHintEmitter);\n if (settings.indent) this.indent = settings.indent;\n\n if (settings.nameResolver)\n {\n this.nameResolver = settings.nameResolver;\n this.deserializer.setNameResolver(settings.nameResolver);\n // this.serializer.set\n }\n\n if (settings.knownTypes)\n {\n // Type-check knownTypes elements to recognize errors in advance.\n settings.knownTypes.forEach((knownType, i) =>\n {\n // tslint:disable-next-line:no-null-keyword\n if (typeof knownType === \"undefined\" || knownType === null)\n {\n logWarning(\n `TypedJSON.config: 'knownTypes' contains an undefined/null value (element ${i}).`);\n }\n });\n\n this.globalKnownTypes = settings.knownTypes;\n }\n }\n\n /**\n * Converts a JSON string to the root class type.\n * @param object The JSON to parse and convert.\n * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown).\n * @returns Deserialized T or undefined if there were errors.\n */\n public parse(object: any): T|undefined\n {\n const json = parseToJSObject(object, this.rootConstructor);\n\n let rootMetadata = JsonObjectMetadata.getFromConstructor(this.rootConstructor);\n let result: T|undefined;\n let knownTypes = new Map();\n\n this.globalKnownTypes.filter(ktc => ktc).forEach(knownTypeCtor =>\n {\n knownTypes.set(this.nameResolver(knownTypeCtor), knownTypeCtor);\n });\n\n if (rootMetadata)\n {\n rootMetadata.knownTypes.forEach(knownTypeCtor =>\n {\n knownTypes.set(this.nameResolver(knownTypeCtor), knownTypeCtor);\n });\n }\n\n try\n {\n result = this.deserializer.convertSingleValue(json, {\n selfConstructor: this.rootConstructor,\n knownTypes: knownTypes,\n }) as T;\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n\n return result;\n }\n\n public parseAsArray(object: any, dimensions?: 1): T[];\n public parseAsArray(object: any, dimensions: 2): T[][];\n public parseAsArray(object: any, dimensions: 3): T[][][];\n public parseAsArray(object: any, dimensions: 4): T[][][][];\n public parseAsArray(object: any, dimensions: 5): T[][][][][];\n public parseAsArray(object: any, dimensions: number): any[];\n public parseAsArray(object: any, dimensions: number = 1): any[]\n {\n const json = parseToJSObject(object, Array);\n if (json instanceof Array)\n {\n return this.deserializer.convertAsArray(json, {\n selfConstructor: Array,\n elementConstructor: new Array(dimensions - 1)\n .fill(Array)\n .concat(this.rootConstructor),\n knownTypes: this._mapKnownTypes(this.globalKnownTypes),\n });\n }\n else\n {\n this.errorHandler(new TypeError(`Expected 'json' to define an Array`\n + `, but got ${typeof json}.`));\n }\n\n return [];\n }\n\n public parseAsSet(object: any): Set\n {\n const json = parseToJSObject(object, Set);\n // A Set is serialized as T[].\n if (json instanceof Array)\n {\n return this.deserializer.convertAsSet(json, {\n selfConstructor: Array,\n elementConstructor: [this.rootConstructor],\n knownTypes: this._mapKnownTypes(this.globalKnownTypes)\n });\n }\n else\n {\n this.errorHandler(new TypeError(`Expected 'json' to define a Set (using an Array)`\n + `, but got ${typeof json}.`,\n ));\n }\n\n return new Set();\n }\n\n public parseAsMap(object: any, keyConstructor: Constructor): Map\n {\n const json = parseToJSObject(object, Map);\n // A Set is serialized as T[].\n if (json instanceof Array)\n {\n return this.deserializer.convertAsMap(json, {\n selfConstructor: Array,\n elementConstructor: [this.rootConstructor],\n knownTypes: this._mapKnownTypes(this.globalKnownTypes),\n keyConstructor: keyConstructor\n });\n }\n else\n {\n this.errorHandler(new TypeError(`Expected 'json' to define a Set (using an Array)`\n + `, but got ${typeof json}.`,\n ));\n }\n\n return new Map();\n }\n\n /**\n * Converts an instance of the specified class type to a plain JSON object.\n * @param object The instance to convert to a JSON string.\n * @returns Serialized object or undefined if an error has occured.\n */\n public toPlainJson(object: T): JsonTypes\n {\n try\n {\n return this.serializer.convertSingleValue(object, {\n selfType: this.rootConstructor\n });\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n public toPlainArray(object: T[], dimensions?: 1): Object[];\n public toPlainArray(object: T[][], dimensions: 2): Object[][];\n public toPlainArray(object: T[][][], dimensions: 3): Object[][][];\n public toPlainArray(object: T[][][][], dimensions: 4): Object[][][][];\n public toPlainArray(object: T[][][][][], dimensions: 5): Object[][][][][];\n public toPlainArray(object: any[], dimensions: 1|2|3|4|5 = 1): Object[]|undefined\n {\n try\n {\n const elementConstructorArray =\n new Array(dimensions - 1).fill(Array).concat(this.rootConstructor);\n return this.serializer.convertAsArray(object, elementConstructorArray);\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n public toPlainSet(object: Set): Object[]|undefined\n {\n try\n {\n return this.serializer.convertAsSet(object, this.rootConstructor);\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n public toPlainMap(object: Map, keyConstructor: Constructor): { key: any, value: any }[]|undefined\n {\n try\n {\n return this.serializer.convertAsMap(object, keyConstructor, this.rootConstructor);\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n /**\n * Converts an instance of the specified class type to a JSON string.\n * @param object The instance to convert to a JSON string.\n * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown).\n * @returns String with the serialized object or an empty string if an error has occured, but\n * the errorHandler did not throw.\n */\n public stringify(object: T): string\n {\n const result = this.toPlainJson(object);\n if (result === undefined) {\n return '';\n }\n return JSON.stringify(result, this.replacer, this.indent);\n }\n\n public stringifyAsArray(object: T[], dimensions?: 1): string;\n public stringifyAsArray(object: T[][], dimensions: 2): string;\n public stringifyAsArray(object: T[][][], dimensions: 3): string;\n public stringifyAsArray(object: T[][][][], dimensions: 4): string;\n public stringifyAsArray(object: T[][][][][], dimensions: 5): string;\n public stringifyAsArray(object: any[], dimensions: any): string\n {\n return JSON.stringify(this.toPlainArray(object, dimensions), this.replacer, this.indent);\n }\n\n public stringifyAsSet(object: Set): string\n {\n return JSON.stringify(this.toPlainSet(object), this.replacer, this.indent);\n }\n\n public stringifyAsMap(object: Map, keyConstructor: Constructor): string\n {\n return JSON.stringify(this.toPlainMap(object, keyConstructor), this.replacer, this.indent);\n }\n\n private _mapKnownTypes(constructors: Array>)\n {\n let map = new Map>();\n\n constructors.filter(ctor => ctor).forEach(ctor => map.set(this.nameResolver(ctor), ctor));\n\n return map;\n }\n}\n\nexport { jsonObject } from \"./typedjson/json-object\";\nexport { jsonMember } from \"./typedjson/json-member\";\nexport { jsonArrayMember } from \"./typedjson/json-array-member\";\nexport { jsonSetMember } from \"./typedjson/json-set-member\";\nexport { jsonMapMember } from \"./typedjson/json-map-member\";\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack://typedjson/webpack/universalModuleDefinition","webpack://typedjson/webpack/bootstrap","webpack://typedjson/./src/typedjson/helpers.ts","webpack://typedjson/./src/typedjson/metadata.ts","webpack://typedjson/./src/typedjson/serializer.ts","webpack://typedjson/./src/typedjson/deserializer.ts","webpack://typedjson/./src/parser.ts","webpack://typedjson/./src/typedjson/json-object.ts","webpack://typedjson/./src/typedjson/json-member.ts","webpack://typedjson/./src/typedjson/json-array-member.ts","webpack://typedjson/./src/typedjson/json-set-member.ts","webpack://typedjson/./src/typedjson/json-map-member.ts","webpack://typedjson/./src/typedjson.ts"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kDAA0C,gCAAgC;AAC1E;AACA;;AAEA;AACA;AACA;AACA,gEAAwD,kBAAkB;AAC1E;AACA,yDAAiD,cAAc;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAyC,iCAAiC;AAC1E,wHAAgH,mBAAmB,EAAE;AACrI;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;;AAGA;AACA;;;;;;;;;;;AC7EO,IAAM,kBAAkB,GAAG,4CAA4C,CAAC;AAExE,SAAS,eAAe,CAAI,IAAmB;IAElD,QAAQ,IAAW,EACnB;QACI,KAAK,MAAM;YACP,OAAO,CAAQ,CAAC;QAEpB,KAAK,MAAM;YACP,OAAO,EAAS,CAAC;QAErB,KAAK,OAAO;YACR,OAAO,KAAY,CAAC;QAExB,KAAK,KAAK;YACN,OAAO,EAAS,CAAC;QAErB;YACI,OAAO,SAAS,CAAC;KACxB;AACL,CAAC;AAED;;;;GAIG;AACI,SAAS,gCAAgC,CAAC,IAAc;IAE3D,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAW,CAAC,CAAC,CAAC;AACrE,CAAC;AAEM,SAAS,gBAAgB,CAAC,IAAc;IAE3C,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,iBAAiB,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,CAAC;SAC9H,OAAO,CAAC,IAAW,CAAC,CAAC,CAAC;AAC/B,CAAC;AAEM,SAAS,gBAAgB,CAAC,GAAQ;IAErC,QAAQ,OAAO,GAAG,EAClB;QACI,KAAK,QAAQ,CAAC;QACd,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS;YACV,OAAO,IAAI,CAAC;QAChB;YACI,OAAO,CAAC,GAAG,YAAY,MAAM,IAAI,GAAG,YAAY,MAAM,IAAI,GAAG,YAAY,OAAO,CAAC,CAAC;KACzF;AACL,CAAC;AAEM,SAAS,QAAQ,CAAC,KAAU;IAE/B,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC;AACrC,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAe,EAAE,YAAsB;IAClE,IAAM,+BAA+B,GAAG,YAAY,KAAK,MAAM;WACxD,YAAY,KAAK,WAAW;WAC5B,YAAY,KAAK,QAAQ,CAAC;IAEjC,IAAM,SAAS,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAC,CAAC,CAAC,KAAK,GAAG,CAAC;IACjG,IAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAE/C,OAAO,CAAC,+BAA+B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,YAAY,KAAK,IAAI,CAAC,CAAC;AACpH,CAAC;AAEM,SAAS,eAAe,CAAC,IAAS,EAAE,YAAsB;IAC7D,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,qBAAqB,CAAC,IAAI,EAAE,YAAY,CAAC,EACzE;QACE,OAAO,IAAI,CAAC;KACb;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED;;;;GAIG;AACI,SAAS,WAAW,CAAC,CAAW,EAAE,CAAW;IAEhD,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC;AAC/C,CAAC;AAEM,SAAS,QAAQ,CAAC,OAAa;IAAE,wBAAwB;SAAxB,UAAwB,EAAxB,qBAAwB,EAAxB,IAAwB;QAAxB,uCAAwB;;IAE5D,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,UAAU,EACtE;QACI,OAAO,CAAC,KAAK,OAAb,OAAO,GAAO,OAAO,SAAK,cAAc,GAAE;KAC7C;SACI,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,UAAU,EACzE;QACI,OAAO,CAAC,GAAG,OAAX,OAAO,GAAK,YAAU,OAAS,SAAK,cAAc,GAAE;KACvD;AACL,CAAC;AAEM,SAAS,UAAU,CAAC,OAAa;IAAE,wBAAwB;SAAxB,UAAwB,EAAxB,qBAAwB,EAAxB,IAAwB;QAAxB,uCAAwB;;IAE9D,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,UAAU,EACpE;QACI,OAAO,CAAC,GAAG,OAAX,OAAO,GAAK,OAAO,SAAK,cAAc,GAAE;KAC3C;AACL,CAAC;AAEM,SAAS,UAAU,CAAC,OAAa;IAAE,wBAAwB;SAAxB,UAAwB,EAAxB,qBAAwB,EAAxB,IAAwB;QAAxB,uCAAwB;;IAE9D,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,UAAU,EACrE;QACI,OAAO,CAAC,IAAI,OAAZ,OAAO,GAAM,OAAO,SAAK,cAAc,GAAE;KAC5C;SAAM,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,UAAU,EAC3E;QACI,OAAO,CAAC,GAAG,OAAX,OAAO,GAAK,cAAY,OAAS,SAAK,cAAc,GAAE;KACzD;AACL,CAAC;AAED;;;GAGG;AACI,SAAS,cAAc,CAAI,KAAQ;IAEtC,OAAO,CAAC,CAAC,OAAO,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC;AAC7D,CAAC;AAEM,SAAS,YAAY,CAAI,KAAU,EAAE,WAAqB;IAE7D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAC7B;QACI,OAAO,CAAC,WAAW,KAAK,MAAM,CAAC,CAAC;KACnC;SACI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAClC;QACI,OAAO,CAAC,WAAW,KAAK,MAAM,CAAC,CAAC;KACnC;SACI,IAAI,OAAO,KAAK,KAAK,SAAS,EACnC;QACI,OAAO,CAAC,WAAW,KAAK,OAAO,CAAC,CAAC;KACpC;SACI,IAAI,QAAQ,CAAC,KAAK,CAAC,EACxB;QACI,OAAO,CAAC,KAAK,YAAY,WAAW,CAAC,CAAC;KACzC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC;AAEM,IAAM,0BAA0B,GACnC,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,OAAO,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC;AAE/E;;;GAGG;AACI,SAAS,MAAM,CAAC,EAAgC;IAEnD,IAAI,OAAO,EAAE,CAAC,IAAI,KAAK,QAAQ,EAC/B;QACI,OAAO,EAAE,CAAC,IAAI,CAAC;KAClB;SAED;QACI,OAAO,WAAW,CAAC;KACtB;AACL,CAAC;;;AC1KoH;AAiCrH;IA+DI,YAAY;IAEZ,4BACI,SAAmB;QAKhB,gBAAW,GAAoC,IAAI,GAAG,EAA8B,CAAC;QAErF,eAAU,GAAkB,IAAI,GAAG,EAAY,CAAC;QAOvD;;;WAGG;QACI,uBAAkB,GAAY,KAAK,CAAC;QAE3C;;;WAGG;QACI,+BAA0B,GAAY,KAAK,CAAC;QAtB/C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC/B,CAAC;IAnED,gBAAgB;IAChB;;;OAGG;IACW,oCAAiB,GAA/B,UAAgC,IAAc;QAE1C,IAAM,QAAQ,GAAG,kBAAkB,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAC7D,OAAO,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC;IAED;;;OAGG;IACW,qCAAkB,GAAhC,UAAiC,IAAc;QAE3C,IAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,IAAI,CAAC,SAAS,EACd;YACI,OAAO;SACV;QAED,IAAI,QAAsC,CAAC;QAC3C,IAAI,SAAS,CAAC,cAAc,CAAC,kBAAkB,CAAC,EAChD;YACI,uDAAuD;YACvD,QAAQ,GAAG,SAAS,CAAC,kBAAkB,CAAC,CAAC;SAC5C;QAED,0DAA0D;QAC1D,IAAI,QAAQ,IAAI,QAAQ,CAAC,kBAAkB,EAC3C;YACI,OAAO,QAAQ,CAAC;SACnB;QAED,gEAAgE;QAChE,IAAI,kBAAkB,CAAC,2BAA2B,CAAC,IAAI,CAAC,EACxD;YACI,IAAM,aAAa,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACnD,aAAa,CAAC,kBAAkB,GAAG,IAAI,CAAC;YACxC,oEAAoE;YACpE,OAAO,aAAa,CAAC;SACxB;IACL,CAAC;IAED;;;OAGG;IACW,2CAAwB,GAAtC,UAAuC,WAAqB;QAExD,IAAM,QAAQ,GAAG,kBAAkB,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;QACpE,OAAO,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACvE,CAAC;IAEc,8CAA2B,GAA1C,UAA2C,IAAc;QAErD,OAAO,gCAAgC,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC;eAChE,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,WAAW,CAAC;IACrD,CAAC;IAoCL,yBAAC;AAAD,CAAC;;AAEM,SAAS,yBAAyB,CAAC,WAA0B,EAAE,OAAwB,EAAE,QAA4B;IAExH,IAAM,aAAa,GAAG,oBAAkB,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,SAAI,MAAM,CAAC,OAAO,CAAG,CAAC,CAAC,sBAAsB;IACpH,IAAI,cAAkC,CAAC;IAEvC,oGAAoG;IACpG,4GAA4G;IAC5G,2DAA2D;IAC3D,IAAI,OAAO,WAAW,KAAK,UAAU,EACrC;QACI,QAAQ,CAAI,aAAa,oCAAiC,CAAC,CAAC;QAC5D,OAAO;KACV;IAED,gCAAgC;IAChC,oDAAoD;IACpD,IAAI,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,UAAU,EAC9C;QACI,QAAQ,CAAI,aAAa,oCAAiC,CAAC,CAAC;QAC5D,OAAO;KACV;IAED,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAC3D;QACI,QAAQ,CAAI,aAAa,2CAAwC,CAAC,CAAC;QACnE,OAAO;KACV;IAED,+FAA+F;IAC/F,2HAA2H;IAC3H,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,kBAAkB,CAAC,EACnD;QACI,iCAAiC;QACjC,cAAc,GAAG,IAAI,2BAAkB,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAEjE,yDAAyD;QACzD,IAAM,cAAc,GAAuB,WAAW,CAAC,kBAAkB,CAAC,CAAC;QAC3E,IAAI,cAAc,EAAE,6DAA6D;SACjF;YACI,cAAc,CAAC,WAAW,CAAC,OAAO,CAAC,UAAC,SAAS,EAAE,QAAQ,IAAK,qBAAc,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAnD,CAAmD,CAAC,CAAC;SACpH;QAED,iHAAiH;QACjH,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE,kBAAkB,EAAE;YACnD,UAAU,EAAE,KAAK;YACjB,YAAY,EAAE,KAAK;YACnB,QAAQ,EAAE,KAAK;YACf,KAAK,EAAE,cAAc;SACxB,CAAC,CAAC;KACN;SAED;QACI,sDAAsD;QACtD,cAAc,GAAG,WAAW,CAAC,kBAAkB,CAAC,CAAC;KACpD;IAED,IAAI,CAAC,QAAQ,CAAC,YAAY,EAC1B;QACI,gDAAgD;QAChD,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;KAChD;IAED,IAAI,QAAQ,CAAC,OAAO;QAChB,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAEpD,IAAI,QAAQ,CAAC,WAAW;QACpB,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,kBAAQ,IAAI,qBAAc,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAvC,CAAuC,CAAC,CAAC;IAEtF,cAAc,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC5D,CAAC;;;;;;;;;;;;;;AC1M8H;AAE/E;AAehD,SAAS,eAAe,CAAC,QAAwB;IAC7C,OAAO,QAAQ,CAAC,QAAQ,KAAK,KAAK,CAAC;AACvC,CAAC;AAQD,SAAS,aAAa,CAAC,QAAwB;IAC3C,OAAO,QAAQ,CAAC,QAAQ,KAAK,GAAG,CAAC;AACrC,CAAC;AASD,SAAS,aAAa,CAAC,QAAwB;IAC3C,OAAO,QAAQ,CAAC,QAAQ,KAAK,GAAG,CAAC;AACrC,CAAC;AAED;;;;;;;GAOG;AACH;IAKI;QAEI,IAAI,CAAC,gBAAgB,GAAG,UAAC,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,kBAAuC;YAE5G,gJAAgJ;YAChJ,2IAA2I;YAC3I,IAAI,YAAY,CAAC,WAAW,KAAK,kBAAkB,EACnD;gBACI,IAAM,MAAI,GAAG,kBAAkB,IAAI,kBAAkB,CAAC,IAAI;oBACtD,CAAC,CAAC,kBAAkB,CAAC,IAAI;oBACzB,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;gBACvC,uEAAuE;gBACvE,6CAA6C;gBAC7C,YAAY,CAAC,QAAQ,CAAC,GAAG,MAAI,CAAC;aACjC;QACL,CAAC,CAAC;QAEF,IAAI,CAAC,aAAa,GAAG,UAAC,KAAK,IAAK,eAAQ,CAAC,KAAK,CAAC,EAAf,CAAe,CAAC;IACpD,CAAC;IAEM,uCAAkB,GAAzB,UAA0B,mBAAuG;QAE7H,IAAI,OAAO,mBAAmB,KAAK,UAAU,EAC7C;YACI,MAAM,IAAI,SAAS,CAAC,0CAA0C,CAAC,CAAC;SACnE;QAED,IAAI,CAAC,gBAAgB,GAAG,mBAAmB,CAAC;IAChD,CAAC;IAEM,oCAAe,GAAtB,UAAuB,oBAA4C;QAE/D,IAAI,OAAO,oBAAoB,KAAK,UAAU,EAC9C;YACI,MAAM,IAAI,SAAS,CAAC,2CAA2C,CAAC,CAAC;SACpE;QAED,IAAI,CAAC,aAAa,GAAG,oBAAoB,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACI,uCAAkB,GAAzB,UAA0B,YAAiB,EAAE,QAAwB,EAAE,UAA6B;QAA7B,kDAA6B;QAEhG,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC;YAAE,OAAO;QAE1C,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAClD;YACI,IAAI,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC7C,IAAI,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;YAElD,IAAI,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC,0BAAwB,UAAU,qBAAgB,YAAY,gBAAW,UAAU,OAAI,CAAC,CAAC,CAAC;YAC3H,OAAO;SACV;QAED,IAAI,gCAAgC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EACvD;YACI,OAAO,YAAY,CAAC;SACvB;aACI,IAAI,QAAQ,CAAC,QAAQ,KAAK,WAAW,EAC1C;YACI,OAAO,IAAI,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC;SAClD;aACI,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,EACvC;YACI,OAAO,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;SAC/C;aACI,IAAI,eAAe,CAAC,QAAQ,CAAC,EAClC;YACI,OAAO,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;SAC/E;aACI,IAAI,aAAa,CAAC,QAAQ,CAAC,EAChC;YACI,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;SAChF;aACI,IAAI,aAAa,CAAC,QAAQ,CAAC,EAChC;YACI,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;SAClG;aACI,IAAI,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAC5C;YACI,OAAO,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;SACjD;aACI,IAAI,OAAO,YAAY,KAAK,QAAQ,EACzC;YACI,OAAO,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;SACnE;IACL,CAAC;IAED;;OAEG;IACI,oCAAe,GAAtB,UAAuB,YAA2B,EAAE,QAAwB,EAAE,UAAmB;QAAjG,iBA0DC;QAxDG,IAAI,kBAAgD,CAAC;QACrD,IAAI,YAA2B,CAAC;QAEhC,IAAI,YAAY,CAAC,WAAW,KAAK,QAAQ,CAAC,QAAQ,IAAI,YAAY,YAAY,QAAQ,CAAC,QAAQ,EAC/F;YACI,4EAA4E;YAC5E,oFAAoF;YACpF,kBAAkB,GAAG,2BAAkB,CAAC,kBAAkB,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;SACxF;aAED;YACI,kBAAkB,GAAG,2BAAkB,CAAC,kBAAkB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;SACjF;QAED,IAAI,kBAAkB,EACtB;YACI,IAAM,YAAU,GAAG,kBAAkB,CAAC;YACtC,wCAAwC;YACxC,2IAA2I;YAC3I,8HAA8H;YAC9H,YAAY,GAAG,EAAE,CAAC;YAElB,kBAAkB,CAAC,WAAW,CAAC,OAAO,CAAC,UAAC,cAAc;gBAElD,IAAI,cAAc,CAAC,UAAU,EAAE;oBAC3B,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC;wBAC7B,cAAc,CAAC,UAAU,CAAC,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;iBACnE;qBAAM,IAAI,cAAc,CAAC,IAAI,EAAE;oBAC5B,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,KAAI,CAAC,kBAAkB,CACvD,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,EAChC;wBACI,QAAQ,EAAE,cAAc,CAAC,IAAI;wBAC7B,YAAY,EAAE,cAAc,CAAC,WAAW;wBACxC,OAAO,EAAE,cAAc,CAAC,OAAO;qBAClC,EACE,MAAM,CAAC,YAAU,CAAC,SAAS,CAAC,SAAI,cAAc,CAAC,GAAK,CAC1D,CAAC;iBACL;qBAAM;oBACH,MAAM,IAAI,SAAS,CACf,yBAAuB,cAAc,CAAC,IAAI,eAAY;0BACpD,oDAAoD,CACzD,CAAC;iBACL;YACL,CAAC,CAAC,CAAC;SACN;aAED;YACI,iEAAiE;YACjE,wIAAwI;YACxI,YAAY,gBAAQ,YAAY,CAAE,CAAC;SACtC;QAED,iBAAiB;QACjB,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;QAEzF,OAAO,YAAY,CAAC;IACxB,CAAC;IAED;;;;;OAKG;IACI,mCAAc,GAArB,UAAsB,YAAmB,EAAE,mBAA+B,EAAE,UAAqB;QAAjG,iBA+BC;QA/B2E,kDAAqB;QAE7F,IAAI,mBAAmB,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;YAC5D,MAAM,IAAI,SAAS,CAAC,yBAAuB,UAAU,gDAA6C,CAAC,CAAC;QAEvG,gDAAgD;QAChD,gIAAgI;QAChI,uJAAuJ;QACvJ,qBAAqB;QACrB,YAAY,CAAC,OAAO,CAAC,UAAC,OAAO,EAAE,CAAC;YAE5B,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,EAClD;gBACI,IAAM,gBAAgB,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxD,IAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;gBACnD,MAAM,IAAI,SAAS,CAAC,yBAAuB,UAAU,SAAI,CAAC,qBAAgB,gBAAgB,gBAAW,cAAc,OAAI,CAAC,CAAC;aAC5H;QACL,CAAC,CAAC,CAAC;QAEH,IAAM,mBAAmB,GAAmB;YACxC,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC;YAChC,YAAY,EAAE,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;SACnF,CAAC;QAEF,IAAI,UAAU,EACd;YACI,+BAA+B;YAC/B,UAAU,IAAI,IAAI,CAAC;SACtB;QAED,OAAO,YAAY,CAAC,GAAG,CAAC,iBAAO,IAAI,YAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,EAAE,UAAU,CAAC,EAAjE,CAAiE,CAAC,CAAC;IAC1G,CAAC;IAED;;;;;;;OAOG;IACI,iCAAY,GAAnB,UAAoB,YAAsB,EAAE,mBAA6B,EAAE,UAAqB;QAAhG,iBA6BC;QA7B0E,kDAAqB;QAE5F,IAAI,CAAC,mBAAmB;YACpB,MAAM,IAAI,SAAS,CAAC,yBAAuB,UAAU,8CAA2C,CAAC,CAAC;QAEtG,IAAI,eAAe,GAAmB;YAClC,QAAQ,EAAE,mBAAmB;SAChC,CAAC;QAEF,oCAAoC;QACpC,IAAI,UAAU;YAAE,UAAU,IAAI,IAAI,CAAC;QAEnC,IAAI,WAAW,GAAU,EAAE,CAAC;QAE5B,oEAAoE;QACpE,6HAA6H;QAC7H,YAAY,CAAC,OAAO,CAAC,iBAAO;YAExB,IAAI,aAAa,GAAG,KAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC;YAElF,kJAAkJ;YAClJ,6FAA6F;YAC7F,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,cAAc,CAAC,aAAa,CAAC,EAC7D;gBACI,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;aACnC;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,WAAW,CAAC;IACvB,CAAC;IAED;;;;;;;OAOG;IACI,iCAAY,GAAnB,UAAoB,YAA2B,EAAE,eAAyB,EAAE,mBAA6B,EAAE,UAAqB;QAAhI,iBAqCC;QArC0G,kDAAqB;QAE5H,IAAI,CAAC,mBAAmB;YACpB,MAAM,IAAI,SAAS,CAAC,yBAAuB,UAAU,4CAAyC,CAAC,CAAC;QAEpG,IAAI,CAAC,eAAe;YAChB,MAAM,IAAI,SAAS,CAAC,yBAAuB,UAAU,0CAAuC,CAAC,CAAC;QAElG,IAAI,eAAe,GAAmB;YAClC,QAAQ,EAAE,mBAAmB;YAC7B,YAAY,EAAE,CAAC,mBAAmB,CAAC;SACtC,CAAC;QAEF,IAAI,WAAW,GAAmB;YAC9B,QAAQ,EAAE,eAAe;SAC5B,CAAC;QAEF,IAAI,UAAU;YAAE,UAAU,IAAI,IAAI,CAAC;QAEnC,IAAI,WAAW,GAAoC,EAAE,CAAC;QAEtD,+FAA+F;QAC/F,YAAY,CAAC,OAAO,CAAC,UAAC,KAAK,EAAE,GAAG;YAE5B,IAAI,qBAAqB,GAAG;gBACxB,GAAG,EAAE,KAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,WAAW,EAAE,UAAU,CAAC;gBAC1D,KAAK,EAAE,KAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,eAAe,EAAE,UAAU,CAAC;aACrE,CAAC;YAEF,4EAA4E;YAC5E,IAAI,cAAc,CAAC,qBAAqB,CAAC,GAAG,CAAC,IAAI,cAAc,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAC5F;gBACI,WAAW,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;aAC3C;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,WAAW,CAAC;IACvB,CAAC;IAED;;;;;;OAMG;IACI,wCAAmB,GAA1B,UAA2B,YAA6B;QAEpD,OAAO,KAAK,CAAC,IAAI,CAAC,YAAmB,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACI,yCAAoB,GAA3B,UAA4B,MAAmB;QAE3C,6EAA6E;QAC7E,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,kBAAQ,IAAI,aAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,EAA7B,CAA6B,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvG,CAAC;IAED;;OAEG;IACI,sCAAiB,GAAxB,UAAyB,QAAkB;QAEvC,OAAO,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACtD,CAAC;IACL,iBAAC;AAAD,CAAC;;;;AC1WyE;AAE1B;AAUhD;;;GAGG;AACH;IAMI;QAEI,IAAI,CAAC,aAAa,GAAG,UAAC,YAAiB,EAAE,UAAiC;YAEtE,IAAI,YAAY,CAAC,MAAM;gBAAE,OAAO,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACxE,CAAC,CAAC;QAEF,IAAI,CAAC,aAAa,GAAG,UAAC,KAAK,IAAK,eAAQ,CAAC,KAAK,CAAC,EAAf,CAAe,CAAC;IACpD,CAAC;IAEM,sCAAe,GAAtB,UAAuB,oBAAgD;QAEnE,IAAI,CAAC,aAAa,GAAG,oBAAoB,CAAC;IAC9C,CAAC;IAEM,sCAAe,GAAtB,UAAuB,oBAA2F;QAE9G,IAAI,OAAO,oBAAoB,KAAK,UAAU;YAAE,MAAM,IAAI,SAAS,CAAC,2CAA2C,CAAC,CAAC;QAEjH,IAAI,CAAC,aAAa,GAAG,oBAAoB,CAAC;IAC9C,CAAC;IAEM,sCAAe,GAAtB,UAAuB,oBAA4C;QAE/D,IAAI,OAAO,oBAAoB,KAAK,UAAU,EAC9C;YACI,MAAM,IAAI,SAAS,CAAC,2CAA2C,CAAC,CAAC;SACpE;QAED,IAAI,CAAC,aAAa,GAAG,oBAAoB,CAAC;IAC9C,CAAC;IAEM,sCAAe,GAAtB,UACI,YAA2B,EAC3B,oBAAoC,EACpC,UAAqB;QAHzB,iBA2KC;QAxKG,kDAAqB;QAErB,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,KAAK,IAAI,EAC7D;YACI,IAAI,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC,wBAAsB,UAAU,+CAA4C,CAAC,CAAC,CAAC;YAChH,OAAO,SAAS,CAAC;SACpB;QAED,IAAI,gBAAgB,GAAG,oBAAoB,CAAC,eAAe,CAAC;QAC5D,IAAI,oBAAoB,GAAG,2BAAkB,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;QACnF,IAAI,qBAAqB,GAAG,oBAAoB,CAAC,UAAU,CAAC;QAE5D,IAAI,oBAAoB,EACxB;YACI,wFAAwF;YACxF,qBAAqB,GAAG,IAAI,CAAC,gBAAgB,CACzC,qBAAqB,EACrB,IAAI,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAC7D,CAAC;SACL;QAED,4DAA4D;QAC5D,IAAI,gBAAgB,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,qBAAqB,CAAC,CAAC;QAE/E,IAAI,gBAAgB,EACpB;YACI,qEAAqE;YACrE,IAAI,WAAW,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,EACnD;gBACI,YAAY;gBACZ,gBAAgB,GAAG,gBAAgB,CAAC;gBACpC,oBAAoB,GAAG,2BAAkB,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;gBAE/E,IAAI,oBAAoB,EACxB;oBACI,2CAA2C;oBAC3C,qBAAqB,GAAG,IAAI,CAAC,gBAAgB,CACzC,qBAAqB,EACrB,IAAI,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAC7D,CAAC;iBACL;aACJ;SACJ;QAED,IAAI,oBAAoB,IAAI,oBAAoB,CAAC,kBAAkB,EACnE;YACI,IAAM,gBAAc,GAAG,oBAAoB,CAAC;YAC5C,qDAAqD;YACrD,wDAAwD;YACxD,IAAM,wCAAsC,GAAG,EAAmB,CAAC;YAEnE,sCAAsC;YACtC,gBAAc,CAAC,WAAW,CAAC,OAAO,CAAC,UAAC,cAAc,EAAE,OAAO;gBAEvD,IAAM,WAAW,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;gBAC1C,IAAM,kBAAkB,GAAM,MAAM,CAAC,gBAAc,CAAC,SAAS,CAAC,SAAI,OAAS,CAAC;gBAE5E,IAAI,YAAY,CAAC;gBACjB,IAAI,cAAc,CAAC,YAAY,EAAE;oBAC7B,YAAY,GAAG,cAAc,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;iBAC3D;qBAAM,IAAI,cAAc,CAAC,IAAI,EAAE;oBAC5B,YAAY,GAAG,KAAI,CAAC,kBAAkB,CAClC,WAAW,EACX;wBACI,eAAe,EAAE,cAAc,CAAC,IAAI;wBACpC,kBAAkB,EAAE,cAAc,CAAC,WAAW;wBAC9C,cAAc,EAAE,cAAc,CAAC,OAAO;wBACtC,UAAU,EAAE,qBAAqB;qBACpC,EACD,kBAAkB,CACrB,CAAC;iBACL;qBAAM;oBACH,MAAM,IAAI,SAAS,CACf,wBAAsB,kBAAkB,cAAW;0BACjD,oDAAoD,CACzD,CAAC;iBACL;gBAED,IAAI,cAAc,CAAC,YAAY,CAAC,EAChC;oBACI,wCAAsC,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC;iBAC7E;qBACI,IAAI,cAAc,CAAC,UAAU,EAClC;oBACI,KAAI,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC,8BAA4B,kBAAkB,OAAI,CAAC,CAAC,CAAC;iBACzF;YACL,CAAC,CAAC,CAAC;YAEH,mCAAmC;YACnC,IAAI,YAAY,SAAe,CAAC;YAEhC,IAAI,OAAO,oBAAoB,CAAC,mBAAmB,KAAK,UAAU,EAClE;gBACI,IACA;oBACI,YAAY,GAAG,oBAAoB,CAAC,mBAAmB,CACnD,wCAAsC,EACtC,YAAY,CACf,CAAC;oBAEF,2DAA2D;oBAC3D,IAAI,CAAC,YAAY,EACjB;wBACI,MAAM,IAAI,SAAS,CACf,wBAAsB,UAAU,MAAG;8BACjC,iDAAiD;+BACjD,YAAU,MAAM,CAAC,oBAAoB,CAAC,SAAS,CAAC,oBAAiB,EACtE,CAAC;qBACL;yBACI,IAAI,CAAC,CAAC,YAAY,YAAY,oBAAoB,CAAC,SAAS,CAAC,EAClE;wBACI,MAAM,IAAI,SAAS,CACf,wBAAsB,UAAU,MAAG;+BACjC,6BAA2B,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,MAAG;+BAC9D,YAAU,MAAM,CAAC,oBAAoB,CAAC,SAAS,CAAC,oBAAiB;+BACjE,UAAQ,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,0BAAuB;+BAC/D,OAAK,MAAM,CAAC,oBAAoB,CAAC,SAAS,CAAC,MAAG,EACnD,CAAC;qBACL;iBACJ;gBACD,OAAO,CAAC,EACR;oBACI,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;oBACtB,OAAO,SAAS,CAAC;iBACpB;aACJ;iBAED;gBACI,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;aAC1D;YAED,4DAA4D;YAC5D,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,wCAAsC,CAAC,CAAC;YAEpE,uCAAuC;YACvC,IAAI,oBAAoB,CAAC,wBAAwB,EACjD;gBACI,IAAI,OAAQ,YAAY,CAAC,WAAmB,CAAC,oBAAoB,CAAC,wBAAwB,CAAC,KAAK,UAAU,EAC1G;oBACK,YAAY,CAAC,WAAmB,CAAC,oBAAoB,CAAC,wBAAwB,CAAC,EAAE,CAAC;iBACtF;qBAED;oBACI,IAAI,CAAC,aAAa,CAAC,IAAI,SAAS,CAC5B,8BAA4B,MAAM,CAAC,oBAAoB,CAAC,SAAS,CAAC,SAAI,oBAAoB,CAAC,wBAAwB,uBAAoB,CAC1I,CAAC,CAAC;iBACN;aACJ;YAED,OAAO,YAAY,CAAC;SACvB;aAED;YACI,gDAAgD;YAChD,IAAI,cAAY,GAAG,EAAmB,CAAC;YAEvC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,mBAAS;gBAEvC,cAAY,CAAC,SAAS,CAAC,GAAG,KAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE;oBACvE,eAAe,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,WAAW;oBACpD,UAAU,EAAE,oBAAoB,CAAC,UAAU;oBAC3C,kBAAkB,EAAE,oBAAoB,CAAC,kBAAkB;oBAC3D,cAAc,EAAE,oBAAoB,CAAC,cAAc;iBACtD,EAAE,SAAS,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;YAEH,OAAO,cAAY,CAAC;SACvB;IACL,CAAC;IAEM,yCAAkB,GAAzB,UAA0B,YAAiB,EAAE,QAAwB,EAAE,UAAqB;QAArB,kDAAqB;QAExF,IAAI,gBAAgB,GAAG,QAAQ,CAAC,eAAe,CAAC;QAChD,IAAI,mBAAmB,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QAExF,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,EACjC;YACI,OAAO,YAAY,CAAC;SACvB;aACI,IAAI,IAAI,CAAC,mCAAmC,CAAC,gBAAgB,CAAC,EACnE;YACI,IAAI,YAAY,CAAC,WAAW,KAAK,gBAAgB,EACjD;gBACI,OAAO,YAAY,CAAC;aACvB;iBAED;gBACI,MAAM,IAAI,SAAS,CAAC,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,YAAY,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;aACnH;SACJ;aACI,IAAI,gBAAgB,KAAK,IAAI,EAClC;YACI,2GAA2G;YAC3G,sDAAsD;YAEtD,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,CAAC,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,GAAG,CAAC,CAAC;gBAC1F,OAAO,IAAI,IAAI,CAAC,YAAmB,CAAC,CAAC;;gBAErC,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC;SACnG;aACI,IAAI,gBAAgB,KAAK,YAAY,EAC1C;YACI,0CAA0C;YAE1C,IAAI,YAAY,YAAY,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,cAAI,IAAI,QAAC,KAAK,CAAC,IAAI,CAAC,EAAZ,CAAY,CAAC;gBACzE,OAAO,IAAI,YAAY,CAAC,YAAY,CAAC,CAAC;;gBAEtC,IAAI,CAAC,uBAAuB,CAAC,cAAc,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC;SAC/G;aACI,IAAI,gBAAgB,KAAK,YAAY,EAC1C;YACI,0CAA0C;YAE1C,IAAI,YAAY,YAAY,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,cAAI,IAAI,QAAC,KAAK,CAAC,IAAI,CAAC,EAAZ,CAAY,CAAC;gBACzE,OAAO,IAAI,YAAY,CAAC,YAAY,CAAC,CAAC;;gBAEtC,IAAI,CAAC,uBAAuB,CAAC,cAAc,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC;SAC/G;aACI,IAAI,gBAAgB,KAAK,UAAU,EACxC;YACI,wCAAwC;YAExC,IAAI,YAAY,YAAY,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,cAAI,IAAI,QAAC,KAAK,CAAC,IAAI,CAAC,EAAZ,CAAY,CAAC;gBACzE,OAAO,IAAI,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,eAAK,IAAI,QAAC,CAAC,KAAK,EAAP,CAAO,CAAC,CAAC,CAAC;;gBAE1D,IAAI,CAAC,uBAAuB,CAAC,YAAY,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC;SAC7G;aACI,IAAI,gBAAgB,KAAK,iBAAiB,EAC/C;YACI,wCAAwC;YAExC,IAAI,YAAY,YAAY,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,cAAI,IAAI,QAAC,KAAK,CAAC,IAAI,CAAC,EAAZ,CAAY,CAAC;gBACzE,OAAO,IAAI,iBAAiB,CAAC,YAAY,CAAC,GAAG,CAAC,eAAK,IAAI,QAAC,CAAC,KAAK,EAAP,CAAO,CAAC,CAAC,CAAC;;gBAEjE,IAAI,CAAC,uBAAuB,CAAC,mBAAmB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC;SACpH;aACI,IAAI,gBAAgB,KAAK,WAAW,EACzC;YACI,yCAAyC;YAEzC,IAAI,YAAY,YAAY,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,cAAI,IAAI,QAAC,KAAK,CAAC,IAAI,CAAC,EAAZ,CAAY,CAAC;gBACzE,OAAO,IAAI,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,eAAK,IAAI,QAAC,CAAC,KAAK,EAAP,CAAO,CAAC,CAAC,CAAC;;gBAE3D,IAAI,CAAC,uBAAuB,CAAC,aAAa,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC;SAC9G;aACI,IAAI,gBAAgB,KAAK,WAAW,EACzC;YACI,yCAAyC;YAEzC,IAAI,YAAY,YAAY,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,cAAI,IAAI,QAAC,KAAK,CAAC,IAAI,CAAC,EAAZ,CAAY,CAAC;gBACzE,OAAO,IAAI,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,eAAK,IAAI,QAAC,CAAC,KAAK,EAAP,CAAO,CAAC,CAAC,CAAC;;gBAE3D,IAAI,CAAC,uBAAuB,CAAC,aAAa,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC;SAC9G;aACI,IAAI,gBAAgB,KAAK,WAAW,EACzC;YACI,IAAI,OAAO,YAAY,KAAK,QAAQ;gBAChC,OAAO,IAAI,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC;;gBAE/C,IAAI,CAAC,uBAAuB,CAAC,aAAa,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC;SACvG;aACI,IAAI,gBAAgB,KAAK,QAAQ,EACtC;YACI,IAAI,OAAO,YAAY,KAAK,QAAQ;gBAChC,OAAO,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;;gBAE5C,IAAI,CAAC,uBAAuB,CAAC,UAAU,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC;SACpG;aACI,IAAI,gBAAgB,KAAK,KAAK,EACnC;YACI,IAAI,YAAY,YAAY,KAAK;gBAC7B,OAAO,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;;gBAE/D,MAAM,IAAI,SAAS,CAAC,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;SACpG;aACI,IAAI,gBAAgB,KAAK,GAAG,EACjC;YACI,IAAI,YAAY,YAAY,KAAK;gBAC7B,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;;gBAE7D,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC;SACrF;aACI,IAAI,gBAAgB,KAAK,GAAG,EACjC;YACI,IAAI,YAAY,YAAY,KAAK;gBAC7B,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;;gBAE7D,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,0CAA0C,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC;SACxH;aACI,IAAI,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,EACzD;YACI,OAAO,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;SACnE;IACL,CAAC;IAEM,qCAAc,GAArB,UAAsB,YAAiB,EAAE,QAAwB,EAAE,UAAqB;QAAxF,iBAqCC;QArCkE,kDAAqB;QAEpF,IAAI,CAAC,CAAC,YAAY,YAAY,KAAK,CAAC,EACpC;YACI,IAAI,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;YAC3G,OAAO,EAAE,CAAC;SACb;QAED,IAAI,CAAC,QAAQ,CAAC,kBAAkB,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,EACvE;YACI,IAAI,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC,2BAAyB,UAAU,gEAA6D,CAAC,CAAC,CAAC;YACpI,OAAO,EAAE,CAAC;SACb;QAED,IAAI,eAAe,GAAmB;YAClC,eAAe,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAC/C,kBAAkB,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;YACxG,UAAU,EAAE,QAAQ,CAAC,UAAU;SAClC,CAAC;QAEF,OAAO,YAAY,CAAC,GAAG,CAAC,iBAAO;YAE3B,0IAA0I;YAC1I,mCAAmC;YACnC,IACA;gBACI,OAAO,KAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;aAC5D;YACD,OAAO,CAAC,EACR;gBACI,KAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;gBAEtB,wEAAwE;gBACxE,kFAAkF;gBAClF,OAAO,SAAS,CAAC;aACpB;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,mCAAY,GAAnB,UAAoB,YAAiB,EAAE,QAAwB,EAAE,UAAqB;QAAtF,iBAmCC;QAnCgE,kDAAqB;QAElF,IAAI,CAAC,CAAC,YAAY,YAAY,KAAK,CAAC,EACpC;YACI,IAAI,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;YAC3G,OAAO,IAAI,GAAG,EAAO,CAAC;SACzB;QAED,IAAI,CAAC,QAAQ,CAAC,kBAAkB,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,EACvE;YACI,IAAI,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC,2BAAyB,UAAU,4DAAyD,CAAC,CAAC,CAAC;YAChI,OAAO,IAAI,GAAG,EAAO,CAAC;SACzB;QAED,IAAI,eAAe,GAAmB;YAClC,eAAe,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAC/C,kBAAkB,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;YACxG,UAAU,EAAE,QAAQ,CAAC,UAAU;SAClC,CAAC;QACF,IAAI,SAAS,GAAG,IAAI,GAAG,EAAO,CAAC;QAE/B,YAAY,CAAC,OAAO,CAAC,UAAC,OAAO,EAAE,CAAC;YAE5B,IACA;gBACI,SAAS,CAAC,GAAG,CAAC,KAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,eAAe,EAAE,UAAU,IAAG,MAAI,CAAC,MAAG,EAAC,CAAC,CAAC;aAC3F;YACD,OAAO,CAAC,EACR;gBACI,0GAA0G;gBAC1G,KAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;aACzB;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,SAAS,CAAC;IACrB,CAAC;IAEM,mCAAY,GAAnB,UAAoB,YAAiB,EAAE,QAAwB,EAAE,UAAqB;QAAtF,iBAqDC;QArDgE,kDAAqB;QAElF,IAAI,CAAC,CAAC,YAAY,YAAY,KAAK,CAAC;YAChC,IAAI,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;QAE/G,IAAI,CAAC,QAAQ,CAAC,cAAc,EAC5B;YACI,IAAI,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC,2BAAyB,UAAU,sCAAmC,CAAC,CAAC,CAAC;YAC1G,OAAO,IAAI,GAAG,EAAY,CAAC;SAC9B;QAED,IAAI,CAAC,QAAQ,CAAC,kBAAkB,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,EACvE;YACI,IAAI,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC,2BAAyB,UAAU,wCAAqC,CAAC,CAAC,CAAC;YAC5G,OAAO,IAAI,GAAG,EAAY,CAAC;SAC9B;QAED,IAAI,WAAW,GAAmB;YAC9B,eAAe,EAAE,QAAQ,CAAC,cAAc;YACxC,UAAU,EAAE,QAAQ,CAAC,UAAU;SAClC,CAAC;QAEF,IAAI,aAAa,GAAmB;YAChC,eAAe,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAC/C,kBAAkB,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;YACxG,UAAU,EAAE,QAAQ,CAAC,UAAU;SAClC,CAAC;QAEF,IAAI,SAAS,GAAG,IAAI,GAAG,EAAY,CAAC;QAEpC,YAAY,CAAC,OAAO,CAAC,UAAC,OAAY;YAE9B,IACA;gBACI,IAAI,GAAG,GAAG,KAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;gBAE5D,iDAAiD;gBACjD,IAAI,cAAc,CAAC,GAAG,CAAC,EACvB;oBACI,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,KAAI,CAAC,kBAAkB,CACtC,OAAO,CAAC,KAAK,EAAE,aAAa,EAAK,UAAU,SAAI,GAAG,MAAG,CACxD,CAAC,CAAC;iBACN;aACJ;YACD,OAAO,CAAC,EACR;gBACI,4DAA4D;gBAC5D,gDAAgD;gBAChD,KAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;aACzB;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,SAAS,CAAC;IACrB,CAAC;IAEO,8CAAuB,GAA/B,UACI,UAAkB,EAClB,kBAA0B,EAC1B,gBAAwB,EACxB,UAA6B;QAA7B,kDAA6B;QAE7B,MAAM,IAAI,SAAS,CACf,2BAAyB,UAAU,YAAO,UAAU,MAAG;eACrD,eAAa,kBAAkB,cAAS,gBAAgB,MAAG,EAChE,CAAC;IACN,CAAC;IAEO,4CAAqB,GAA7B,UAA8B,YAA+B,EAAE,UAA6B,EAAE,UAAqB;QAArB,kDAAqB;QAE/G,IAAI,gBAAgB,GAAG,CAAC,OAAO,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;QAClG,IAAI,cAAc,GAAG,CAAC,OAAO,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;QAE1F,OAAO,2BAAyB,UAAU,oBAAe,gBAAgB,gBAAW,cAAc,OAAI,CAAC;IAC3G,CAAC;IAEO,uCAAgB,GAAxB,UAAyB,IAAS;QAE9B,OAAO,IAAI,IAAI,EAAE,CAAC;IACtB,CAAC;IAEO,uCAAgB,GAAxB;QAAA,iBAoBC;QApBwB,uBAA8C;aAA9C,UAA8C,EAA9C,qBAA8C,EAA9C,IAA8C;YAA9C,kCAA8C;;QAEnE,IAAI,MAAM,GAAG,IAAI,GAAG,EAAoB,CAAC;QAEzC,aAAa,CAAC,OAAO,CAAC,oBAAU;YAE5B,UAAU,CAAC,OAAO,CAAC,UAAC,IAAI,EAAE,IAAI;gBAE1B,IAAI,KAAI,CAAC,aAAa,EACtB;oBACI,MAAM,CAAC,GAAG,CAAC,KAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;iBAC9C;qBAED;oBACI,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;iBAC1B;YACL,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAClB,CAAC;IAEO,2CAAoB,GAA5B,UAA6B,SAAwB;QAArD,iBAqBC;QAnBG,IAAM,GAAG,GAAG,IAAI,GAAG,EAAoB,CAAC;QAExC,SAAS,CAAC,OAAO,CAAC,cAAI;YAElB,IAAI,KAAI,CAAC,aAAa,EACtB;gBACI,GAAG,CAAC,GAAG,CAAC,KAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;aAC3C;iBAED;gBACI,IAAM,aAAa,GAAG,2BAAkB,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;gBAClE,IAAM,MAAI,GAAG,aAAa,IAAI,aAAa,CAAC,kBAAkB,IAAI,aAAa,CAAC,IAAI;oBAChF,CAAC,CAAC,aAAa,CAAC,IAAI;oBACpB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;gBAChB,GAAG,CAAC,GAAG,CAAC,MAAI,EAAE,IAAI,CAAC,CAAC;aACvB;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,CAAC;IACf,CAAC;IAEO,0DAAmC,GAA3C,UAA4C,IAAS;QAEjD,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACtD,CAAC;IAEM,0CAAmB,GAA1B,UAA2B,YAAiB;QAExC,OAAO,YAAY,CAAC;IACxB,CAAC;IAEO,2CAAoB,GAA5B,UAA6B,GAAW;QAEpC,IAAI,GAAG,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,wBAAwB;QACnE,IAAI,OAAO,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC;QAEnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EACpD;YACI,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;SAClC;QAED,OAAO,GAAG,CAAC;IACf,CAAC;IAEO,wCAAiB,GAAzB,UAA0B,GAAW;QAEjC,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC;IACxD,CAAC;IACL,mBAAC;AAAD,CAAC;;;;;;;;;;;;;;;ACnkBmD;AACI;AACE;AAC0B;AA2CpF;IAkLI;;;;;OAKG;IACH,mBAAY,eAA+B,EAAE,QAA6B;QAjB1E,YAAY;QAEJ,eAAU,GAAe,IAAI,qBAAU,EAAE,CAAC;QAC1C,iBAAY,GAAoB,IAAI,yBAAY,EAAK,CAAC;QACtD,qBAAgB,GAA4B,EAAE,CAAC;QAC/C,WAAM,GAAW,CAAC,CAAC;QAcvB,IAAI,YAAY,GAAG,2BAAkB,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;QAE1E,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,YAAY,CAAC,kBAAkB,IAAI,CAAC,YAAY,CAAC,0BAA0B,CAAC,EACnG;YACI,MAAM,IAAI,SAAS,CAAC,wEAAwE,CAAC,CAAC;SACjG;QAED,IAAI,CAAC,YAAY,GAAG,UAAC,IAAI,IAAK,aAAM,CAAC,IAAI,CAAC,EAAZ,CAAY,CAAC;QAC3C,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,YAAY,GAAG,UAAC,KAAK,IAAK,eAAQ,CAAC,KAAK,CAAC,EAAf,CAAe,CAAC;QAE/C,IAAI,QAAQ,EACZ;YACI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;SACzB;aACI,IAAI,SAAS,CAAC,aAAa,EAChC;YACI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;SACnB;IACL,CAAC;IA3MD,gBAAgB;IACF,eAAK,GAAnB,UACI,MAAW,EAAE,QAAwB,EAAE,QAA6B;QAEpE,OAAO,IAAI,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3D,CAAC;IAgCa,sBAAY,GAA1B,UACI,MAAW,EACX,WAA2B,EAC3B,QAA6B,EAC7B,UAAmB;QAEnB,OAAO,IAAI,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,UAAiB,CAAC,CAAC;IACxF,CAAC;IAEa,oBAAU,GAAxB,UACI,MAAW,EAAE,WAA2B,EAAE,QAA6B;QAEvE,OAAO,IAAI,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACnE,CAAC;IAEa,oBAAU,GAAxB,UACI,MAAW,EACX,OAAuB,EACvB,SAAyB,EACzB,QAA6B;QAE7B,OAAO,IAAI,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1E,CAAC;IAEa,qBAAW,GAAzB,UACI,MAAS,EAAE,QAAwB,EAAE,QAA6B;QAElE,OAAO,IAAI,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACjE,CAAC;IAoBa,sBAAY,GAA1B,UACI,MAAa,EAAE,WAA2B,EAAE,UAAgB,EAAE,QAA6B;QAE3F,OAAO,IAAI,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACjF,CAAC;IAEa,oBAAU,GAAxB,UACI,MAAc,EAAE,WAA2B,EAAE,QAA6B;QAE1E,OAAO,IAAI,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IACvE,CAAC;IAEa,oBAAU,GAAxB,UACI,MAAiB,EACjB,OAAuB,EACvB,SAAyB,EACzB,QAA6B;QAE7B,OAAO,IAAI,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9E,CAAC;IAEa,mBAAS,GAAvB,UACI,MAAS,EAAE,QAAwB,EAAE,QAA6B;QAElE,OAAO,IAAI,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC/D,CAAC;IAoBa,0BAAgB,GAA9B,UACI,MAAa,EAAE,WAA2B,EAAE,UAAgB,EAAE,QAA6B;QAE3F,OAAO,IAAI,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,gBAAgB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACrF,CAAC;IAEa,wBAAc,GAA5B,UACI,MAAc,EAAE,WAA2B,EAAE,QAA6B;QAE1E,OAAO,IAAI,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IACvE,CAAC;IAEa,wBAAc,GAA5B,UACI,MAAiB,EACjB,OAAuB,EACvB,SAAyB,EACzB,QAA6B;QAE7B,OAAO,IAAI,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9E,CAAC;IAIa,yBAAe,GAA7B,UAA8B,MAA0B;QAEpD,IAAI,IAAI,CAAC,aAAa,EACtB;YACI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;SAC7C;aAED;YACI,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;SAC/B;IACL,CAAC;IA0CD;;;OAGG;IACI,0BAAM,GAAb,UAAc,QAA4B;QAEtC,IAAI,SAAS,CAAC,aAAa,EAC3B;YACI,QAAQ,GAAG,kBACJ,SAAS,CAAC,aAAa,EACvB,QAAQ,CACd,CAAC;YAEF,IAAI,QAAQ,CAAC,UAAU,IAAI,SAAS,CAAC,aAAa,CAAC,UAAU,EAC7D;gBACI,wEAAwE;gBACxE,QAAQ,CAAC,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CACpC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,UAAU,CAAC,CACjE,CAAC,CAAC;aACN;SACJ;QAED,IAAI,QAAQ,CAAC,YAAY,EACzB;YACI,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC;YAC1C,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YACzD,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;SAC1D;QAED,IAAI,QAAQ,CAAC,QAAQ;YAAE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;QACzD,IAAI,QAAQ,CAAC,YAAY;YAAE,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QACpF,IAAI,QAAQ,CAAC,eAAe;YAAE,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QAC3F,IAAI,QAAQ,CAAC,MAAM;YAAE,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAEnD,IAAI,QAAQ,CAAC,YAAY,EACzB;YACI,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC;YAC1C,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YACzD,sBAAsB;SACzB;QAED,IAAI,QAAQ,CAAC,UAAU,EACvB;YACI,iEAAiE;YACjE,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,UAAC,SAAS,EAAE,CAAC;gBAErC,2CAA2C;gBAC3C,IAAI,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,KAAK,IAAI,EAC1D;oBACI,UAAU,CACN,8EAA4E,CAAC,OAAI,CAAC,CAAC;iBAC1F;YACL,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC,UAAU,CAAC;SAC/C;IACL,CAAC;IAED;;;;;OAKG;IACI,yBAAK,GAAZ,UAAa,MAAW;QAAxB,iBAkCC;QAhCG,IAAM,IAAI,GAAG,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAE3D,IAAI,YAAY,GAAG,2BAAkB,CAAC,kBAAkB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC/E,IAAI,MAAmB,CAAC;QACxB,IAAI,UAAU,GAAG,IAAI,GAAG,EAAoB,CAAC;QAE7C,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,aAAG,IAAI,UAAG,EAAH,CAAG,CAAC,CAAC,OAAO,CAAC,uBAAa;YAE1D,UAAU,CAAC,GAAG,CAAC,KAAI,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QAEH,IAAI,YAAY,EAChB;YACI,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,uBAAa;gBAEzC,UAAU,CAAC,GAAG,CAAC,KAAI,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC;YACpE,CAAC,CAAC,CAAC;SACN;QAED,IACA;YACI,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,IAAI,EAAE;gBAChD,eAAe,EAAE,IAAI,CAAC,eAAe;gBACrC,UAAU,EAAE,UAAU;aACzB,CAAM,CAAC;SACX;QACD,OAAO,CAAC,EACR;YACI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;SACxB;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;IAQM,gCAAY,GAAnB,UAAoB,MAAW,EAAE,UAAsB;QAAtB,2CAAsB;QAEnD,IAAM,IAAI,GAAG,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC5C,IAAI,IAAI,YAAY,KAAK,EACzB;YACI,OAAO,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,EAAE;gBAC1C,eAAe,EAAE,KAAK;gBACtB,kBAAkB,EAAE,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC;qBACxC,IAAI,CAAC,KAAK,CAAC;qBACX,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC;gBACjC,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC;aACzD,CAAC,CAAC;SACN;aAED;YACI,IAAI,CAAC,YAAY,CAAC,IAAI,SAAS,CAAC,oCAAoC;mBAC9D,eAAa,OAAO,IAAI,MAAG,EAAC,CAAC,CAAC;SACvC;QAED,OAAO,EAAE,CAAC;IACd,CAAC;IAEM,8BAAU,GAAjB,UAAkB,MAAW;QAEzB,IAAM,IAAI,GAAG,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1C,iCAAiC;QACjC,IAAI,IAAI,YAAY,KAAK,EACzB;YACI,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,EAAE;gBACxC,eAAe,EAAE,KAAK;gBACtB,kBAAkB,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC;gBAC1C,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC;aACzD,CAAC,CAAC;SACN;aAED;YACI,IAAI,CAAC,YAAY,CAAC,IAAI,SAAS,CAAC,kDAAkD;mBAC5E,eAAa,OAAO,IAAI,MAAG,EAChC,CAAC,CAAC;SACN;QAED,OAAO,IAAI,GAAG,EAAK,CAAC;IACxB,CAAC;IAEM,8BAAU,GAAjB,UAAqB,MAAW,EAAE,cAA8B;QAE5D,IAAM,IAAI,GAAG,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1C,iCAAiC;QACjC,IAAI,IAAI,YAAY,KAAK,EACzB;YACI,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,EAAE;gBACxC,eAAe,EAAE,KAAK;gBACtB,kBAAkB,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC;gBAC1C,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC;gBACtD,cAAc,EAAE,cAAc;aACjC,CAAC,CAAC;SACN;aAED;YACI,IAAI,CAAC,YAAY,CAAC,IAAI,SAAS,CAAC,kDAAkD;mBAC5E,eAAa,OAAO,IAAI,MAAG,EAChC,CAAC,CAAC;SACN;QAED,OAAO,IAAI,GAAG,EAAQ,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACI,+BAAW,GAAlB,UAAmB,MAAS;QAExB,IACA;YACI,OAAO,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,MAAM,EAAE;gBAC9C,QAAQ,EAAE,IAAI,CAAC,eAAe;aACjC,CAAC,CAAC;SACN;QACD,OAAO,CAAC,EACR;YACI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;SACxB;IACL,CAAC;IAOM,gCAAY,GAAnB,UAAoB,MAAa,EAAE,UAAyB;QAAzB,2CAAyB;QAExD,IACA;YACI,IAAM,uBAAuB,GACzB,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACvE,OAAO,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;SAC1E;QACD,OAAO,CAAC,EACR;YACI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;SACxB;IACL,CAAC;IAEM,8BAAU,GAAjB,UAAkB,MAAc;QAE5B,IACA;YACI,OAAO,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;SACrE;QACD,OAAO,CAAC,EACR;YACI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;SACxB;IACL,CAAC;IAEM,8BAAU,GAAjB,UAAqB,MAAiB,EAAE,cAA8B;QAElE,IACA;YACI,OAAO,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;SACrF;QACD,OAAO,CAAC,EACR;YACI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;SACxB;IACL,CAAC;IAED;;;;;;OAMG;IACI,6BAAS,GAAhB,UAAiB,MAAS;QAEtB,IAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,MAAM,KAAK,SAAS,EAAE;YACtB,OAAO,EAAE,CAAC;SACb;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9D,CAAC;IAOM,oCAAgB,GAAvB,UAAwB,MAAa,EAAE,UAAe;QAElD,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7F,CAAC;IAEM,kCAAc,GAArB,UAAsB,MAAc;QAEhC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/E,CAAC;IAEM,kCAAc,GAArB,UAAyB,MAAiB,EAAE,cAA8B;QAEtE,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/F,CAAC;IAEO,kCAAc,GAAtB,UAAuB,YAAqC;QAA5D,iBAOC;QALG,IAAI,GAAG,GAAG,IAAI,GAAG,EAA4B,CAAC;QAE9C,YAAY,CAAC,MAAM,CAAC,cAAI,IAAI,WAAI,EAAJ,CAAI,CAAC,CAAC,OAAO,CAAC,cAAI,IAAI,UAAG,CAAC,GAAG,CAAC,KAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAtC,CAAsC,CAAC,CAAC;QAE1F,OAAO,GAAG,CAAC;IACf,CAAC;IACL,gBAAC;AAAD,CAAC;;;;ACphB8C;AACC;AA2DzC,SAAS,UAAU,CAAmB,eAAwD;IAEjG,IAAI,OAA8B,CAAC;IAEnC,IAAI,OAAO,eAAe,KAAK,UAAU,EACzC;QACI,qDAAqD;QACrD,OAAO,GAAG,EAAE,CAAC;KAChB;SAED;QACI,mDAAmD;QACnD,OAAO,GAAG,eAAe,IAAI,EAAE,CAAC;KACnC;IAED,SAAS,SAAS,CACd,MAAgB;QAEhB,IAAI,cAAkC,CAAC;QAEvC,8CAA8C;QAC9C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,kBAAkB,CAAC,EACxD;YACI,0EAA0E;YAC1E,cAAc,GAAG,IAAI,2BAAkB,CAAC,MAAM,CAAC,CAAC;YAEhD,yEAAyE;YACzE,IAAM,cAAc,GAAuB,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;YAChF,IAAI,cAAc,EAClB;gBACI,cAAc,CAAC,WAAW;qBACrB,OAAO,CAAC,UAAC,cAAc,EAAE,OAAO;oBAC7B,qBAAc,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,cAAc,CAAC;gBAAvD,CAAuD,CAAC,CAAC;gBACjE,cAAc,CAAC,UAAU;qBACpB,OAAO,CAAC,UAAC,SAAS,IAAK,qBAAc,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAxC,CAAwC,CAAC,CAAC;aACzE;YAED,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,EAAE,kBAAkB,EAAE;gBACxD,UAAU,EAAE,KAAK;gBACjB,YAAY,EAAE,KAAK;gBACnB,QAAQ,EAAE,KAAK;gBACf,KAAK,EAAE,cAAc;aACxB,CAAC,CAAC;SACN;aAED;YACI,4DAA4D;YAC5D,cAAc,GAAG,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;YACtD,cAAc,CAAC,SAAS,GAAG,MAAM,CAAC;SACrC;QAED,2BAA2B;QAC3B,cAAc,CAAC,kBAAkB,GAAG,IAAI,CAAC;QACzC,cAAc,CAAC,wBAAwB,GAAG,OAAO,CAAC,cAAc,CAAC;QACjE,gCAAgC;QAChC,cAAc,CAAC,mBAAmB,GAAG,OAAO,CAAC,WAAkB,CAAC;QAChE,IAAI,OAAO,CAAC,IAAI,EAChB;YACI,cAAc,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;SACtC;QAED,sBAAsB;QACtB,IAAI,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ,EAC1C;YACI,cAAc,CAAC,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;SAC3D;aACI,IAAI,OAAO,CAAC,UAAU,YAAY,KAAK,EAC5C;YACI,OAAO,CAAC,UAAU;iBACb,MAAM,CAAC,mBAAS,IAAI,QAAC,CAAC,SAAS,EAAX,CAAW,CAAC;iBAChC,OAAO,CAAC,mBAAS,IAAI,qBAAc,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAxC,CAAwC,CAAC,CAAC;SACvE;IACL,CAAC;IAED,IAAI,OAAO,eAAe,KAAK,UAAU,EACzC;QACI,qDAAqD;QACrD,SAAS,CAAC,eAAe,CAAC,CAAC;KAC9B;SAED;QACI,mDAAmD;QACnD,OAAO,SAAS,CAAC;KACpB;AACL,CAAC;;;AC/IkB;AACoC;AA4ChD,SAAS,UAAU,CAA6B,eAA6C,EAAE,OAAyB;IAE3H,IAAI,eAAe,YAAY,MAAM,IAAI,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,OAAO,KAAK,QAAQ,CAAC,EACrG;QACI,IAAM,MAAM,GAAG,eAAyB,CAAC;QACzC,sBAAsB;QACtB,IAAM,aAAa,GAAG,oBAAkB,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,SAAI,MAAM,CAAC,OAAO,CAAG,CAAC;QAExF,qGAAqG;QACrG,yDAAyD;QACzD,IAAI,0BAA0B,EAC9B;YACI,IAAM,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAa,CAAC;YAExF,IAAI,CAAC,eAAe,EACpB;gBACI,QAAQ,CAAI,aAAa,kEAA+D,CAAC,CAAC;gBAC1F,OAAO;aACV;YAED,IAAI,qBAAqB,CAAC,aAAa,EAAE,eAAe,CAAC,EACzD;gBACI,OAAO;aACV;YAED,yBAAyB,CAAC,MAAM,EAAE,OAAO,EAAE;gBACvC,IAAI,EAAE,eAAe;gBACrB,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE;gBACvB,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE;aAC3B,CAAC,CAAC;SACN;aAED;YACI,QAAQ,CAAI,aAAa,6EAA0E,CAAC,CAAC;YACrG,OAAO;SACV;KACJ;SAED;QACI,0CAA0C;QAC1C,OAAO,UAAC,MAAc,EAAE,QAAyB;YAE7C,IAAI,OAAO,GAAuB,eAAe,IAAI,EAAE,CAAC;YACxD,IAAI,QAA4B,CAAC;YACjC,IAAI,aAAa,GAAG,oBAAkB,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,SAAI,MAAM,CAAC,QAAQ,CAAG,CAAC,CAAC,sBAAsB;YAE9G,IAAI,OAAO,CAAC,cAAc,CAAC,aAAa,CAAC,EACzC;gBACI,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,WAAW,CAAC,EACxC;oBACI,QAAQ,CAAI,aAAa,gEAA6D,CAAC,CAAC;oBACxF,OAAO;iBACV;gBAED,2IAA2I;gBAC3I,IAAI,0BAA0B,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,EACzH;oBACI,UAAU,CAAI,aAAa,kEAA+D,CAAC,CAAC;iBAC/F;gBAED,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC;aAClC;iBAED;gBACI,wDAAwD;gBACxD,IAAI,0BAA0B,EAC9B;oBACI,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,CAAa,CAAC;oBAE5E,IAAI,CAAC,QAAQ,EACb;wBACI,QAAQ,CAAI,aAAa,+DAA4D,CAAC,CAAC;wBACvF,OAAO;qBACV;iBACJ;qBACI,IAAI,CAAC,OAAO,CAAC,YAAY,EAC9B;oBACI,QAAQ,CAAI,aAAa,6EAA0E,CAAC,CAAC;oBACrG,OAAO;iBACV;aACJ;YAED,IAAI,qBAAqB,CAAC,aAAa,EAAE,QAAQ,CAAC,EAClD;gBACI,OAAO;aACV;YAED,yBAAyB,CAAC,MAAM,EAAE,QAAQ,EAAE;gBACxC,IAAI,EAAE,QAAQ;gBACd,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,KAAK;gBACnD,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,KAAK;gBACvC,GAAG,EAAE,QAAQ,CAAC,QAAQ,EAAE;gBACxB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC,QAAQ,EAAE;gBACzC,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,UAAU,EAAE,OAAO,CAAC,UAAU;aACjC,CAAC,CAAC;QACP,CAAC,CAAC;KACL;AACL,CAAC;AAED,SAAS,qBAAqB,CAAC,aAAqB,EAAE,QAAmB;IAErE,IAAI,QAAQ,KAAK,KAAK,EACtB;QACI,QAAQ,CAAI,aAAa,iEAA8D;cACjF,2BAA2B,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;KACf;IAED,IAAI,QAAQ,KAAK,GAAG,EACpB;QACI,QAAQ,CAAI,aAAa,4DAAyD;cAC5E,2BAA2B,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;KACf;IAED,IAAI,QAAQ,KAAK,GAAG,EACpB;QACI,QAAQ,CAAI,aAAa,4DAAyD;cAC5E,2BAA2B,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;KACf;IAED,OAAO,KAAK,CAAC;AACjB,CAAC;;;AC3KwE;AAClB;AA4BvD;;;;GAIG;AACI,SAAS,eAAe,CAAC,kBAA4B,EAAE,OAAqC;IAArC,sCAAqC;IAE/F,OAAO,UAAC,MAAc,EAAE,OAAwB;QAE5C,IAAI,aAAa,GAAG,yBAAuB,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,SAAI,MAAM,CAAC,OAAO,CAAG,CAAC,CAAC,sBAAsB;QAElH,IAAI,OAAO,kBAAkB,KAAK,UAAU,EAC5C;YACI,QAAQ,CAAI,aAAa,kEAA+D,CAAC,CAAC;YAC1F,OAAO;SACV;QAED,IAAM,UAAU,GAAG,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;QAC7E,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EACxC;YACI,QAAQ,CAAI,aAAa,8CAA2C,CAAC,CAAC;YACtE,OAAO;SACV;QAED,0GAA0G;QAC1G,IAAI,0BAA0B,IAAI,OAAO,CAAC,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,KAAK,EAC/F;YACI,QAAQ,CAAI,aAAa,gCAA6B,CAAC,CAAC;YACxD,OAAO;SACV;QAED,yBAAyB,CAAC,MAAM,EAAE,OAAO,EAAE;YACvC,IAAI,EAAE,KAAK;YACX,WAAW,EAAE,sBAAsB,CAAC,kBAAkB,EAAE,UAAU,CAAC;YACnE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,KAAK;YACnD,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,KAAK;YACvC,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE;YACvB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,QAAQ,EAAE;YACxC,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,UAAU,EAAE,OAAO,CAAC,UAAU;SACjC,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC;AAED,SAAS,sBAAsB,CAAC,WAAqB,EAAE,UAAkB;IACrE,IAAM,YAAY,GAAG,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9D,YAAY,CAAC,UAAU,GAAC,CAAC,CAAC,GAAG,WAAW,CAAC;IACzC,OAAO,YAAY,CAAC;AACxB,CAAC;;;AC7EkC;AAE4D;AAC1D;AAyBrC;;;;;GAKG;AACI,SAAS,aAAa,CAAC,kBAA4B,EAAE,OAAmC;IAAnC,sCAAmC;IAE3F,OAAO,UAAC,MAAc,EAAE,OAAwB;QAE5C,IAAI,aAAa,GAAG,uBAAqB,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,SAAI,MAAM,CAAC,OAAO,CAAG,CAAC,CAAC,sBAAsB;QAEhH,IAAI,OAAO,kBAAkB,KAAK,UAAU,EAC5C;YACI,QAAgB,CAAI,aAAa,gEAA6D,CAAC,CAAC;YAChG,OAAO;SACV;QAED,kHAAkH;QAClH,IAAI,0BAAkC,IAAI,OAAO,CAAC,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,GAAG,EACrG;YACI,QAAgB,CAAI,aAAa,6BAA0B,CAAC,CAAC;YAC7D,OAAO;SACV;QAED,yBAAyB,CAAC,MAAM,EAAE,OAAO,EAAE;YACvC,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,CAAC,kBAAkB,CAAC;YACjC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,KAAK;YACnD,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,KAAK;YACvC,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE;YACvB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,QAAQ,EAAE;YACxC,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,UAAU,EAAE,OAAO,CAAC,UAAU;SACjC,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC;;;AChEwE;AAClB;AAyBvD;;;;;;GAMG;AACI,SAAS,aAAa,CAAC,cAAwB,EAAE,gBAA0B,EAAE,OAAmC;IAAnC,sCAAmC;IAEnH,OAAO,UAAC,MAAc,EAAE,OAAwB;QAE5C,IAAI,aAAa,GAAG,uBAAqB,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,SAAI,MAAM,CAAC,OAAO,CAAG,CAAC,CAAC,sBAAsB;QAEhH,IAAI,OAAO,cAAc,KAAK,UAAU,EACxC;YACI,QAAQ,CAAI,aAAa,4DAAyD,CAAC,CAAC;YACpF,OAAO;SACV;QAED,IAAI,OAAO,gBAAgB,KAAK,UAAU,EAC1C;YACI,QAAQ,CAAI,aAAa,8DAA2D,CAAC,CAAC;YACtF,OAAO;SACV;QAED,kHAAkH;QAClH,IAAI,0BAA0B,IAAI,OAAO,CAAC,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,GAAG,EAC7F;YACI,QAAQ,CAAI,aAAa,6BAA0B,CAAC,CAAC;YACrD,OAAO;SACV;QAED,yBAAyB,CAAC,MAAM,EAAE,OAAO,EAAE;YACvC,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,CAAC,gBAAgB,CAAC;YAC/B,OAAO,EAAE,cAAc;YACvB,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,KAAK;YACnD,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,KAAK;YACvC,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE;YACvB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,QAAQ,EAAE;YACxC,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,UAAU,EAAE,OAAO,CAAC,UAAU;SACjC,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC;;;ACtED;AAAA;AAAA;AAAA;AAAA;AAAA;AAAoE;AACf;AACA;AACW;AACJ;AACA","file":"typedjson.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"typedjson\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"typedjson\"] = factory();\n\telse\n\t\troot[\"typedjson\"] = factory();\n})((typeof self !== 'undefined' ? self : this), function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","declare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport const METADATA_FIELD_KEY = \"__typedJsonJsonObjectMetadataInformation__\";\n\nexport function getDefaultValue(type: { new (): T }): T|undefined\n{\n switch (type as any)\n {\n case Number:\n return 0 as any;\n\n case String:\n return \"\" as any;\n\n case Boolean:\n return false as any;\n\n case Array:\n return [] as any;\n\n default:\n return undefined;\n }\n}\n\n/**\n * Determines whether the specified type is a type that can be passed on \"as-is\" into `JSON.stringify`.\n * Values of these types don't need special conversion.\n * @param type The constructor of the type (wrapper constructor for primitive types, e.g. `Number` for `number`).\n */\nexport function isDirectlySerializableNativeType(type: Function): boolean\n{\n return !!(~[Date, Number, String, Boolean].indexOf(type as any));\n}\n\nexport function isTypeTypedArray(type: Function): boolean\n{\n return !!(~[Float32Array, Float64Array, Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array]\n .indexOf(type as any));\n}\n\nexport function isPrimitiveValue(obj: any): boolean\n{\n switch (typeof obj)\n {\n case \"string\":\n case \"number\":\n case \"boolean\":\n return true;\n default:\n return (obj instanceof String || obj instanceof Number || obj instanceof Boolean);\n }\n}\n\nexport function isObject(value: any): value is Object\n{\n return typeof value === \"object\";\n}\n\nfunction shouldOmitParseString(jsonStr: string, expectedType: Function): boolean {\n const expectsTypesSerializedAsStrings = expectedType === String\n || expectedType === ArrayBuffer\n || expectedType === DataView;\n\n const hasQuotes = jsonStr.length >= 2 && jsonStr[0] === '\"' && jsonStr[jsonStr.length-1] === '\"';\n const isInteger = /^\\d+$/.test(jsonStr.trim());\n\n return (expectsTypesSerializedAsStrings && !hasQuotes) || ((!hasQuotes && !isInteger) && expectedType === Date);\n}\n\nexport function parseToJSObject(json: any, expectedType: Function): Object {\n if (typeof json !== 'string' || shouldOmitParseString(json, expectedType))\n {\n return json;\n }\n return JSON.parse(json);\n}\n\n/**\n * Determines if 'A' is a sub-type of 'B' (or if 'A' equals 'B').\n * @param A The supposed derived type.\n * @param B The supposed base type.\n */\nexport function isSubtypeOf(A: Function, B: Function)\n{\n return A === B || A.prototype instanceof B;\n}\n\nexport function logError(message?: any, ...optionalParams: any[])\n{\n if (typeof console === \"object\" && typeof console.error === \"function\")\n {\n console.error(message, ...optionalParams);\n }\n else if (typeof console === \"object\" && typeof console.log === \"function\")\n {\n console.log(`ERROR: ${message}`, ...optionalParams);\n }\n}\n\nexport function logMessage(message?: any, ...optionalParams: any[])\n{\n if (typeof console === \"object\" && typeof console.log === \"function\")\n {\n console.log(message, ...optionalParams);\n }\n}\n\nexport function logWarning(message?: any, ...optionalParams: any[])\n{\n if (typeof console === \"object\" && typeof console.warn === \"function\")\n {\n console.warn(message, ...optionalParams);\n } else if (typeof console === \"object\" && typeof console.log === \"function\")\n {\n console.log(`WARNING: ${message}`, ...optionalParams);\n }\n}\n\n/**\n * Checks if the value is considered defined (not undefined and not null).\n * @param value\n */\nexport function isValueDefined(value: T): value is Exclude\n{\n return !(typeof value === \"undefined\" || value === null);\n}\n\nexport function isInstanceOf(value: any, constructor: Function): boolean\n{\n if (typeof value === \"number\")\n {\n return (constructor === Number);\n }\n else if (typeof value === \"string\")\n {\n return (constructor === String);\n }\n else if (typeof value === \"boolean\")\n {\n return (constructor === Boolean);\n }\n else if (isObject(value))\n {\n return (value instanceof constructor);\n }\n\n return false;\n}\n\nexport const isReflectMetadataSupported =\n (typeof Reflect === \"object\" && typeof Reflect.getMetadata === \"function\");\n\n/**\n * Gets the name of a function.\n * @param fn The function whose name to get.\n */\nexport function nameof(fn: Function & { name?: string })\n{\n if (typeof fn.name === \"string\")\n {\n return fn.name;\n }\n else\n {\n return \"undefined\";\n }\n}\n","import { nameof, logError, METADATA_FIELD_KEY, isDirectlySerializableNativeType, isTypeTypedArray } from \"./helpers\";\nimport { IndexedObject } from \"./types\";\n\nexport interface JsonMemberMetadata\n{\n /** If set, a default value will be emitted for uninitialized members. */\n emitDefaultValue?: boolean;\n\n /** Member name as it appears in the serialized JSON. */\n name: string;\n\n /** Property or field key of the json member. */\n key: string;\n\n /** Constuctor (type) reference of the member. */\n ctor?: Function;\n\n /** If set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** If the json member is an array, map or set, sets member options of elements/values. Subsequent values define the types of nested arrays. */\n elementType?: Function[];\n\n /** If the json member is a map, sets member options of array keys. */\n keyType?: Function;\n\n /** Custom deserializer to use. */\n deserializer?: (json: any) => any;\n\n /** Custom serializer to use. */\n serializer?: (value: any) => any;\n}\n\nexport class JsonObjectMetadata\n{\n //#region Static\n /**\n * Gets the name of a class as it appears in a serialized JSON string.\n * @param ctor The constructor of a class (with or without jsonObject).\n */\n public static getJsonObjectName(ctor: Function): string\n {\n const metadata = JsonObjectMetadata.getFromConstructor(ctor);\n return metadata ? nameof(metadata.classType) : nameof(ctor);\n }\n\n /**\n * Gets jsonObject metadata information from a class.\n * @param ctor The constructor class.\n */\n public static getFromConstructor(ctor: Function): JsonObjectMetadata|undefined\n {\n const prototype = ctor.prototype;\n if (!prototype)\n {\n return;\n }\n\n let metadata: JsonObjectMetadata|undefined;\n if (prototype.hasOwnProperty(METADATA_FIELD_KEY))\n {\n // The class prototype contains own jsonObject metadata\n metadata = prototype[METADATA_FIELD_KEY];\n }\n\n // Ignore implicitly added jsonObject (through jsonMember)\n if (metadata && metadata.isExplicitlyMarked)\n {\n return metadata;\n }\n\n // In the end maybe it is something which we can handle directly\n if (JsonObjectMetadata.doesHandleWithoutAnnotation(ctor))\n {\n const primitiveMeta = new JsonObjectMetadata(ctor);\n primitiveMeta.isExplicitlyMarked = true;\n // we do not store the metadata here to not modify builtin prototype\n return primitiveMeta;\n }\n }\n\n /**\n * Gets the known type name of a jsonObject class for type hint.\n * @param constructor The constructor class.\n */\n public static getKnownTypeNameFromType(constructor: Function): string\n {\n const metadata = JsonObjectMetadata.getFromConstructor(constructor);\n return metadata ? nameof(metadata.classType) : nameof(constructor);\n }\n\n private static doesHandleWithoutAnnotation(ctor: Function): boolean\n {\n return isDirectlySerializableNativeType(ctor) || isTypeTypedArray(ctor)\n || ctor === DataView || ctor === ArrayBuffer;\n }\n //#endregion\n\n constructor(\n classType: Function,\n ) {\n this.classType = classType;\n }\n\n public dataMembers: Map = new Map();\n\n public knownTypes: Set = new Set();\n\n public knownTypeMethodName?: string;\n\n /** Gets or sets the constructor function for the jsonObject. */\n public classType: Function;\n\n /**\n * Indicates whether this class was explicitly annotated with @jsonObject\n * or implicitly by @jsonMember\n */\n public isExplicitlyMarked: boolean = false;\n\n /**\n * Indicates whether this type is handled without annotation. This is usually\n * used for the builtin types (except for Maps, Sets, and normal Arrays).\n */\n public isHandledWithoutAnnotation: boolean = false;\n\n /** Name used to encode polymorphic type */\n public name?: string;\n\n public onDeserializedMethodName?: string;\n\n public initializerCallback?: (sourceObject: Object, rawSourceObject: Object) => Object;\n}\n\nexport function injectMetadataInformation(constructor: IndexedObject, propKey: string | symbol, metadata: JsonMemberMetadata)\n{\n const decoratorName = `@jsonMember on ${nameof(constructor.constructor)}.${String(propKey)}`; // For error messages.\n let objectMetadata: JsonObjectMetadata;\n\n // When a property decorator is applied to a static member, 'constructor' is a constructor function.\n // See: https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Decorators.md#property-decorators\n // ... and static members are not supported here, so abort.\n if (typeof constructor === \"function\")\n {\n logError(`${decoratorName}: cannot use a static property.`);\n return;\n }\n\n // Methods cannot be serialized.\n // @ts-ignore symbol indexing is not supported by ts\n if (typeof constructor[propKey] === \"function\")\n {\n logError(`${decoratorName}: cannot use a method property.`);\n return;\n }\n\n if (!metadata || (!metadata.ctor && !metadata.deserializer))\n {\n logError(`${decoratorName}: JsonMemberMetadata has unknown ctor.`);\n return;\n }\n\n // Add jsonObject metadata to 'constructor' if not yet exists ('constructor' is the prototype).\n // NOTE: this will not fire up custom serialization, as 'constructor' must be explicitly marked with '@jsonObject' as well.\n if (!constructor.hasOwnProperty(METADATA_FIELD_KEY))\n {\n // No *own* metadata, create new.\n objectMetadata = new JsonObjectMetadata(constructor.constructor);\n\n // Inherit @JsonMembers from parent @jsonObject (if any).\n const parentMetadata: JsonObjectMetadata = constructor[METADATA_FIELD_KEY];\n if (parentMetadata) // && !constructor.hasOwnProperty(Helpers.METADATA_FIELD_KEY)\n {\n parentMetadata.dataMembers.forEach((_metadata, _propKey) => objectMetadata.dataMembers.set(_propKey, _metadata));\n }\n\n // ('constructor' is the prototype of the involved class, metadata information is added to this class prototype).\n Object.defineProperty(constructor, METADATA_FIELD_KEY, {\n enumerable: false,\n configurable: false,\n writable: false,\n value: objectMetadata\n });\n }\n else\n {\n // JsonObjectMetadata already exists on 'constructor'.\n objectMetadata = constructor[METADATA_FIELD_KEY];\n }\n\n if (!metadata.deserializer)\n {\n // @ts-ignore above is a check (!deser && !ctor)\n objectMetadata.knownTypes.add(metadata.ctor);\n }\n\n if (metadata.keyType)\n objectMetadata.knownTypes.add(metadata.keyType);\n\n if (metadata.elementType)\n metadata.elementType.forEach(elemCtor => objectMetadata.knownTypes.add(elemCtor));\n\n objectMetadata.dataMembers.set(metadata.name, metadata);\n}\n","import { nameof, logError, isValueDefined, isInstanceOf, isTypeTypedArray, isDirectlySerializableNativeType } from \"./helpers\";\nimport { IndexedObject } from \"./types\";\nimport { JsonObjectMetadata } from \"./metadata\";\n\nexport interface IScopeTypeInfo\n{\n selfType: Function;\n elementTypes?: Function[];\n keyType?: Function;\n}\n\nexport interface IScopeArrayTypeInfo extends IScopeTypeInfo\n{\n selfType: new () => Array;\n elementTypes: Function[];\n}\n\nfunction isArrayTypeInfo(typeInfo: IScopeTypeInfo): typeInfo is IScopeArrayTypeInfo {\n return typeInfo.selfType === Array;\n}\n\nexport interface IScopeSetTypeInfo extends IScopeTypeInfo\n{\n selfType: new () => Set;\n elementTypes: [Function];\n}\n\nfunction isSetTypeInfo(typeInfo: IScopeTypeInfo): typeInfo is IScopeSetTypeInfo {\n return typeInfo.selfType === Set;\n}\n\nexport interface IScopeMapTypeInfo extends IScopeTypeInfo\n{\n selfType: new () => Map;\n elementTypes: [Function];\n keyType: Function;\n}\n\nfunction isMapTypeInfo(typeInfo: IScopeTypeInfo): typeInfo is IScopeMapTypeInfo {\n return typeInfo.selfType === Map;\n}\n\n/**\n * Utility class, converts a typed object tree (i.e. a tree of class instances, arrays of class instances, and so on) to an untyped javascript object (also\n * called \"simple javascript object\"), and emits any necessary type hints in the process (for polymorphism).\n *\n * The converted object tree is what will be given to `JSON.stringify` to convert to string as the last step, the serialization is basically like:\n *\n * (1) typed object-tree -> (2) simple JS object-tree -> (3) JSON-string\n */\nexport class Serializer\n{\n private _typeHintEmitter: (targetObject: IndexedObject, sourceObject: IndexedObject, expectedSourceType: Function, sourceTypeMetadata?: JsonObjectMetadata) => void;\n private _errorHandler: (error: Error) => void;\n\n constructor()\n {\n this._typeHintEmitter = (targetObject, sourceObject, expectedSourceType, sourceTypeMetadata?: JsonObjectMetadata) =>\n {\n // By default, we put a \"__type\" property on the output object if the actual object is not the same as the expected one, so that deserialization\n // will know what to deserialize into (given the required known-types are defined, and the object is a valid subtype of the expected type).\n if (sourceObject.constructor !== expectedSourceType)\n {\n const name = sourceTypeMetadata && sourceTypeMetadata.name\n ? sourceTypeMetadata.name\n : nameof(sourceObject.constructor);\n // TODO: Perhaps this can work correctly without string-literal access?\n // tslint:disable-next-line:no-string-literal\n targetObject[\"__type\"] = name;\n }\n };\n\n this._errorHandler = (error) => logError(error);\n }\n\n public setTypeHintEmitter(typeEmitterCallback: (targetObject: Object, sourceObject: Object, expectedSourceType: Function) => void)\n {\n if (typeof typeEmitterCallback !== \"function\")\n {\n throw new TypeError(\"'typeEmitterCallback' is not a function.\");\n }\n\n this._typeHintEmitter = typeEmitterCallback;\n }\n\n public setErrorHandler(errorHandlerCallback: (error: Error) => void)\n {\n if (typeof errorHandlerCallback !== \"function\")\n {\n throw new TypeError(\"'errorHandlerCallback' is not a function.\");\n }\n\n this._errorHandler = errorHandlerCallback;\n }\n\n /**\n * Convert a value of any supported serializable type.\n * The value type will be detected, and the correct serialization method will be called.\n */\n public convertSingleValue(sourceObject: any, typeInfo: IScopeTypeInfo, memberName: string = \"object\"): any\n {\n if (!isValueDefined(sourceObject)) return;\n\n if (!isInstanceOf(sourceObject, typeInfo.selfType))\n {\n let expectedName = nameof(typeInfo.selfType);\n let actualName = nameof(sourceObject.constructor);\n\n this._errorHandler(new TypeError(`Could not serialize '${memberName}': expected '${expectedName}', got '${actualName}'.`));\n return;\n }\n\n if (isDirectlySerializableNativeType(typeInfo.selfType))\n {\n return sourceObject;\n }\n else if (typeInfo.selfType === ArrayBuffer)\n {\n return this.convertAsArrayBuffer(sourceObject);\n }\n else if (typeInfo.selfType === DataView)\n {\n return this.convertAsDataView(sourceObject);\n }\n else if (isArrayTypeInfo(typeInfo))\n {\n return this.convertAsArray(sourceObject, typeInfo.elementTypes, memberName);\n }\n else if (isSetTypeInfo(typeInfo))\n {\n return this.convertAsSet(sourceObject, typeInfo.elementTypes[0], memberName);\n }\n else if (isMapTypeInfo(typeInfo))\n {\n return this.convertAsMap(sourceObject, typeInfo.keyType, typeInfo.elementTypes[0], memberName);\n }\n else if (isTypeTypedArray(typeInfo.selfType))\n {\n return this.convertAsTypedArray(sourceObject);\n }\n else if (typeof sourceObject === \"object\")\n {\n return this.convertAsObject(sourceObject, typeInfo, memberName);\n }\n }\n\n /**\n * Performs the conversion of a typed object (usually a class instance) to a simple javascript object for serialization.\n */\n public convertAsObject(sourceObject: IndexedObject, typeInfo: IScopeTypeInfo, memberName?: string)\n {\n let sourceTypeMetadata: JsonObjectMetadata|undefined;\n let targetObject: IndexedObject;\n\n if (sourceObject.constructor !== typeInfo.selfType && sourceObject instanceof typeInfo.selfType)\n {\n // The source object is not of the expected type, but it is a valid subtype.\n // This is OK, and we'll proceed to gather object metadata from the subtype instead.\n sourceTypeMetadata = JsonObjectMetadata.getFromConstructor(sourceObject.constructor);\n }\n else\n {\n sourceTypeMetadata = JsonObjectMetadata.getFromConstructor(typeInfo.selfType);\n }\n\n if (sourceTypeMetadata)\n {\n const sourceMeta = sourceTypeMetadata;\n // Strong-typed serialization available.\n // We'll serialize by members that have been marked with @jsonMember (including array/set/map members), and perform recursive conversion on\n // each of them. The converted objects are put on the 'targetObject', which is what will be put into 'JSON.stringify' finally.\n targetObject = {};\n\n sourceTypeMetadata.dataMembers.forEach((memberMetadata) =>\n {\n if (memberMetadata.serializer) {\n targetObject[memberMetadata.name] =\n memberMetadata.serializer(sourceObject[memberMetadata.key]);\n } else if (memberMetadata.ctor) {\n targetObject[memberMetadata.name] = this.convertSingleValue(\n sourceObject[memberMetadata.key],\n {\n selfType: memberMetadata.ctor,\n elementTypes: memberMetadata.elementType,\n keyType: memberMetadata.keyType,\n },\n `${nameof(sourceMeta.classType)}.${memberMetadata.key}`,\n );\n } else {\n throw new TypeError(\n `Could not serialize ${memberMetadata.name}, there is`\n + ` no constructor nor serialization function to use.`,\n );\n }\n });\n }\n else\n {\n // Untyped serialization, \"as-is\", we'll just pass the object on.\n // We'll clone the source object, because type hints are added to the object itself, and we don't want to modify to the original object.\n targetObject = { ...sourceObject };\n }\n\n // Add type-hint.\n this._typeHintEmitter(targetObject, sourceObject, typeInfo.selfType, sourceTypeMetadata);\n\n return targetObject;\n }\n\n /**\n * Performs the conversion of an array of typed objects (or primitive values) to an array of simple javascript objects (or primitive values) for\n * serialization.\n * @param expectedElementType The expected type of elements. If the array is supposed to be multi-dimensional, subsequent elements define lower dimensions.\n * @param memberName Name of the object being serialized, used for debugging purposes.\n */\n public convertAsArray(sourceObject: any[], expectedElementType: Function[], memberName = \"object\"): any[]\n {\n if (expectedElementType.length === 0 || !expectedElementType[0])\n throw new TypeError(`Could not serialize ${memberName} as Array: missing element type definition.`);\n\n // Check the type of each element, individually.\n // If at least one array element type is incorrect, we return undefined, which results in no value emitted during serialization.\n // This is so that invalid element types don't unexpectedly alter the ordering of other, valid elements, and that no unexpected undefined values are in\n // the emitted array.\n sourceObject.forEach((element, i) =>\n {\n if (!isInstanceOf(element, expectedElementType[0]))\n {\n const expectedTypeName = nameof(expectedElementType[0]);\n const actualTypeName = nameof(element.constructor);\n throw new TypeError(`Could not serialize ${memberName}[${i}]: expected '${expectedTypeName}', got '${actualTypeName}'.`);\n }\n });\n\n const typeInfoForElements: IScopeTypeInfo = {\n selfType: expectedElementType[0],\n elementTypes: expectedElementType.length > 1 ? expectedElementType.slice(1) : [], // For multidimensional arrays.\n };\n\n if (memberName)\n {\n // Just for debugging purposes.\n memberName += \"[]\";\n }\n\n return sourceObject.map(element => this.convertSingleValue(element, typeInfoForElements, memberName));\n }\n\n /**\n * Performs the conversion of a set of typed objects (or primitive values) into an array of simple javascript objects.\n *\n * @param sourceObject\n * @param expectedElementType The constructor of the expected Set elements (e.g. `Number` for `Set`, or `MyClass` for `Set`).\n * @param memberName Name of the object being serialized, used for debugging purposes.\n * @returns\n */\n public convertAsSet(sourceObject: Set, expectedElementType: Function, memberName = \"object\"): any[]\n {\n if (!expectedElementType)\n throw new TypeError(`Could not serialize ${memberName} as Set: missing element type definition.`);\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfType: expectedElementType,\n };\n\n // For debugging and error tracking.\n if (memberName) memberName += \"[]\";\n\n let resultArray: any[] = [];\n\n // Convert each element of the set, and put it into an output array.\n // The output array is the one serialized, as JSON.stringify does not support Set serialization. (TODO: clarification needed)\n sourceObject.forEach(element =>\n {\n let resultElement = this.convertSingleValue(element, elementTypeInfo, memberName);\n\n // Add to output if the source element was undefined, OR the converted element is defined. This will add intentionally undefined values to output,\n // but not values that became undefined DURING serializing (usually because of a type-error).\n if (!isValueDefined(element) || isValueDefined(resultElement))\n {\n resultArray.push(resultElement);\n }\n });\n\n return resultArray;\n }\n\n /**\n * Performs the conversion of a map of typed objects (or primitive values) into an array of simple javascript objects with `key` and `value` properties.\n *\n * @param sourceObject\n * @param expectedKeyType The constructor of the expected Map keys (e.g. `Number` for `Map`, or `MyClass` for `Map`).\n * @param expectedElementType The constructor of the expected Map values (e.g. `Number` for `Map`, or `MyClass` for `Map`).\n * @param memberName Name of the object being serialized, used for debugging purposes.\n */\n public convertAsMap(sourceObject: Map, expectedKeyType: Function, expectedElementType: Function, memberName = \"object\"): Array<{ key: any, value: any }>\n {\n if (!expectedElementType)\n throw new TypeError(`Could not serialize ${memberName} as Map: missing value type definition.`);\n\n if (!expectedKeyType)\n throw new TypeError(`Could not serialize ${memberName} as Map: missing key type definition.`);\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfType: expectedElementType,\n elementTypes: [expectedElementType]\n };\n\n let keyTypeInfo: IScopeTypeInfo = {\n selfType: expectedKeyType\n };\n\n if (memberName) memberName += \"[]\";\n\n let resultArray: Array<{ key: any, value: any }> = [];\n\n // Convert each *entry* in the map to a simple javascript object with key and value properties.\n sourceObject.forEach((value, key) =>\n {\n let resultKeyValuePairObj = {\n key: this.convertSingleValue(key, keyTypeInfo, memberName),\n value: this.convertSingleValue(value, elementTypeInfo, memberName)\n };\n\n // We are not going to emit entries with undefined keys OR undefined values.\n if (isValueDefined(resultKeyValuePairObj.key) && isValueDefined(resultKeyValuePairObj.value))\n {\n resultArray.push(resultKeyValuePairObj);\n }\n });\n\n return resultArray;\n }\n\n /**\n * Performs the conversion of a typed javascript array to a simple untyped javascript array.\n * This is needed because typed arrays are otherwise serialized as objects, so we'll end up with something like \"{ 0: 0, 1: 1, ... }\".\n *\n * @param sourceObject\n * @returns\n */\n public convertAsTypedArray(sourceObject: ArrayBufferView)\n {\n return Array.from(sourceObject as any);\n }\n\n /**\n * Performs the conversion of a raw ArrayBuffer to a string.\n */\n public convertAsArrayBuffer(buffer: ArrayBuffer)\n {\n // ArrayBuffer -> 16-bit character codes -> character array -> joined string.\n return Array.from(new Uint16Array(buffer)).map(charCode => String.fromCharCode(charCode)).join(\"\");\n }\n\n /**\n * Performs the conversion of DataView, converting its internal ArrayBuffer to a string and returning that string.\n */\n public convertAsDataView(dataView: DataView)\n {\n return this.convertAsArrayBuffer(dataView.buffer);\n }\n}\n","import { nameof, logError, isSubtypeOf, isValueDefined } from \"./helpers\";\nimport { IndexedObject } from \"./types\";\nimport { JsonObjectMetadata } from \"./metadata\";\n\nexport interface IScopeTypeInfo\n{\n selfConstructor: Function;\n elementConstructor?: Function[];\n keyConstructor?: Function;\n knownTypes: Map;\n}\n\n/**\n * Utility class, converts a simple/untyped javascript object-tree to a typed object-tree.\n * It is used after parsing a JSON-string.\n */\nexport class Deserializer\n{\n private _typeResolver: (sourceObject: Object, knownTypes: Map) => Function|undefined;\n private _nameResolver?: (ctor: Function) => string;\n private _errorHandler: (error: Error) => void;\n\n constructor()\n {\n this._typeResolver = (sourceObject: any, knownTypes: Map) =>\n {\n if (sourceObject.__type) return knownTypes.get(sourceObject.__type);\n };\n\n this._errorHandler = (error) => logError(error);\n }\n\n public setNameResolver(nameResolverCallback: (ctor: Function) => string)\n {\n this._nameResolver = nameResolverCallback;\n }\n\n public setTypeResolver(typeResolverCallback: (sourceObject: Object, knownTypes: Map) => Function)\n {\n if (typeof typeResolverCallback !== \"function\") throw new TypeError(\"'typeResolverCallback' is not a function.\");\n\n this._typeResolver = typeResolverCallback;\n }\n\n public setErrorHandler(errorHandlerCallback: (error: Error) => void)\n {\n if (typeof errorHandlerCallback !== \"function\")\n {\n throw new TypeError(\"'errorHandlerCallback' is not a function.\");\n }\n\n this._errorHandler = errorHandlerCallback;\n }\n\n public convertAsObject(\n sourceObject: IndexedObject,\n sourceObjectTypeInfo: IScopeTypeInfo,\n objectName = \"object\",\n ) {\n if (typeof sourceObject !== \"object\" || sourceObject === null)\n {\n this._errorHandler(new TypeError(`Cannot deserialize ${objectName}: 'sourceObject' must be a defined object.`));\n return undefined;\n }\n\n let expectedSelfType = sourceObjectTypeInfo.selfConstructor;\n let sourceObjectMetadata = JsonObjectMetadata.getFromConstructor(expectedSelfType);\n let knownTypeConstructors = sourceObjectTypeInfo.knownTypes;\n\n if (sourceObjectMetadata)\n {\n // Merge known types received from \"above\" with known types defined on the current type.\n knownTypeConstructors = this._mergeKnownTypes(\n knownTypeConstructors,\n this._createKnownTypesMap(sourceObjectMetadata.knownTypes),\n );\n }\n\n // Check if a type-hint is available from the source object.\n let typeFromTypeHint = this._typeResolver(sourceObject, knownTypeConstructors);\n\n if (typeFromTypeHint)\n {\n // Check if type hint is a valid subtype of the expected source type.\n if (isSubtypeOf(typeFromTypeHint, expectedSelfType))\n {\n // Hell yes.\n expectedSelfType = typeFromTypeHint;\n sourceObjectMetadata = JsonObjectMetadata.getFromConstructor(typeFromTypeHint);\n\n if (sourceObjectMetadata)\n {\n // Also merge new known types from subtype.\n knownTypeConstructors = this._mergeKnownTypes(\n knownTypeConstructors,\n this._createKnownTypesMap(sourceObjectMetadata.knownTypes),\n );\n }\n }\n }\n\n if (sourceObjectMetadata && sourceObjectMetadata.isExplicitlyMarked)\n {\n const sourceMetadata = sourceObjectMetadata;\n // Strong-typed deserialization available, get to it.\n // First deserialize properties into a temporary object.\n const sourceObjectWithDeserializedProperties = {} as IndexedObject;\n\n // Deserialize by expected properties.\n sourceMetadata.dataMembers.forEach((memberMetadata, propKey) =>\n {\n const memberValue = sourceObject[propKey];\n const memberNameForDebug = `${nameof(sourceMetadata.classType)}.${propKey}`;\n\n let revivedValue;\n if (memberMetadata.deserializer) {\n revivedValue = memberMetadata.deserializer(memberValue);\n } else if (memberMetadata.ctor) {\n revivedValue = this.convertSingleValue(\n memberValue,\n {\n selfConstructor: memberMetadata.ctor,\n elementConstructor: memberMetadata.elementType,\n keyConstructor: memberMetadata.keyType,\n knownTypes: knownTypeConstructors\n },\n memberNameForDebug,\n );\n } else {\n throw new TypeError(\n `Cannot deserialize ${memberNameForDebug} thers is`\n + ` no constructor nor deserlization function to use.`,\n );\n }\n\n if (isValueDefined(revivedValue))\n {\n sourceObjectWithDeserializedProperties[memberMetadata.key] = revivedValue;\n }\n else if (memberMetadata.isRequired)\n {\n this._errorHandler(new TypeError(`Missing required member '${memberNameForDebug}'.`));\n }\n });\n\n // Next, instantiate target object.\n let targetObject: IndexedObject;\n\n if (typeof sourceObjectMetadata.initializerCallback === \"function\")\n {\n try\n {\n targetObject = sourceObjectMetadata.initializerCallback(\n sourceObjectWithDeserializedProperties,\n sourceObject,\n );\n\n // Check the validity of user-defined initializer callback.\n if (!targetObject)\n {\n throw new TypeError(\n `Cannot deserialize ${objectName}:`\n + ` 'initializer' function returned undefined/null`\n + `, but '${nameof(sourceObjectMetadata.classType)}' was expected.`,\n );\n }\n else if (!(targetObject instanceof sourceObjectMetadata.classType))\n {\n throw new TypeError(\n `Cannot deserialize ${objectName}:`\n + `'initializer' returned '${nameof(targetObject.constructor)}'`\n + `, but '${nameof(sourceObjectMetadata.classType)}' was expected,`\n + `and '${nameof(targetObject.constructor)}' is not a subtype of`\n + ` '${nameof(sourceObjectMetadata.classType)}'`,\n );\n }\n }\n catch (e)\n {\n this._errorHandler(e);\n return undefined;\n }\n }\n else\n {\n targetObject = this._instantiateType(expectedSelfType);\n }\n\n // Finally, assign deserialized properties to target object.\n Object.assign(targetObject, sourceObjectWithDeserializedProperties);\n\n // Call onDeserialized method (if any).\n if (sourceObjectMetadata.onDeserializedMethodName)\n {\n if (typeof (targetObject.constructor as any)[sourceObjectMetadata.onDeserializedMethodName] === \"function\")\n {\n (targetObject.constructor as any)[sourceObjectMetadata.onDeserializedMethodName]();\n }\n else\n {\n this._errorHandler(new TypeError(\n `onDeserialized callback '${nameof(sourceObjectMetadata.classType)}.${sourceObjectMetadata.onDeserializedMethodName}' is not a method.`\n ));\n }\n }\n\n return targetObject;\n }\n else\n {\n // Untyped deserialization into Object instance.\n let targetObject = {} as IndexedObject;\n\n Object.keys(sourceObject).forEach(sourceKey =>\n {\n targetObject[sourceKey] = this.convertSingleValue(sourceObject[sourceKey], {\n selfConstructor: sourceObject[sourceKey].constructor,\n knownTypes: sourceObjectTypeInfo.knownTypes,\n elementConstructor: sourceObjectTypeInfo.elementConstructor,\n keyConstructor: sourceObjectTypeInfo.keyConstructor\n }, sourceKey);\n });\n\n return targetObject;\n }\n }\n\n public convertSingleValue(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\")\n {\n let expectedSelfType = typeInfo.selfConstructor;\n let srcTypeNameForDebug = sourceObject ? nameof(sourceObject.constructor) : \"undefined\";\n\n if (!isValueDefined(sourceObject))\n {\n return sourceObject;\n }\n else if (this._isDirectlyDeserializableNativeType(expectedSelfType))\n {\n if (sourceObject.constructor === expectedSelfType)\n {\n return sourceObject;\n }\n else\n {\n throw new TypeError(this._makeTypeErrorMessage(nameof(expectedSelfType), sourceObject.constructor, memberName));\n }\n }\n else if (expectedSelfType === Date)\n {\n // Support for Date with ISO 8601 format, or with numeric timestamp (milliseconds elapsed since the Epoch).\n // ISO 8601 spec.: https://www.w3.org/TR/NOTE-datetime\n\n if (typeof sourceObject === \"string\" || (typeof sourceObject === \"number\" && sourceObject > 0))\n return new Date(sourceObject as any);\n else\n this._throwTypeMismatchError(\"Date\", \"an ISO-8601 string\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Float32Array)\n {\n // Deserialize Float32Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Float32Array(sourceObject);\n else\n this._throwTypeMismatchError(\"Float32Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Float64Array)\n {\n // Deserialize Float64Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Float64Array(sourceObject);\n else\n this._throwTypeMismatchError(\"Float64Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint8Array)\n {\n // Deserialize Uint8Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint8Array(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint8Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint8ClampedArray)\n {\n // Deserialize Uint8Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint8ClampedArray(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint8ClampedArray\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint16Array)\n {\n // Deserialize Uint16Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint16Array(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint16Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint32Array)\n {\n // Deserialize Uint32Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint32Array(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint32Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === ArrayBuffer)\n {\n if (typeof sourceObject === \"string\")\n return this._stringToArrayBuffer(sourceObject);\n else\n this._throwTypeMismatchError(\"ArrayBuffer\", \"a string source\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === DataView)\n {\n if (typeof sourceObject === \"string\")\n return this._stringToDataView(sourceObject);\n else\n this._throwTypeMismatchError(\"DataView\", \"a string source\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Array)\n {\n if (sourceObject instanceof Array)\n return this.convertAsArray(sourceObject, typeInfo, memberName);\n else\n throw new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName));\n }\n else if (expectedSelfType === Set)\n {\n if (sourceObject instanceof Array)\n return this.convertAsSet(sourceObject, typeInfo, memberName);\n else\n this._throwTypeMismatchError(\"Set\", \"Array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Map)\n {\n if (sourceObject instanceof Array)\n return this.convertAsMap(sourceObject, typeInfo, memberName);\n else\n this._throwTypeMismatchError(\"Map\", \"a source array of key-value-pair objects\", srcTypeNameForDebug, memberName);\n }\n else if (sourceObject && typeof sourceObject === \"object\")\n {\n return this.convertAsObject(sourceObject, typeInfo, memberName);\n }\n }\n\n public convertAsArray(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\"): any[]\n {\n if (!(sourceObject instanceof Array))\n {\n this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)));\n return [];\n }\n\n if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Array: missing constructor reference of Array elements.`));\n return [];\n }\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.elementConstructor[0],\n elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [],\n knownTypes: typeInfo.knownTypes\n };\n\n return sourceObject.map(element =>\n {\n // If an array element fails to deserialize, substitute with undefined. This is so that the original ordering is not interrupted by faulty\n // entries, as an Array is ordered.\n try\n {\n return this.convertSingleValue(element, elementTypeInfo);\n }\n catch (e)\n {\n this._errorHandler(e);\n\n // Keep filling the array here with undefined to keep original ordering.\n // Note: this is just aesthetics, not returning anything produces the same result.\n return undefined;\n }\n });\n }\n\n public convertAsSet(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\")\n {\n if (!(sourceObject instanceof Array))\n {\n this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)));\n return new Set();\n }\n\n if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Set: missing constructor reference of Set elements.`));\n return new Set();\n }\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.elementConstructor[0],\n elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [],\n knownTypes: typeInfo.knownTypes\n };\n let resultSet = new Set();\n\n sourceObject.forEach((element, i) =>\n {\n try\n {\n resultSet.add(this.convertSingleValue(element, elementTypeInfo, memberName + `[${i}]`));\n }\n catch (e)\n {\n // Faulty entries are skipped, because a Set is not ordered, and skipping an entry does not affect others.\n this._errorHandler(e);\n }\n });\n\n return resultSet;\n }\n\n public convertAsMap(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\")\n {\n if (!(sourceObject instanceof Array))\n this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)));\n\n if (!typeInfo.keyConstructor)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Map: missing key constructor.`));\n return new Map();\n }\n\n if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Map: missing value constructor.`));\n return new Map();\n }\n\n let keyTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.keyConstructor,\n knownTypes: typeInfo.knownTypes\n };\n\n let valueTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.elementConstructor[0],\n elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [],\n knownTypes: typeInfo.knownTypes\n };\n\n let resultMap = new Map();\n\n sourceObject.forEach((element: any) =>\n {\n try\n {\n let key = this.convertSingleValue(element.key, keyTypeInfo);\n\n // Undefined/null keys not supported, skip if so.\n if (isValueDefined(key))\n {\n resultMap.set(key, this.convertSingleValue(\n element.value, valueTypeInfo, `${memberName}[${key}]`,\n ));\n }\n }\n catch (e)\n {\n // Faulty entries are skipped, because a Map is not ordered,\n // and skipping an entry does not affect others.\n this._errorHandler(e);\n }\n });\n\n return resultMap;\n }\n\n private _throwTypeMismatchError(\n targetType: string,\n expectedSourceType: string,\n actualSourceType: string,\n memberName: string = \"object\",\n ) {\n throw new TypeError(\n `Could not deserialize ${memberName} as ${targetType}:`\n + ` expected ${expectedSourceType}, got ${actualSourceType}.`,\n );\n }\n\n private _makeTypeErrorMessage(expectedType: Function | string, actualType: Function | string, memberName = \"object\")\n {\n let expectedTypeName = (typeof expectedType === \"function\") ? nameof(expectedType) : expectedType;\n let actualTypeName = (typeof actualType === \"function\") ? nameof(actualType) : actualType;\n\n return `Could not deserialize ${memberName}: expected '${expectedTypeName}', got '${actualTypeName}'.`;\n }\n\n private _instantiateType(ctor: any)\n {\n return new ctor();\n }\n\n private _mergeKnownTypes(...knownTypeMaps: Array>)\n {\n let result = new Map();\n\n knownTypeMaps.forEach(knownTypes =>\n {\n knownTypes.forEach((ctor, name) =>\n {\n if (this._nameResolver)\n {\n result.set(this._nameResolver(ctor), ctor);\n }\n else\n {\n result.set(name, ctor);\n }\n });\n });\n\n return result;\n }\n\n private _createKnownTypesMap(knowTypes: Set)\n {\n const map = new Map();\n\n knowTypes.forEach(ctor =>\n {\n if (this._nameResolver)\n {\n map.set(this._nameResolver(ctor), ctor);\n }\n else\n {\n const knownTypeMeta = JsonObjectMetadata.getFromConstructor(ctor);\n const name = knownTypeMeta && knownTypeMeta.isExplicitlyMarked && knownTypeMeta.name\n ? knownTypeMeta.name\n : ctor.name;\n map.set(name, ctor);\n }\n });\n\n return map;\n }\n\n private _isDirectlyDeserializableNativeType(ctor: any)\n {\n return ~([Number, String, Boolean].indexOf(ctor));\n }\n\n public convertNativeObject(sourceObject: any)\n {\n return sourceObject;\n }\n\n private _stringToArrayBuffer(str: string)\n {\n let buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char\n let bufView = new Uint16Array(buf);\n\n for (let i = 0, strLen = str.length; i < strLen; i++)\n {\n bufView[i] = str.charCodeAt(i);\n }\n\n return buf;\n }\n\n private _stringToDataView(str: string)\n {\n return new DataView(this._stringToArrayBuffer(str));\n }\n}\n","import { Constructor } from \"./typedjson/types\";\nimport { Serializer } from \"./typedjson/serializer\";\nimport { Deserializer } from \"./typedjson/deserializer\";\nimport { JsonObjectMetadata } from \"./typedjson/metadata\";\nimport { logError, logWarning, nameof, parseToJSObject } from \"./typedjson/helpers\";\n\nexport type JsonTypes = Object|boolean|string|number|null|undefined;\n\nexport interface ITypedJSONSettings\n{\n /**\n * Sets the handler callback to invoke on errors during serializing and deserializing.\n * Re-throwing errors in this function will halt serialization/deserialization.\n * The default behavior is to log errors to the console.\n */\n errorHandler?: (e: Error) => void;\n\n /**\n * Sets a callback that determines the constructor of the correct sub-type of polymorphic\n * objects while deserializing.\n * The default behavior is to read the type-name from the '__type' property of 'sourceObject',\n * and look it up in 'knownTypes'.\n * The constructor of the sub-type should be returned.\n */\n typeResolver?: (sourceObject: Object, knownTypes: Map) => Function;\n\n nameResolver?: (ctor: Function) => string;\n\n /**\n * Sets a callback that writes type-hints to serialized objects.\n * The default behavior is to write the type-name to the '__type' property, if a derived type\n * is present in place of a base type.\n */\n typeHintEmitter?:\n (targetObject: Object, sourceObject: Object, expectedSourceType: Function) => void;\n\n /**\n * Sets the amount of indentation to use in produced JSON strings.\n * Default value is 0, or no indentation.\n */\n indent?: number;\n\n replacer?: (key: string, value: any) => any;\n\n knownTypes?: Array>;\n}\n\nexport class TypedJSON\n{\n //#region Static\n public static parse(\n object: any, rootType: Constructor, settings?: ITypedJSONSettings,\n ): T|undefined {\n return new TypedJSON(rootType, settings).parse(object);\n }\n\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings?: ITypedJSONSettings,\n dimensions?: 1\n ): T[];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 2\n ): T[][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 3\n ): T[][][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 4\n ): T[][][][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 5\n ): T[][][][][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings?: ITypedJSONSettings,\n dimensions?: number\n ): any[] {\n return new TypedJSON(elementType, settings).parseAsArray(object, dimensions as any);\n }\n\n public static parseAsSet(\n object: any, elementType: Constructor, settings?: ITypedJSONSettings,\n ): Set {\n return new TypedJSON(elementType, settings).parseAsSet(object);\n }\n\n public static parseAsMap(\n object: any,\n keyType: Constructor,\n valueType: Constructor,\n settings?: ITypedJSONSettings,\n ): Map {\n return new TypedJSON(valueType, settings).parseAsMap(object, keyType);\n }\n\n public static toPlainJson(\n object: T, rootType: Constructor, settings?: ITypedJSONSettings,\n ): JsonTypes {\n return new TypedJSON(rootType, settings).toPlainJson(object);\n }\n\n public static toPlainArray(\n object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings,\n ): Object[];\n public static toPlainArray(\n object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings,\n ): Object[][];\n public static toPlainArray(\n object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings,\n ): Object[][][];\n public static toPlainArray(\n object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings,\n ): Object[][][][];\n public static toPlainArray(\n object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings,\n ): Object[][][][][];\n public static toPlainArray(\n object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings,\n ): any[];\n public static toPlainArray(\n object: any[], elementType: Constructor, dimensions?: any, settings?: ITypedJSONSettings,\n ): any[] {\n return new TypedJSON(elementType, settings).toPlainArray(object, dimensions);\n }\n\n public static toPlainSet(\n object: Set, elementType: Constructor, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(elementType, settings).stringifyAsSet(object);\n }\n\n public static toPlainMap(\n object: Map,\n keyCtor: Constructor,\n valueCtor: Constructor,\n settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(valueCtor, settings).stringifyAsMap(object, keyCtor);\n }\n\n public static stringify(\n object: T, rootType: Constructor, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(rootType, settings).stringify(object);\n }\n\n public static stringifyAsArray(\n object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: any[], elementType: Constructor, dimensions?: any, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(elementType, settings).stringifyAsArray(object, dimensions);\n }\n\n public static stringifyAsSet(\n object: Set, elementType: Constructor, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(elementType, settings).stringifyAsSet(object);\n }\n\n public static stringifyAsMap(\n object: Map,\n keyCtor: Constructor,\n valueCtor: Constructor,\n settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(valueCtor, settings).stringifyAsMap(object, keyCtor);\n }\n\n private static _globalConfig: ITypedJSONSettings;\n\n public static setGlobalConfig(config: ITypedJSONSettings)\n {\n if (this._globalConfig)\n {\n Object.assign(this._globalConfig, config);\n }\n else\n {\n this._globalConfig = config;\n }\n }\n\n //#endregion\n\n private serializer: Serializer = new Serializer();\n private deserializer: Deserializer = new Deserializer();\n private globalKnownTypes: Array> = [];\n private indent: number = 0;\n private rootConstructor: Constructor;\n private errorHandler: (e: Error) => void;\n private nameResolver: (ctor: Function) => string;\n private replacer?: (key: string, value: any) => any;\n\n /**\n * Creates a new TypedJSON instance to serialize (stringify) and deserialize (parse) object\n * instances of the specified root class type.\n * @param rootType The constructor of the root class type.\n * @param settings Additional configuration settings.\n */\n constructor(rootConstructor: Constructor, settings?: ITypedJSONSettings)\n {\n let rootMetadata = JsonObjectMetadata.getFromConstructor(rootConstructor);\n\n if (!rootMetadata || (!rootMetadata.isExplicitlyMarked && !rootMetadata.isHandledWithoutAnnotation))\n {\n throw new TypeError(\"The TypedJSON root data type must have the @jsonObject decorator used.\");\n }\n\n this.nameResolver = (ctor) => nameof(ctor);\n this.rootConstructor = rootConstructor;\n this.errorHandler = (error) => logError(error);\n\n if (settings)\n {\n this.config(settings);\n }\n else if (TypedJSON._globalConfig)\n {\n this.config({});\n }\n }\n\n /**\n * Configures TypedJSON through a settings object.\n * @param settings The configuration settings object.\n */\n public config(settings: ITypedJSONSettings)\n {\n if (TypedJSON._globalConfig)\n {\n settings = {\n ...TypedJSON._globalConfig,\n ...settings\n };\n\n if (settings.knownTypes && TypedJSON._globalConfig.knownTypes)\n {\n // Merge known-types (also de-duplicate them, so Array -> Set -> Array).\n settings.knownTypes = Array.from(new Set(\n settings.knownTypes.concat(TypedJSON._globalConfig.knownTypes),\n ));\n }\n }\n\n if (settings.errorHandler)\n {\n this.errorHandler = settings.errorHandler;\n this.deserializer.setErrorHandler(settings.errorHandler);\n this.serializer.setErrorHandler(settings.errorHandler);\n }\n\n if (settings.replacer) this.replacer = settings.replacer;\n if (settings.typeResolver) this.deserializer.setTypeResolver(settings.typeResolver);\n if (settings.typeHintEmitter) this.serializer.setTypeHintEmitter(settings.typeHintEmitter);\n if (settings.indent) this.indent = settings.indent;\n\n if (settings.nameResolver)\n {\n this.nameResolver = settings.nameResolver;\n this.deserializer.setNameResolver(settings.nameResolver);\n // this.serializer.set\n }\n\n if (settings.knownTypes)\n {\n // Type-check knownTypes elements to recognize errors in advance.\n settings.knownTypes.forEach((knownType, i) =>\n {\n // tslint:disable-next-line:no-null-keyword\n if (typeof knownType === \"undefined\" || knownType === null)\n {\n logWarning(\n `TypedJSON.config: 'knownTypes' contains an undefined/null value (element ${i}).`);\n }\n });\n\n this.globalKnownTypes = settings.knownTypes;\n }\n }\n\n /**\n * Converts a JSON string to the root class type.\n * @param object The JSON to parse and convert.\n * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown).\n * @returns Deserialized T or undefined if there were errors.\n */\n public parse(object: any): T|undefined\n {\n const json = parseToJSObject(object, this.rootConstructor);\n\n let rootMetadata = JsonObjectMetadata.getFromConstructor(this.rootConstructor);\n let result: T|undefined;\n let knownTypes = new Map();\n\n this.globalKnownTypes.filter(ktc => ktc).forEach(knownTypeCtor =>\n {\n knownTypes.set(this.nameResolver(knownTypeCtor), knownTypeCtor);\n });\n\n if (rootMetadata)\n {\n rootMetadata.knownTypes.forEach(knownTypeCtor =>\n {\n knownTypes.set(this.nameResolver(knownTypeCtor), knownTypeCtor);\n });\n }\n\n try\n {\n result = this.deserializer.convertSingleValue(json, {\n selfConstructor: this.rootConstructor,\n knownTypes: knownTypes,\n }) as T;\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n\n return result;\n }\n\n public parseAsArray(object: any, dimensions?: 1): T[];\n public parseAsArray(object: any, dimensions: 2): T[][];\n public parseAsArray(object: any, dimensions: 3): T[][][];\n public parseAsArray(object: any, dimensions: 4): T[][][][];\n public parseAsArray(object: any, dimensions: 5): T[][][][][];\n public parseAsArray(object: any, dimensions: number): any[];\n public parseAsArray(object: any, dimensions: number = 1): any[]\n {\n const json = parseToJSObject(object, Array);\n if (json instanceof Array)\n {\n return this.deserializer.convertAsArray(json, {\n selfConstructor: Array,\n elementConstructor: new Array(dimensions - 1)\n .fill(Array)\n .concat(this.rootConstructor),\n knownTypes: this._mapKnownTypes(this.globalKnownTypes),\n });\n }\n else\n {\n this.errorHandler(new TypeError(`Expected 'json' to define an Array`\n + `, but got ${typeof json}.`));\n }\n\n return [];\n }\n\n public parseAsSet(object: any): Set\n {\n const json = parseToJSObject(object, Set);\n // A Set is serialized as T[].\n if (json instanceof Array)\n {\n return this.deserializer.convertAsSet(json, {\n selfConstructor: Array,\n elementConstructor: [this.rootConstructor],\n knownTypes: this._mapKnownTypes(this.globalKnownTypes)\n });\n }\n else\n {\n this.errorHandler(new TypeError(`Expected 'json' to define a Set (using an Array)`\n + `, but got ${typeof json}.`,\n ));\n }\n\n return new Set();\n }\n\n public parseAsMap(object: any, keyConstructor: Constructor): Map\n {\n const json = parseToJSObject(object, Map);\n // A Set is serialized as T[].\n if (json instanceof Array)\n {\n return this.deserializer.convertAsMap(json, {\n selfConstructor: Array,\n elementConstructor: [this.rootConstructor],\n knownTypes: this._mapKnownTypes(this.globalKnownTypes),\n keyConstructor: keyConstructor\n });\n }\n else\n {\n this.errorHandler(new TypeError(`Expected 'json' to define a Set (using an Array)`\n + `, but got ${typeof json}.`,\n ));\n }\n\n return new Map();\n }\n\n /**\n * Converts an instance of the specified class type to a plain JSON object.\n * @param object The instance to convert to a JSON string.\n * @returns Serialized object or undefined if an error has occured.\n */\n public toPlainJson(object: T): JsonTypes\n {\n try\n {\n return this.serializer.convertSingleValue(object, {\n selfType: this.rootConstructor\n });\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n public toPlainArray(object: T[], dimensions?: 1): Object[];\n public toPlainArray(object: T[][], dimensions: 2): Object[][];\n public toPlainArray(object: T[][][], dimensions: 3): Object[][][];\n public toPlainArray(object: T[][][][], dimensions: 4): Object[][][][];\n public toPlainArray(object: T[][][][][], dimensions: 5): Object[][][][][];\n public toPlainArray(object: any[], dimensions: 1|2|3|4|5 = 1): Object[]|undefined\n {\n try\n {\n const elementConstructorArray =\n new Array(dimensions - 1).fill(Array).concat(this.rootConstructor);\n return this.serializer.convertAsArray(object, elementConstructorArray);\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n public toPlainSet(object: Set): Object[]|undefined\n {\n try\n {\n return this.serializer.convertAsSet(object, this.rootConstructor);\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n public toPlainMap(object: Map, keyConstructor: Constructor): { key: any, value: any }[]|undefined\n {\n try\n {\n return this.serializer.convertAsMap(object, keyConstructor, this.rootConstructor);\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n /**\n * Converts an instance of the specified class type to a JSON string.\n * @param object The instance to convert to a JSON string.\n * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown).\n * @returns String with the serialized object or an empty string if an error has occured, but\n * the errorHandler did not throw.\n */\n public stringify(object: T): string\n {\n const result = this.toPlainJson(object);\n if (result === undefined) {\n return '';\n }\n return JSON.stringify(result, this.replacer, this.indent);\n }\n\n public stringifyAsArray(object: T[], dimensions?: 1): string;\n public stringifyAsArray(object: T[][], dimensions: 2): string;\n public stringifyAsArray(object: T[][][], dimensions: 3): string;\n public stringifyAsArray(object: T[][][][], dimensions: 4): string;\n public stringifyAsArray(object: T[][][][][], dimensions: 5): string;\n public stringifyAsArray(object: any[], dimensions: any): string\n {\n return JSON.stringify(this.toPlainArray(object, dimensions), this.replacer, this.indent);\n }\n\n public stringifyAsSet(object: Set): string\n {\n return JSON.stringify(this.toPlainSet(object), this.replacer, this.indent);\n }\n\n public stringifyAsMap(object: Map, keyConstructor: Constructor): string\n {\n return JSON.stringify(this.toPlainMap(object, keyConstructor), this.replacer, this.indent);\n }\n\n private _mapKnownTypes(constructors: Array>)\n {\n let map = new Map>();\n\n constructors.filter(ctor => ctor).forEach(ctor => map.set(this.nameResolver(ctor), ctor));\n\n return map;\n }\n}\n","import { Constructor, ParameterlessConstructor } from \"./types\";\nimport { METADATA_FIELD_KEY } from \"./helpers\";\nimport { JsonObjectMetadata } from \"./metadata\";\n\nexport interface IJsonObjectOptionsBase\n{\n /**\n * An array of known types to recognize when encountering type-hints,\n * or the name of a static method used for determining known types.\n */\n knownTypes?: Function[] | string;\n\n /**\n * The name of a static or instance method to call when deserialization\n * of the object is completed.\n */\n onDeserialized?: string;\n\n /**\n * The name used to differentiate between different polymorphic types.\n */\n name?: string;\n}\n\nexport interface IJsonObjectOptionsWithInitializer extends IJsonObjectOptionsBase\n{\n /**\n * The name of a static method to call before deserializing and initializing the object, accepting two arguments: (1) sourceObject, an 'Object' instance\n * with all properties already deserialized, and (2) rawSourceObject, a raw 'Object' instance representation of the current object in the serialized JSON\n * (i.e. without deserialized properties).\n */\n initializer: (sourceObject: T, rawSourceObject: T) => T;\n}\n\nexport interface IJsonObjectOptions extends IJsonObjectOptionsBase\n{\n /**\n * The name of a static method to call before deserializing and initializing the object, accepting two arguments: (1) sourceObject, an 'Object' instance\n * with all properties already deserialized, and (2) rawSourceObject, a raw 'Object' instance representation of the current object in the serialized JSON\n * (i.e. without deserialized properties).\n */\n initializer?: (sourceObject: T, rawSourceObject: T) => T;\n}\n\n/**\n * Marks that a class with a parameterized constructor is serializable using TypedJSON, with additional settings. The 'initializer' setting must be specified.\n * @param options Configuration settings.\n */\nexport function jsonObject(options?: IJsonObjectOptionsWithInitializer): (target: Constructor) => void;\n\n/**\n * Marks that a class is serializable using TypedJSON, with additional settings.\n * @param options Configuration settings.\n */\nexport function jsonObject(options?: IJsonObjectOptions): (target: ParameterlessConstructor) => void;\n\n/**\n * Marks that a class with a parameterless constructor is serializable using TypedJSON.\n */\nexport function jsonObject(target: ParameterlessConstructor): void;\n\nexport function jsonObject(optionsOrTarget?: IJsonObjectOptions | Constructor\n): ((target: Constructor) => void) | void {\n let options: IJsonObjectOptions;\n\n if (typeof optionsOrTarget === \"function\")\n {\n // jsonObject is being used as a decorator, directly.\n options = {};\n }\n else\n {\n // jsonObject is being used as a decorator factory.\n options = optionsOrTarget || {};\n }\n\n function decorator(\n target: Function\n ): void {\n let objectMetadata: JsonObjectMetadata;\n\n // Create or obtain JsonObjectMetadata object.\n if (!target.prototype.hasOwnProperty(METADATA_FIELD_KEY))\n {\n // Target has no JsonObjectMetadata associated with it yet, create it now.\n objectMetadata = new JsonObjectMetadata(target);\n\n // Inherit json members and known types from parent @jsonObject (if any).\n const parentMetadata: JsonObjectMetadata = target.prototype[METADATA_FIELD_KEY];\n if (parentMetadata)\n {\n parentMetadata.dataMembers\n .forEach((memberMetadata, propKey) =>\n objectMetadata.dataMembers.set(propKey, memberMetadata));\n parentMetadata.knownTypes\n .forEach((knownType) => objectMetadata.knownTypes.add(knownType));\n }\n\n Object.defineProperty(target.prototype, METADATA_FIELD_KEY, {\n enumerable: false,\n configurable: false,\n writable: false,\n value: objectMetadata\n });\n }\n else\n {\n // Target already has JsonObjectMetadata associated with it.\n objectMetadata = target.prototype[METADATA_FIELD_KEY];\n objectMetadata.classType = target;\n }\n\n // Fill JsonObjectMetadata.\n objectMetadata.isExplicitlyMarked = true;\n objectMetadata.onDeserializedMethodName = options.onDeserialized;\n // T extend Object so it is fine\n objectMetadata.initializerCallback = options.initializer as any;\n if (options.name)\n {\n objectMetadata.name = options.name;\n }\n\n // Obtain known-types.\n if (typeof options.knownTypes === \"string\")\n {\n objectMetadata.knownTypeMethodName = options.knownTypes;\n }\n else if (options.knownTypes instanceof Array)\n {\n options.knownTypes\n .filter(knownType => !!knownType)\n .forEach(knownType => objectMetadata.knownTypes.add(knownType));\n }\n }\n\n if (typeof optionsOrTarget === \"function\")\n {\n // jsonObject is being used as a decorator, directly.\n decorator(optionsOrTarget);\n }\n else\n {\n // jsonObject is being used as a decorator factory.\n return decorator;\n }\n}\n","import {\n nameof, logError, isReflectMetadataSupported, isValueDefined, logWarning, isSubtypeOf\n} from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonMemberOptions\n{\n /**\n * Sets the constructor of the property.\n * Optional with ReflectDecorators.\n */\n constructor?: Function;\n\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, a default value is emitted if the property is uninitialized/undefined. */\n emitDefaultValue?: boolean;\n\n /** When set, the key on the JSON that should be used instead of the class property name. */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that a property is part of the object when serializing, with additional options.\n * Omitting the 'constructor' option requires ReflectDecorators and that the property type is always explicitly declared.\n * @param options Additional options.\n */\nexport function jsonMember(options: IJsonMemberOptions): PropertyDecorator;\n\n/**\n * Specifies that a property is part of the object when serializing.\n * This call signature requires ReflectDecorators and that the property type is always explicitly declared.\n */\nexport function jsonMember(target: Object, propertyKey: string | symbol): void;\n\nexport function jsonMember(optionsOrTarget?: IJsonMemberOptions | Object, propKey?: string | symbol): PropertyDecorator | void\n{\n if (optionsOrTarget instanceof Object && (typeof propKey === \"string\" || typeof propKey === \"symbol\"))\n {\n const target = optionsOrTarget as Object;\n // For error messages.\n const decoratorName = `@jsonMember on ${nameof(target.constructor)}.${String(propKey)}`;\n\n // jsonMember used directly, no additional information directly available besides target and propKey.\n // Obtain property constructor through ReflectDecorators.\n if (isReflectMetadataSupported)\n {\n const reflectPropCtor = Reflect.getMetadata(\"design:type\", target, propKey) as Function;\n\n if (!reflectPropCtor)\n {\n logError(`${decoratorName}: could not resolve detected property constructor at runtime.`);\n return;\n }\n\n if (isSpecialPropertyType(decoratorName, reflectPropCtor))\n {\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: reflectPropCtor,\n key: propKey.toString(),\n name: propKey.toString(),\n });\n }\n else\n {\n logError(`${decoratorName}: ReflectDecorators is required if no 'constructor' option is specified.`);\n return;\n }\n }\n else\n {\n // jsonMember used as a decorator factory.\n return (target: Object, _propKey: string | symbol) =>\n {\n let options: IJsonMemberOptions = optionsOrTarget || {};\n let propCtor: Function|undefined;\n let decoratorName = `@jsonMember on ${nameof(target.constructor)}.${String(_propKey)}`; // For error messages.\n\n if (options.hasOwnProperty(\"constructor\"))\n {\n if (!isValueDefined(options.constructor))\n {\n logError(`${decoratorName}: cannot resolve specified property constructor at runtime.`);\n return;\n }\n\n // Property constructor has been specified. Use ReflectDecorators (if available) to check whether that constructor is correct. Warn if not.\n if (isReflectMetadataSupported && !isSubtypeOf(options.constructor, Reflect.getMetadata(\"design:type\", target, _propKey)))\n {\n logWarning(`${decoratorName}: detected property type does not match 'constructor' option.`);\n }\n\n propCtor = options.constructor;\n }\n else\n {\n // Use ReflectDecorators to obtain property constructor.\n if (isReflectMetadataSupported)\n {\n propCtor = Reflect.getMetadata(\"design:type\", target, _propKey) as Function;\n\n if (!propCtor)\n {\n logError(`${decoratorName}: cannot resolve detected property constructor at runtime.`);\n return;\n }\n }\n else if (!options.deserializer)\n {\n logError(`${decoratorName}: ReflectDecorators is required if no 'constructor' option is specified.`);\n return;\n }\n }\n\n if (isSpecialPropertyType(decoratorName, propCtor))\n {\n return;\n }\n\n injectMetadataInformation(target, _propKey, {\n ctor: propCtor,\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: _propKey.toString(),\n name: options.name || _propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n }\n}\n\nfunction isSpecialPropertyType(decoratorName: string, propCtor?: Function)\n{\n if (propCtor === Array)\n {\n logError(`${decoratorName}: property is an Array. Use the jsonArrayMember decorator to`\n + ` serialize this property.`);\n return true;\n }\n\n if (propCtor === Set)\n {\n logError(`${decoratorName}: property is a Set. Use the jsonSetMember decorator to`\n + ` serialize this property.`);\n return true;\n }\n\n if (propCtor === Map)\n {\n logError(`${decoratorName}: property is a Map. Use the jsonMapMember decorator to`\n + ` serialize this property.`);\n return true;\n }\n\n return false;\n}\n","import { nameof, logError, isReflectMetadataSupported } from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonArrayMemberOptions\n{\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, an empty array is emitted if the property is undefined/uninitialized. */\n emitDefaultValue?: boolean;\n\n /** Sets array dimensions (e.g. 1 for 'number[]' or 2 for 'number[][]'). Defaults to 1. */\n dimensions?: number;\n\n /** When set, the key on the JSON that should be used instead of the class property name */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that a property, of type array, is part of an object when serializing.\n * @param elementConstructor Constructor of array elements (e.g. 'Number' for 'number[]', or 'Date' for 'Date[]').\n * @param options Additional options.\n */\nexport function jsonArrayMember(elementConstructor: Function, options: IJsonArrayMemberOptions = {})\n{\n return (target: Object, propKey: string | symbol) =>\n {\n let decoratorName = `@jsonArrayMember on ${nameof(target.constructor)}.${String(propKey)}`; // For error messages.\n\n if (typeof elementConstructor !== \"function\")\n {\n logError(`${decoratorName}: could not resolve constructor of array elements at runtime.`);\n return;\n }\n\n const dimensions = options.dimensions === undefined ? 1 : options.dimensions;\n if (!isNaN(dimensions) && dimensions < 1)\n {\n logError(`${decoratorName}: 'dimensions' option must be at least 1.`);\n return;\n }\n\n // If ReflectDecorators is available, use it to check whether 'jsonArrayMember' has been used on an array.\n if (isReflectMetadataSupported && Reflect.getMetadata(\"design:type\", target, propKey) !== Array)\n {\n logError(`${decoratorName}: property is not an Array.`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Array,\n elementType: createArrayElementType(elementConstructor, dimensions),\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: propKey.toString(),\n name: options.name || propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n}\n\nfunction createArrayElementType(elementCtor: Function, dimensions: number) {\n const elementTypes = new Array(dimensions).fill(Array, 0, -1);\n elementTypes[dimensions-1] = elementCtor;\n return elementTypes;\n}\n","import { nameof } from \"./helpers\";\nimport { IJsonMemberOptions } from \"./json-member\";\nimport { JsonMemberMetadata, JsonObjectMetadata, injectMetadataInformation } from \"./metadata\";\nimport * as Helpers from \"./helpers\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonSetMemberOptions\n{\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, a default value is emitted for each uninitialized json member. */\n emitDefaultValue?: boolean;\n\n /** When set, the key on the JSON that should be used instead of the class property name */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that the property is part of the object when serializing.\n * Use this decorator on properties of type Set.\n * @param elementConstructor Constructor of set elements (e.g. 'Number' for Set or 'Date' for Set).\n * @param options Additional options.\n */\nexport function jsonSetMember(elementConstructor: Function, options: IJsonSetMemberOptions = {})\n{\n return (target: Object, propKey: string | symbol) =>\n {\n var decoratorName = `@jsonSetMember on ${nameof(target.constructor)}.${String(propKey)}`; // For error messages.\n\n if (typeof elementConstructor !== \"function\")\n {\n Helpers.logError(`${decoratorName}: could not resolve constructor of set elements at runtime.`);\n return;\n }\n\n // If ReflectDecorators is available, use it to check whether 'jsonSetMember' has been used on a set. Warn if not.\n if (Helpers.isReflectMetadataSupported && Reflect.getMetadata(\"design:type\", target, propKey) !== Set)\n {\n Helpers.logError(`${decoratorName}: property is not a Set.`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Set,\n elementType: [elementConstructor],\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: propKey.toString(),\n name: options.name || propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n}\n","import { nameof, logError, isReflectMetadataSupported } from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonMapMemberOptions\n{\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, a default value is emitted for each uninitialized json member. */\n emitDefaultValue?: boolean;\n\n /** When set, the key on the JSON that should be used instead of the class property name */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that the property is part of the object when serializing.\n * Use this decorator on properties of type Map.\n * @param keyConstructor Constructor of map keys (e.g. 'Number' for 'Map').\n * @param valueConstructor Constructor of map values (e.g. 'Date' for 'Map').\n * @param options Additional options.\n */\nexport function jsonMapMember(keyConstructor: Function, valueConstructor: Function, options: IJsonMapMemberOptions = {})\n{\n return (target: Object, propKey: string | symbol) =>\n {\n let decoratorName = `@jsonMapMember on ${nameof(target.constructor)}.${String(propKey)}`; // For error messages.\n\n if (typeof keyConstructor !== \"function\")\n {\n logError(`${decoratorName}: could not resolve constructor of map keys at runtime.`);\n return;\n }\n\n if (typeof valueConstructor !== \"function\")\n {\n logError(`${decoratorName}: could not resolve constructor of map values at runtime.`);\n return;\n }\n\n // If ReflectDecorators is available, use it to check whether 'jsonMapMember' has been used on a map. Warn if not.\n if (isReflectMetadataSupported && Reflect.getMetadata(\"design:type\", target, propKey) !== Map)\n {\n logError(`${decoratorName}: property is not a Map.`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Map,\n elementType: [valueConstructor],\n keyType: keyConstructor,\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: propKey.toString(),\n name: options.name || propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n}\n","export { TypedJSON, ITypedJSONSettings, JsonTypes } from \"./parser\";\nexport { jsonObject } from \"./typedjson/json-object\";\nexport { jsonMember } from \"./typedjson/json-member\";\nexport { jsonArrayMember } from \"./typedjson/json-array-member\";\nexport { jsonSetMember } from \"./typedjson/json-set-member\";\nexport { jsonMapMember } from \"./typedjson/json-map-member\";\n"],"sourceRoot":""} \ No newline at end of file diff --git a/js/typedjson.min.js b/js/typedjson.min.js index 979374f..2adbbd5 100644 --- a/js/typedjson.min.js +++ b/js/typedjson.min.js @@ -1,3 +1,3 @@ -// [typedjson] Version: 1.2.3 - 2019-03-13 - !function(e,r){"object"==typeof exports&&"object"==typeof module?module.exports=r():"function"==typeof define&&define.amd?define("typedjson",[],r):"object"==typeof exports?exports.typedjson=r():e.typedjson=r()}("undefined"!=typeof self?self:this,function(){return function(t){var n={};function o(e){if(n[e])return n[e].exports;var r=n[e]={i:e,l:!1,exports:{}};return t[e].call(r.exports,r,r.exports,o),r.l=!0,r.exports}return o.m=t,o.c=n,o.d=function(e,r,t){o.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(r,e){if(1&e&&(r=o(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var t=Object.create(null);if(o.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var n in r)o.d(t,n,function(e){return r[e]}.bind(null,n));return t},o.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(r,"a",r),r},o.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},o.p="",o(o.s=0)}([function(e,r,t){"use strict";t.r(r);var s="__typedJsonJsonObjectMetadataInformation__";function i(e){return!!~[Date,Number,String,Boolean].indexOf(e)}function a(e){return!!~[Float32Array,Float64Array,Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array].indexOf(e)}function c(e,r){return"string"!=typeof e||(t=e,o=(n=r)===String||n===ArrayBuffer||n===DataView,i=2<=t.length&&'"'===t[0]&&'"'===t[t.length-1],s=/^\d+$/.test(t.trim()),o&&!i||!i&&!s&&n===Date)?e:JSON.parse(e);var t,n,o,i,s}function f(e,r){return e===r||e.prototype instanceof r}function u(e){for(var r=[],t=1;t(type: { new (): T }): T|undefined\n{\n switch (type as any)\n {\n case Number:\n return 0 as any;\n\n case String:\n return \"\" as any;\n\n case Boolean:\n return false as any;\n\n case Array:\n return [] as any;\n\n default:\n return undefined;\n }\n}\n\n/**\n * Determines whether the specified type is a type that can be passed on \"as-is\" into `JSON.stringify`.\n * Values of these types don't need special conversion.\n * @param type The constructor of the type (wrapper constructor for primitive types, e.g. `Number` for `number`).\n */\nexport function isDirectlySerializableNativeType(type: Function): boolean\n{\n return !!(~[Date, Number, String, Boolean].indexOf(type as any));\n}\n\nexport function isTypeTypedArray(type: Function): boolean\n{\n return !!(~[Float32Array, Float64Array, Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array]\n .indexOf(type as any));\n}\n\nexport function isPrimitiveValue(obj: any): boolean\n{\n switch (typeof obj)\n {\n case \"string\":\n case \"number\":\n case \"boolean\":\n return true;\n default:\n return (obj instanceof String || obj instanceof Number || obj instanceof Boolean);\n }\n}\n\nexport function isObject(value: any): value is Object\n{\n return typeof value === \"object\";\n}\n\nfunction shouldOmitParseString(jsonStr: string, expectedType: Function): boolean {\n const expectsTypesSerializedAsStrings = expectedType === String\n || expectedType === ArrayBuffer\n || expectedType === DataView;\n\n const hasQuotes = jsonStr.length >= 2 && jsonStr[0] === '\"' && jsonStr[jsonStr.length-1] === '\"';\n const isInteger = /^\\d+$/.test(jsonStr.trim());\n\n return (expectsTypesSerializedAsStrings && !hasQuotes) || ((!hasQuotes && !isInteger) && expectedType === Date);\n}\n\nexport function parseToJSObject(json: any, expectedType: Function): Object {\n if (typeof json !== 'string' || shouldOmitParseString(json, expectedType))\n {\n return json;\n }\n return JSON.parse(json);\n}\n\n/**\n * Determines if 'A' is a sub-type of 'B' (or if 'A' equals 'B').\n * @param A The supposed derived type.\n * @param B The supposed base type.\n */\nexport function isSubtypeOf(A: Function, B: Function)\n{\n return A === B || A.prototype instanceof B;\n}\n\nexport function logError(message?: any, ...optionalParams: any[])\n{\n if (typeof console === \"object\" && typeof console.error === \"function\")\n {\n console.error(message, ...optionalParams);\n }\n else if (typeof console === \"object\" && typeof console.log === \"function\")\n {\n console.log(`ERROR: ${message}`, ...optionalParams);\n }\n}\n\nexport function logMessage(message?: any, ...optionalParams: any[])\n{\n if (typeof console === \"object\" && typeof console.log === \"function\")\n {\n console.log(message, ...optionalParams);\n }\n}\n\nexport function logWarning(message?: any, ...optionalParams: any[])\n{\n if (typeof console === \"object\" && typeof console.warn === \"function\")\n {\n console.warn(message, ...optionalParams);\n } else if (typeof console === \"object\" && typeof console.log === \"function\")\n {\n console.log(`WARNING: ${message}`, ...optionalParams);\n }\n}\n\n/**\n * Checks if the value is considered defined (not undefined and not null).\n * @param value\n */\nexport function isValueDefined(value: T): value is Exclude\n{\n return !(typeof value === \"undefined\" || value === null);\n}\n\nexport function isInstanceOf(value: any, constructor: Function): boolean\n{\n if (typeof value === \"number\")\n {\n return (constructor === Number);\n }\n else if (typeof value === \"string\")\n {\n return (constructor === String);\n }\n else if (typeof value === \"boolean\")\n {\n return (constructor === Boolean);\n }\n else if (isObject(value))\n {\n return (value instanceof constructor);\n }\n\n return false;\n}\n\nexport const isReflectMetadataSupported =\n (typeof Reflect === \"object\" && typeof Reflect.getMetadata === \"function\");\n\n/**\n * Gets the name of a function.\n * @param fn The function whose name to get.\n */\nexport function nameof(fn: Function & { name?: string })\n{\n if (typeof fn.name === \"string\")\n {\n return fn.name;\n }\n else\n {\n return \"undefined\";\n }\n}\n","import { nameof, logError, METADATA_FIELD_KEY, isDirectlySerializableNativeType, isTypeTypedArray } from \"./helpers\";\nimport { IndexedObject } from \"./types\";\n\nexport interface JsonMemberMetadata\n{\n /** If set, a default value will be emitted for uninitialized members. */\n emitDefaultValue?: boolean;\n\n /** Member name as it appears in the serialized JSON. */\n name: string;\n\n /** Property or field key of the json member. */\n key: string;\n\n /** Constuctor (type) reference of the member. */\n ctor?: Function;\n\n /** If set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** If the json member is an array, map or set, sets member options of elements/values. Subsequent values define the types of nested arrays. */\n elementType?: Function[];\n\n /** If the json member is a map, sets member options of array keys. */\n keyType?: Function;\n\n /** Custom deserializer to use. */\n deserializer?: (json: any) => any;\n\n /** Custom serializer to use. */\n serializer?: (value: any) => any;\n}\n\nexport class JsonObjectMetadata\n{\n //#region Static\n /**\n * Gets the name of a class as it appears in a serialized JSON string.\n * @param ctor The constructor of a class (with or without jsonObject).\n */\n public static getJsonObjectName(ctor: Function): string\n {\n const metadata = JsonObjectMetadata.getFromConstructor(ctor);\n return metadata ? nameof(metadata.classType) : nameof(ctor);\n }\n\n /**\n * Gets jsonObject metadata information from a class.\n * @param ctor The constructor class.\n */\n public static getFromConstructor(ctor: Function): JsonObjectMetadata|undefined\n {\n const prototype = ctor.prototype;\n if (!prototype)\n {\n return;\n }\n\n let metadata: JsonObjectMetadata|undefined;\n if (prototype.hasOwnProperty(METADATA_FIELD_KEY))\n {\n // The class prototype contains own jsonObject metadata\n metadata = prototype[METADATA_FIELD_KEY];\n }\n\n // Ignore implicitly added jsonObject (through jsonMember)\n if (metadata && metadata.isExplicitlyMarked)\n {\n return metadata;\n }\n\n // In the end maybe it is something which we can handle directly\n if (JsonObjectMetadata.doesHandleWithoutAnnotation(ctor))\n {\n const primitiveMeta = new JsonObjectMetadata(ctor);\n primitiveMeta.isExplicitlyMarked = true;\n // we do not store the metadata here to not modify builtin prototype\n return primitiveMeta;\n }\n }\n\n /**\n * Gets the known type name of a jsonObject class for type hint.\n * @param constructor The constructor class.\n */\n public static getKnownTypeNameFromType(constructor: Function): string\n {\n const metadata = JsonObjectMetadata.getFromConstructor(constructor);\n return metadata ? nameof(metadata.classType) : nameof(constructor);\n }\n\n private static doesHandleWithoutAnnotation(ctor: Function): boolean\n {\n return isDirectlySerializableNativeType(ctor) || isTypeTypedArray(ctor)\n || ctor === DataView || ctor === ArrayBuffer;\n }\n //#endregion\n\n constructor(\n classType: Function,\n ) {\n this.classType = classType;\n }\n\n public dataMembers: Map = new Map();\n\n public knownTypes: Set = new Set();\n\n public knownTypeMethodName?: string;\n\n /** Gets or sets the constructor function for the jsonObject. */\n public classType: Function;\n\n /**\n * Indicates whether this class was explicitly annotated with @jsonObject\n * or implicitly by @jsonMember\n */\n public isExplicitlyMarked: boolean = false;\n\n /**\n * Indicates whether this type is handled without annotation. This is usually\n * used for the builtin types (except for Maps, Sets, and normal Arrays).\n */\n public isHandledWithoutAnnotation: boolean = false;\n\n /** Name used to encode polymorphic type */\n public name?: string;\n\n public onDeserializedMethodName?: string;\n\n public initializerCallback?: (sourceObject: Object, rawSourceObject: Object) => Object;\n}\n\nexport function injectMetadataInformation(constructor: IndexedObject, propKey: string | symbol, metadata: JsonMemberMetadata)\n{\n const decoratorName = `@jsonMember on ${nameof(constructor.constructor)}.${String(propKey)}`; // For error messages.\n let objectMetadata: JsonObjectMetadata;\n\n // When a property decorator is applied to a static member, 'constructor' is a constructor function.\n // See: https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Decorators.md#property-decorators\n // ... and static members are not supported here, so abort.\n if (typeof constructor === \"function\")\n {\n logError(`${decoratorName}: cannot use a static property.`);\n return;\n }\n\n // Methods cannot be serialized.\n // @ts-ignore symbol indexing is not supported by ts\n if (typeof constructor[propKey] === \"function\")\n {\n logError(`${decoratorName}: cannot use a method property.`);\n return;\n }\n\n if (!metadata || (!metadata.ctor && !metadata.deserializer))\n {\n logError(`${decoratorName}: JsonMemberMetadata has unknown ctor.`);\n return;\n }\n\n // Add jsonObject metadata to 'constructor' if not yet exists ('constructor' is the prototype).\n // NOTE: this will not fire up custom serialization, as 'constructor' must be explicitly marked with '@jsonObject' as well.\n if (!constructor.hasOwnProperty(METADATA_FIELD_KEY))\n {\n // No *own* metadata, create new.\n objectMetadata = new JsonObjectMetadata(constructor.constructor);\n\n // Inherit @JsonMembers from parent @jsonObject (if any).\n const parentMetadata: JsonObjectMetadata = constructor[METADATA_FIELD_KEY];\n if (parentMetadata) // && !constructor.hasOwnProperty(Helpers.METADATA_FIELD_KEY)\n {\n parentMetadata.dataMembers.forEach((_metadata, _propKey) => objectMetadata.dataMembers.set(_propKey, _metadata));\n }\n\n // ('constructor' is the prototype of the involved class, metadata information is added to this class prototype).\n Object.defineProperty(constructor, METADATA_FIELD_KEY, {\n enumerable: false,\n configurable: false,\n writable: false,\n value: objectMetadata\n });\n }\n else\n {\n // JsonObjectMetadata already exists on 'constructor'.\n objectMetadata = constructor[METADATA_FIELD_KEY];\n }\n\n if (!metadata.deserializer)\n {\n // @ts-ignore above is a check (!deser && !ctor)\n objectMetadata.knownTypes.add(metadata.ctor);\n }\n\n if (metadata.keyType)\n objectMetadata.knownTypes.add(metadata.keyType);\n\n if (metadata.elementType)\n metadata.elementType.forEach(elemCtor => objectMetadata.knownTypes.add(elemCtor));\n\n objectMetadata.dataMembers.set(metadata.name, metadata);\n}\n","import { nameof, logError, isSubtypeOf, isValueDefined } from \"./helpers\";\nimport { IndexedObject } from \"./types\";\nimport { JsonObjectMetadata } from \"./metadata\";\n\nexport interface IScopeTypeInfo\n{\n selfConstructor: Function;\n elementConstructor?: Function[];\n keyConstructor?: Function;\n knownTypes: Map;\n}\n\n/**\n * Utility class, converts a simple/untyped javascript object-tree to a typed object-tree.\n * It is used after parsing a JSON-string.\n */\nexport class Deserializer\n{\n private _typeResolver: (sourceObject: Object, knownTypes: Map) => Function|undefined;\n private _nameResolver?: (ctor: Function) => string;\n private _errorHandler: (error: Error) => void;\n\n constructor()\n {\n this._typeResolver = (sourceObject: any, knownTypes: Map) =>\n {\n if (sourceObject.__type) return knownTypes.get(sourceObject.__type);\n };\n\n this._errorHandler = (error) => logError(error);\n }\n\n public setNameResolver(nameResolverCallback: (ctor: Function) => string)\n {\n this._nameResolver = nameResolverCallback;\n }\n\n public setTypeResolver(typeResolverCallback: (sourceObject: Object, knownTypes: Map) => Function)\n {\n if (typeof typeResolverCallback !== \"function\") throw new TypeError(\"'typeResolverCallback' is not a function.\");\n\n this._typeResolver = typeResolverCallback;\n }\n\n public setErrorHandler(errorHandlerCallback: (error: Error) => void)\n {\n if (typeof errorHandlerCallback !== \"function\")\n {\n throw new TypeError(\"'errorHandlerCallback' is not a function.\");\n }\n\n this._errorHandler = errorHandlerCallback;\n }\n\n public convertAsObject(\n sourceObject: IndexedObject,\n sourceObjectTypeInfo: IScopeTypeInfo,\n objectName = \"object\",\n ) {\n if (typeof sourceObject !== \"object\" || sourceObject === null)\n {\n this._errorHandler(new TypeError(`Cannot deserialize ${objectName}: 'sourceObject' must be a defined object.`));\n return undefined;\n }\n\n let expectedSelfType = sourceObjectTypeInfo.selfConstructor;\n let sourceObjectMetadata = JsonObjectMetadata.getFromConstructor(expectedSelfType);\n let knownTypeConstructors = sourceObjectTypeInfo.knownTypes;\n\n if (sourceObjectMetadata)\n {\n // Merge known types received from \"above\" with known types defined on the current type.\n knownTypeConstructors = this._mergeKnownTypes(\n knownTypeConstructors,\n this._createKnownTypesMap(sourceObjectMetadata.knownTypes),\n );\n }\n\n // Check if a type-hint is available from the source object.\n let typeFromTypeHint = this._typeResolver(sourceObject, knownTypeConstructors);\n\n if (typeFromTypeHint)\n {\n // Check if type hint is a valid subtype of the expected source type.\n if (isSubtypeOf(typeFromTypeHint, expectedSelfType))\n {\n // Hell yes.\n expectedSelfType = typeFromTypeHint;\n sourceObjectMetadata = JsonObjectMetadata.getFromConstructor(typeFromTypeHint);\n\n if (sourceObjectMetadata)\n {\n // Also merge new known types from subtype.\n knownTypeConstructors = this._mergeKnownTypes(\n knownTypeConstructors,\n this._createKnownTypesMap(sourceObjectMetadata.knownTypes),\n );\n }\n }\n }\n\n if (sourceObjectMetadata && sourceObjectMetadata.isExplicitlyMarked)\n {\n const sourceMetadata = sourceObjectMetadata;\n // Strong-typed deserialization available, get to it.\n // First deserialize properties into a temporary object.\n const sourceObjectWithDeserializedProperties = {} as IndexedObject;\n\n // Deserialize by expected properties.\n sourceMetadata.dataMembers.forEach((memberMetadata, propKey) =>\n {\n const memberValue = sourceObject[propKey];\n const memberNameForDebug = `${nameof(sourceMetadata.classType)}.${propKey}`;\n\n let revivedValue;\n if (memberMetadata.deserializer) {\n revivedValue = memberMetadata.deserializer(memberValue);\n } else if (memberMetadata.ctor) {\n revivedValue = this.convertSingleValue(\n memberValue,\n {\n selfConstructor: memberMetadata.ctor,\n elementConstructor: memberMetadata.elementType,\n keyConstructor: memberMetadata.keyType,\n knownTypes: knownTypeConstructors\n },\n memberNameForDebug,\n );\n } else {\n throw new TypeError(\n `Cannot deserialize ${memberNameForDebug} thers is`\n + ` no constructor nor deserlization function to use.`,\n );\n }\n\n if (isValueDefined(revivedValue))\n {\n sourceObjectWithDeserializedProperties[memberMetadata.key] = revivedValue;\n }\n else if (memberMetadata.isRequired)\n {\n this._errorHandler(new TypeError(`Missing required member '${memberNameForDebug}'.`));\n }\n });\n\n // Next, instantiate target object.\n let targetObject: IndexedObject;\n\n if (typeof sourceObjectMetadata.initializerCallback === \"function\")\n {\n try\n {\n targetObject = sourceObjectMetadata.initializerCallback(\n sourceObjectWithDeserializedProperties,\n sourceObject,\n );\n\n // Check the validity of user-defined initializer callback.\n if (!targetObject)\n {\n throw new TypeError(\n `Cannot deserialize ${objectName}:`\n + ` 'initializer' function returned undefined/null`\n + `, but '${nameof(sourceObjectMetadata.classType)}' was expected.`,\n );\n }\n else if (!(targetObject instanceof sourceObjectMetadata.classType))\n {\n throw new TypeError(\n `Cannot deserialize ${objectName}:`\n + `'initializer' returned '${nameof(targetObject.constructor)}'`\n + `, but '${nameof(sourceObjectMetadata.classType)}' was expected,`\n + `and '${nameof(targetObject.constructor)}' is not a subtype of`\n + ` '${nameof(sourceObjectMetadata.classType)}'`,\n );\n }\n }\n catch (e)\n {\n this._errorHandler(e);\n return undefined;\n }\n }\n else\n {\n targetObject = this._instantiateType(expectedSelfType);\n }\n\n // Finally, assign deserialized properties to target object.\n Object.assign(targetObject, sourceObjectWithDeserializedProperties);\n\n // Call onDeserialized method (if any).\n if (sourceObjectMetadata.onDeserializedMethodName)\n {\n if (typeof (targetObject.constructor as any)[sourceObjectMetadata.onDeserializedMethodName] === \"function\")\n {\n (targetObject.constructor as any)[sourceObjectMetadata.onDeserializedMethodName]();\n }\n else\n {\n this._errorHandler(new TypeError(\n `onDeserialized callback '${nameof(sourceObjectMetadata.classType)}.${sourceObjectMetadata.onDeserializedMethodName}' is not a method.`\n ));\n }\n }\n\n return targetObject;\n }\n else\n {\n // Untyped deserialization into Object instance.\n let targetObject = {} as IndexedObject;\n\n Object.keys(sourceObject).forEach(sourceKey =>\n {\n targetObject[sourceKey] = this.convertSingleValue(sourceObject[sourceKey], {\n selfConstructor: sourceObject[sourceKey].constructor,\n knownTypes: sourceObjectTypeInfo.knownTypes,\n elementConstructor: sourceObjectTypeInfo.elementConstructor,\n keyConstructor: sourceObjectTypeInfo.keyConstructor\n }, sourceKey);\n });\n\n return targetObject;\n }\n }\n\n public convertSingleValue(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\")\n {\n let expectedSelfType = typeInfo.selfConstructor;\n let srcTypeNameForDebug = sourceObject ? nameof(sourceObject.constructor) : \"undefined\";\n\n if (!isValueDefined(sourceObject))\n {\n return sourceObject;\n }\n else if (this._isDirectlyDeserializableNativeType(expectedSelfType))\n {\n if (sourceObject.constructor === expectedSelfType)\n {\n return sourceObject;\n }\n else\n {\n throw new TypeError(this._makeTypeErrorMessage(nameof(expectedSelfType), sourceObject.constructor, memberName));\n }\n }\n else if (expectedSelfType === Date)\n {\n // Support for Date with ISO 8601 format, or with numeric timestamp (milliseconds elapsed since the Epoch).\n // ISO 8601 spec.: https://www.w3.org/TR/NOTE-datetime\n\n if (typeof sourceObject === \"string\" || (typeof sourceObject === \"number\" && sourceObject > 0))\n return new Date(sourceObject as any);\n else\n this._throwTypeMismatchError(\"Date\", \"an ISO-8601 string\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Float32Array)\n {\n // Deserialize Float32Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Float32Array(sourceObject);\n else\n this._throwTypeMismatchError(\"Float32Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Float64Array)\n {\n // Deserialize Float64Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Float64Array(sourceObject);\n else\n this._throwTypeMismatchError(\"Float64Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint8Array)\n {\n // Deserialize Uint8Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint8Array(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint8Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint8ClampedArray)\n {\n // Deserialize Uint8Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint8ClampedArray(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint8ClampedArray\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint16Array)\n {\n // Deserialize Uint16Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint16Array(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint16Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint32Array)\n {\n // Deserialize Uint32Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint32Array(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint32Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === ArrayBuffer)\n {\n if (typeof sourceObject === \"string\")\n return this._stringToArrayBuffer(sourceObject);\n else\n this._throwTypeMismatchError(\"ArrayBuffer\", \"a string source\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === DataView)\n {\n if (typeof sourceObject === \"string\")\n return this._stringToDataView(sourceObject);\n else\n this._throwTypeMismatchError(\"DataView\", \"a string source\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Array)\n {\n if (sourceObject instanceof Array)\n return this.convertAsArray(sourceObject, typeInfo, memberName);\n else\n throw new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName));\n }\n else if (expectedSelfType === Set)\n {\n if (sourceObject instanceof Array)\n return this.convertAsSet(sourceObject, typeInfo, memberName);\n else\n this._throwTypeMismatchError(\"Set\", \"Array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Map)\n {\n if (sourceObject instanceof Array)\n return this.convertAsMap(sourceObject, typeInfo, memberName);\n else\n this._throwTypeMismatchError(\"Map\", \"a source array of key-value-pair objects\", srcTypeNameForDebug, memberName);\n }\n else if (sourceObject && typeof sourceObject === \"object\")\n {\n return this.convertAsObject(sourceObject, typeInfo, memberName);\n }\n }\n\n public convertAsArray(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\"): any[]\n {\n if (!(sourceObject instanceof Array))\n {\n this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)));\n return [];\n }\n\n if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Array: missing constructor reference of Array elements.`));\n return [];\n }\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.elementConstructor[0],\n elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [],\n knownTypes: typeInfo.knownTypes\n };\n\n return sourceObject.map(element =>\n {\n // If an array element fails to deserialize, substitute with undefined. This is so that the original ordering is not interrupted by faulty\n // entries, as an Array is ordered.\n try\n {\n return this.convertSingleValue(element, elementTypeInfo);\n }\n catch (e)\n {\n this._errorHandler(e);\n\n // Keep filling the array here with undefined to keep original ordering.\n // Note: this is just aesthetics, not returning anything produces the same result.\n return undefined;\n }\n });\n }\n\n public convertAsSet(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\")\n {\n if (!(sourceObject instanceof Array))\n {\n this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)));\n return new Set();\n }\n\n if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Set: missing constructor reference of Set elements.`));\n return new Set();\n }\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.elementConstructor[0],\n elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [],\n knownTypes: typeInfo.knownTypes\n };\n let resultSet = new Set();\n\n sourceObject.forEach((element, i) =>\n {\n try\n {\n resultSet.add(this.convertSingleValue(element, elementTypeInfo, memberName + `[${i}]`));\n }\n catch (e)\n {\n // Faulty entries are skipped, because a Set is not ordered, and skipping an entry does not affect others.\n this._errorHandler(e);\n }\n });\n\n return resultSet;\n }\n\n public convertAsMap(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\")\n {\n if (!(sourceObject instanceof Array))\n this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)));\n\n if (!typeInfo.keyConstructor)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Map: missing key constructor.`));\n return new Map();\n }\n\n if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Map: missing value constructor.`));\n return new Map();\n }\n\n let keyTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.keyConstructor,\n knownTypes: typeInfo.knownTypes\n };\n\n let valueTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.elementConstructor[0],\n elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [],\n knownTypes: typeInfo.knownTypes\n };\n\n let resultMap = new Map();\n\n sourceObject.forEach((element: any) =>\n {\n try\n {\n let key = this.convertSingleValue(element.key, keyTypeInfo);\n\n // Undefined/null keys not supported, skip if so.\n if (isValueDefined(key))\n {\n resultMap.set(key, this.convertSingleValue(\n element.value, valueTypeInfo, `${memberName}[${key}]`,\n ));\n }\n }\n catch (e)\n {\n // Faulty entries are skipped, because a Map is not ordered,\n // and skipping an entry does not affect others.\n this._errorHandler(e);\n }\n });\n\n return resultMap;\n }\n\n private _throwTypeMismatchError(\n targetType: string,\n expectedSourceType: string,\n actualSourceType: string,\n memberName: string = \"object\",\n ) {\n throw new TypeError(\n `Could not deserialize ${memberName} as ${targetType}:`\n + ` expected ${expectedSourceType}, got ${actualSourceType}.`,\n );\n }\n\n private _makeTypeErrorMessage(expectedType: Function | string, actualType: Function | string, memberName = \"object\")\n {\n let expectedTypeName = (typeof expectedType === \"function\") ? nameof(expectedType) : expectedType;\n let actualTypeName = (typeof actualType === \"function\") ? nameof(actualType) : actualType;\n\n return `Could not deserialize ${memberName}: expected '${expectedTypeName}', got '${actualTypeName}'.`;\n }\n\n private _instantiateType(ctor: any)\n {\n return new ctor();\n }\n\n private _mergeKnownTypes(...knownTypeMaps: Array>)\n {\n let result = new Map();\n\n knownTypeMaps.forEach(knownTypes =>\n {\n knownTypes.forEach((ctor, name) =>\n {\n if (this._nameResolver)\n {\n result.set(this._nameResolver(ctor), ctor);\n }\n else\n {\n result.set(name, ctor);\n }\n });\n });\n\n return result;\n }\n\n private _createKnownTypesMap(knowTypes: Set)\n {\n const map = new Map();\n\n knowTypes.forEach(ctor =>\n {\n if (this._nameResolver)\n {\n map.set(this._nameResolver(ctor), ctor);\n }\n else\n {\n const knownTypeMeta = JsonObjectMetadata.getFromConstructor(ctor);\n const name = knownTypeMeta && knownTypeMeta.isExplicitlyMarked && knownTypeMeta.name\n ? knownTypeMeta.name\n : ctor.name;\n map.set(name, ctor);\n }\n });\n\n return map;\n }\n\n private _isDirectlyDeserializableNativeType(ctor: any)\n {\n return ~([Number, String, Boolean].indexOf(ctor));\n }\n\n public convertNativeObject(sourceObject: any)\n {\n return sourceObject;\n }\n\n private _stringToArrayBuffer(str: string)\n {\n let buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char\n let bufView = new Uint16Array(buf);\n\n for (let i = 0, strLen = str.length; i < strLen; i++)\n {\n bufView[i] = str.charCodeAt(i);\n }\n\n return buf;\n }\n\n private _stringToDataView(str: string)\n {\n return new DataView(this._stringToArrayBuffer(str));\n }\n}\n","import { nameof, logError, isValueDefined, isInstanceOf, isTypeTypedArray, isDirectlySerializableNativeType } from \"./helpers\";\nimport { IndexedObject } from \"./types\";\nimport { JsonObjectMetadata } from \"./metadata\";\n\nexport interface IScopeTypeInfo\n{\n selfType: Function;\n elementTypes?: Function[];\n keyType?: Function;\n}\n\nexport interface IScopeArrayTypeInfo extends IScopeTypeInfo\n{\n selfType: new () => Array;\n elementTypes: Function[];\n}\n\nfunction isArrayTypeInfo(typeInfo: IScopeTypeInfo): typeInfo is IScopeArrayTypeInfo {\n return typeInfo.selfType === Array;\n}\n\nexport interface IScopeSetTypeInfo extends IScopeTypeInfo\n{\n selfType: new () => Set;\n elementTypes: [Function];\n}\n\nfunction isSetTypeInfo(typeInfo: IScopeTypeInfo): typeInfo is IScopeSetTypeInfo {\n return typeInfo.selfType === Set;\n}\n\nexport interface IScopeMapTypeInfo extends IScopeTypeInfo\n{\n selfType: new () => Map;\n elementTypes: [Function];\n keyType: Function;\n}\n\nfunction isMapTypeInfo(typeInfo: IScopeTypeInfo): typeInfo is IScopeMapTypeInfo {\n return typeInfo.selfType === Map;\n}\n\n/**\n * Utility class, converts a typed object tree (i.e. a tree of class instances, arrays of class instances, and so on) to an untyped javascript object (also\n * called \"simple javascript object\"), and emits any necessary type hints in the process (for polymorphism).\n *\n * The converted object tree is what will be given to `JSON.stringify` to convert to string as the last step, the serialization is basically like:\n *\n * (1) typed object-tree -> (2) simple JS object-tree -> (3) JSON-string\n */\nexport class Serializer\n{\n private _typeHintEmitter: (targetObject: IndexedObject, sourceObject: IndexedObject, expectedSourceType: Function, sourceTypeMetadata?: JsonObjectMetadata) => void;\n private _errorHandler: (error: Error) => void;\n\n constructor()\n {\n this._typeHintEmitter = (targetObject, sourceObject, expectedSourceType, sourceTypeMetadata?: JsonObjectMetadata) =>\n {\n // By default, we put a \"__type\" property on the output object if the actual object is not the same as the expected one, so that deserialization\n // will know what to deserialize into (given the required known-types are defined, and the object is a valid subtype of the expected type).\n if (sourceObject.constructor !== expectedSourceType)\n {\n const name = sourceTypeMetadata && sourceTypeMetadata.name\n ? sourceTypeMetadata.name\n : nameof(sourceObject.constructor);\n // TODO: Perhaps this can work correctly without string-literal access?\n // tslint:disable-next-line:no-string-literal\n targetObject[\"__type\"] = name;\n }\n };\n\n this._errorHandler = (error) => logError(error);\n }\n\n public setTypeHintEmitter(typeEmitterCallback: (targetObject: Object, sourceObject: Object, expectedSourceType: Function) => void)\n {\n if (typeof typeEmitterCallback !== \"function\")\n {\n throw new TypeError(\"'typeEmitterCallback' is not a function.\");\n }\n\n this._typeHintEmitter = typeEmitterCallback;\n }\n\n public setErrorHandler(errorHandlerCallback: (error: Error) => void)\n {\n if (typeof errorHandlerCallback !== \"function\")\n {\n throw new TypeError(\"'errorHandlerCallback' is not a function.\");\n }\n\n this._errorHandler = errorHandlerCallback;\n }\n\n /**\n * Convert a value of any supported serializable type.\n * The value type will be detected, and the correct serialization method will be called.\n */\n public convertSingleValue(sourceObject: any, typeInfo: IScopeTypeInfo, memberName: string = \"object\"): any\n {\n if (!isValueDefined(sourceObject)) return;\n\n if (!isInstanceOf(sourceObject, typeInfo.selfType))\n {\n let expectedName = nameof(typeInfo.selfType);\n let actualName = nameof(sourceObject.constructor);\n\n this._errorHandler(new TypeError(`Could not serialize '${memberName}': expected '${expectedName}', got '${actualName}'.`));\n return;\n }\n\n if (isDirectlySerializableNativeType(typeInfo.selfType))\n {\n return sourceObject;\n }\n else if (typeInfo.selfType === ArrayBuffer)\n {\n return this.convertAsArrayBuffer(sourceObject);\n }\n else if (typeInfo.selfType === DataView)\n {\n return this.convertAsDataView(sourceObject);\n }\n else if (isArrayTypeInfo(typeInfo))\n {\n return this.convertAsArray(sourceObject, typeInfo.elementTypes, memberName);\n }\n else if (isSetTypeInfo(typeInfo))\n {\n return this.convertAsSet(sourceObject, typeInfo.elementTypes[0], memberName);\n }\n else if (isMapTypeInfo(typeInfo))\n {\n return this.convertAsMap(sourceObject, typeInfo.keyType, typeInfo.elementTypes[0], memberName);\n }\n else if (isTypeTypedArray(typeInfo.selfType))\n {\n return this.convertAsTypedArray(sourceObject);\n }\n else if (typeof sourceObject === \"object\")\n {\n return this.convertAsObject(sourceObject, typeInfo, memberName);\n }\n }\n\n /**\n * Performs the conversion of a typed object (usually a class instance) to a simple javascript object for serialization.\n */\n public convertAsObject(sourceObject: IndexedObject, typeInfo: IScopeTypeInfo, memberName?: string)\n {\n let sourceTypeMetadata: JsonObjectMetadata|undefined;\n let targetObject: IndexedObject;\n\n if (sourceObject.constructor !== typeInfo.selfType && sourceObject instanceof typeInfo.selfType)\n {\n // The source object is not of the expected type, but it is a valid subtype.\n // This is OK, and we'll proceed to gather object metadata from the subtype instead.\n sourceTypeMetadata = JsonObjectMetadata.getFromConstructor(sourceObject.constructor);\n }\n else\n {\n sourceTypeMetadata = JsonObjectMetadata.getFromConstructor(typeInfo.selfType);\n }\n\n if (sourceTypeMetadata)\n {\n const sourceMeta = sourceTypeMetadata;\n // Strong-typed serialization available.\n // We'll serialize by members that have been marked with @jsonMember (including array/set/map members), and perform recursive conversion on\n // each of them. The converted objects are put on the 'targetObject', which is what will be put into 'JSON.stringify' finally.\n targetObject = {};\n\n sourceTypeMetadata.dataMembers.forEach((memberMetadata) =>\n {\n if (memberMetadata.serializer) {\n targetObject[memberMetadata.name] =\n memberMetadata.serializer(sourceObject[memberMetadata.key]);\n } else if (memberMetadata.ctor) {\n targetObject[memberMetadata.name] = this.convertSingleValue(\n sourceObject[memberMetadata.key],\n {\n selfType: memberMetadata.ctor,\n elementTypes: memberMetadata.elementType,\n keyType: memberMetadata.keyType,\n },\n `${nameof(sourceMeta.classType)}.${memberMetadata.key}`,\n );\n } else {\n throw new TypeError(\n `Could not serialize ${memberMetadata.name}, there is`\n + ` no constructor nor serialization function to use.`,\n );\n }\n });\n }\n else\n {\n // Untyped serialization, \"as-is\", we'll just pass the object on.\n // We'll clone the source object, because type hints are added to the object itself, and we don't want to modify to the original object.\n targetObject = { ...sourceObject };\n }\n\n // Add type-hint.\n this._typeHintEmitter(targetObject, sourceObject, typeInfo.selfType, sourceTypeMetadata);\n\n return targetObject;\n }\n\n /**\n * Performs the conversion of an array of typed objects (or primitive values) to an array of simple javascript objects (or primitive values) for\n * serialization.\n * @param expectedElementType The expected type of elements. If the array is supposed to be multi-dimensional, subsequent elements define lower dimensions.\n * @param memberName Name of the object being serialized, used for debugging purposes.\n */\n public convertAsArray(sourceObject: any[], expectedElementType: Function[], memberName = \"object\"): any[]\n {\n if (expectedElementType.length === 0 || !expectedElementType[0])\n throw new TypeError(`Could not serialize ${memberName} as Array: missing element type definition.`);\n\n // Check the type of each element, individually.\n // If at least one array element type is incorrect, we return undefined, which results in no value emitted during serialization.\n // This is so that invalid element types don't unexpectedly alter the ordering of other, valid elements, and that no unexpected undefined values are in\n // the emitted array.\n sourceObject.forEach((element, i) =>\n {\n if (!isInstanceOf(element, expectedElementType[0]))\n {\n const expectedTypeName = nameof(expectedElementType[0]);\n const actualTypeName = nameof(element.constructor);\n throw new TypeError(`Could not serialize ${memberName}[${i}]: expected '${expectedTypeName}', got '${actualTypeName}'.`);\n }\n });\n\n const typeInfoForElements: IScopeTypeInfo = {\n selfType: expectedElementType[0],\n elementTypes: expectedElementType.length > 1 ? expectedElementType.slice(1) : [], // For multidimensional arrays.\n };\n\n if (memberName)\n {\n // Just for debugging purposes.\n memberName += \"[]\";\n }\n\n return sourceObject.map(element => this.convertSingleValue(element, typeInfoForElements, memberName));\n }\n\n /**\n * Performs the conversion of a set of typed objects (or primitive values) into an array of simple javascript objects.\n *\n * @param sourceObject\n * @param expectedElementType The constructor of the expected Set elements (e.g. `Number` for `Set`, or `MyClass` for `Set`).\n * @param memberName Name of the object being serialized, used for debugging purposes.\n * @returns\n */\n public convertAsSet(sourceObject: Set, expectedElementType: Function, memberName = \"object\"): any[]\n {\n if (!expectedElementType)\n throw new TypeError(`Could not serialize ${memberName} as Set: missing element type definition.`);\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfType: expectedElementType,\n };\n\n // For debugging and error tracking.\n if (memberName) memberName += \"[]\";\n\n let resultArray: any[] = [];\n\n // Convert each element of the set, and put it into an output array.\n // The output array is the one serialized, as JSON.stringify does not support Set serialization. (TODO: clarification needed)\n sourceObject.forEach(element =>\n {\n let resultElement = this.convertSingleValue(element, elementTypeInfo, memberName);\n\n // Add to output if the source element was undefined, OR the converted element is defined. This will add intentionally undefined values to output,\n // but not values that became undefined DURING serializing (usually because of a type-error).\n if (!isValueDefined(element) || isValueDefined(resultElement))\n {\n resultArray.push(resultElement);\n }\n });\n\n return resultArray;\n }\n\n /**\n * Performs the conversion of a map of typed objects (or primitive values) into an array of simple javascript objects with `key` and `value` properties.\n *\n * @param sourceObject\n * @param expectedKeyType The constructor of the expected Map keys (e.g. `Number` for `Map`, or `MyClass` for `Map`).\n * @param expectedElementType The constructor of the expected Map values (e.g. `Number` for `Map`, or `MyClass` for `Map`).\n * @param memberName Name of the object being serialized, used for debugging purposes.\n */\n public convertAsMap(sourceObject: Map, expectedKeyType: Function, expectedElementType: Function, memberName = \"object\"): Array<{ key: any, value: any }>\n {\n if (!expectedElementType)\n throw new TypeError(`Could not serialize ${memberName} as Map: missing value type definition.`);\n\n if (!expectedKeyType)\n throw new TypeError(`Could not serialize ${memberName} as Map: missing key type definition.`);\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfType: expectedElementType,\n elementTypes: [expectedElementType]\n };\n\n let keyTypeInfo: IScopeTypeInfo = {\n selfType: expectedKeyType\n };\n\n if (memberName) memberName += \"[]\";\n\n let resultArray: Array<{ key: any, value: any }> = [];\n\n // Convert each *entry* in the map to a simple javascript object with key and value properties.\n sourceObject.forEach((value, key) =>\n {\n let resultKeyValuePairObj = {\n key: this.convertSingleValue(key, keyTypeInfo, memberName),\n value: this.convertSingleValue(value, elementTypeInfo, memberName)\n };\n\n // We are not going to emit entries with undefined keys OR undefined values.\n if (isValueDefined(resultKeyValuePairObj.key) && isValueDefined(resultKeyValuePairObj.value))\n {\n resultArray.push(resultKeyValuePairObj);\n }\n });\n\n return resultArray;\n }\n\n /**\n * Performs the conversion of a typed javascript array to a simple untyped javascript array.\n * This is needed because typed arrays are otherwise serialized as objects, so we'll end up with something like \"{ 0: 0, 1: 1, ... }\".\n *\n * @param sourceObject\n * @returns\n */\n public convertAsTypedArray(sourceObject: ArrayBufferView)\n {\n return Array.from(sourceObject as any);\n }\n\n /**\n * Performs the conversion of a raw ArrayBuffer to a string.\n */\n public convertAsArrayBuffer(buffer: ArrayBuffer)\n {\n // ArrayBuffer -> 16-bit character codes -> character array -> joined string.\n return Array.from(new Uint16Array(buffer)).map(charCode => String.fromCharCode(charCode)).join(\"\");\n }\n\n /**\n * Performs the conversion of DataView, converting its internal ArrayBuffer to a string and returning that string.\n */\n public convertAsDataView(dataView: DataView)\n {\n return this.convertAsArrayBuffer(dataView.buffer);\n }\n}\n","import { Constructor, ParameterlessConstructor } from \"./types\";\nimport { METADATA_FIELD_KEY } from \"./helpers\";\nimport { JsonObjectMetadata } from \"./metadata\";\n\nexport interface IJsonObjectOptionsBase\n{\n /**\n * An array of known types to recognize when encountering type-hints,\n * or the name of a static method used for determining known types.\n */\n knownTypes?: Function[] | string;\n\n /**\n * The name of a static or instance method to call when deserialization\n * of the object is completed.\n */\n onDeserialized?: string;\n\n /**\n * The name used to differentiate between different polymorphic types.\n */\n name?: string;\n}\n\nexport interface IJsonObjectOptionsWithInitializer extends IJsonObjectOptionsBase\n{\n /**\n * The name of a static method to call before deserializing and initializing the object, accepting two arguments: (1) sourceObject, an 'Object' instance\n * with all properties already deserialized, and (2) rawSourceObject, a raw 'Object' instance representation of the current object in the serialized JSON\n * (i.e. without deserialized properties).\n */\n initializer: (sourceObject: T, rawSourceObject: T) => T;\n}\n\nexport interface IJsonObjectOptions extends IJsonObjectOptionsBase\n{\n /**\n * The name of a static method to call before deserializing and initializing the object, accepting two arguments: (1) sourceObject, an 'Object' instance\n * with all properties already deserialized, and (2) rawSourceObject, a raw 'Object' instance representation of the current object in the serialized JSON\n * (i.e. without deserialized properties).\n */\n initializer?: (sourceObject: T, rawSourceObject: T) => T;\n}\n\n/**\n * Marks that a class with a parameterized constructor is serializable using TypedJSON, with additional settings. The 'initializer' setting must be specified.\n * @param options Configuration settings.\n */\nexport function jsonObject(options?: IJsonObjectOptionsWithInitializer): (target: Constructor) => void;\n\n/**\n * Marks that a class is serializable using TypedJSON, with additional settings.\n * @param options Configuration settings.\n */\nexport function jsonObject(options?: IJsonObjectOptions): (target: ParameterlessConstructor) => void;\n\n/**\n * Marks that a class with a parameterless constructor is serializable using TypedJSON.\n */\nexport function jsonObject(target: ParameterlessConstructor): void;\n\nexport function jsonObject(optionsOrTarget?: IJsonObjectOptions | Constructor\n): ((target: Constructor) => void) | void {\n let options: IJsonObjectOptions;\n\n if (typeof optionsOrTarget === \"function\")\n {\n // jsonObject is being used as a decorator, directly.\n options = {};\n }\n else\n {\n // jsonObject is being used as a decorator factory.\n options = optionsOrTarget || {};\n }\n\n function decorator(\n target: Function\n ): void {\n let objectMetadata: JsonObjectMetadata;\n\n // Create or obtain JsonObjectMetadata object.\n if (!target.prototype.hasOwnProperty(METADATA_FIELD_KEY))\n {\n // Target has no JsonObjectMetadata associated with it yet, create it now.\n objectMetadata = new JsonObjectMetadata(target);\n\n // Inherit json members and known types from parent @jsonObject (if any).\n const parentMetadata: JsonObjectMetadata = target.prototype[METADATA_FIELD_KEY];\n if (parentMetadata)\n {\n parentMetadata.dataMembers\n .forEach((memberMetadata, propKey) =>\n objectMetadata.dataMembers.set(propKey, memberMetadata));\n parentMetadata.knownTypes\n .forEach((knownType) => objectMetadata.knownTypes.add(knownType));\n }\n\n Object.defineProperty(target.prototype, METADATA_FIELD_KEY, {\n enumerable: false,\n configurable: false,\n writable: false,\n value: objectMetadata\n });\n }\n else\n {\n // Target already has JsonObjectMetadata associated with it.\n objectMetadata = target.prototype[METADATA_FIELD_KEY];\n objectMetadata.classType = target;\n }\n\n // Fill JsonObjectMetadata.\n objectMetadata.isExplicitlyMarked = true;\n objectMetadata.onDeserializedMethodName = options.onDeserialized;\n // T extend Object so it is fine\n objectMetadata.initializerCallback = options.initializer as any;\n if (options.name)\n {\n objectMetadata.name = options.name;\n }\n\n // Obtain known-types.\n if (typeof options.knownTypes === \"string\")\n {\n objectMetadata.knownTypeMethodName = options.knownTypes;\n }\n else if (options.knownTypes instanceof Array)\n {\n options.knownTypes\n .filter(knownType => !!knownType)\n .forEach(knownType => objectMetadata.knownTypes.add(knownType));\n }\n }\n\n if (typeof optionsOrTarget === \"function\")\n {\n // jsonObject is being used as a decorator, directly.\n decorator(optionsOrTarget);\n }\n else\n {\n // jsonObject is being used as a decorator factory.\n return decorator;\n }\n}\n","import {\n nameof, logError, isReflectMetadataSupported, isValueDefined, logWarning, isSubtypeOf\n} from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonMemberOptions\n{\n /**\n * Sets the constructor of the property.\n * Optional with ReflectDecorators.\n */\n constructor?: Function;\n\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, a default value is emitted if the property is uninitialized/undefined. */\n emitDefaultValue?: boolean;\n\n /** When set, the key on the JSON that should be used instead of the class property name. */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that a property is part of the object when serializing, with additional options.\n * Omitting the 'constructor' option requires ReflectDecorators and that the property type is always explicitly declared.\n * @param options Additional options.\n */\nexport function jsonMember(options: IJsonMemberOptions): PropertyDecorator;\n\n/**\n * Specifies that a property is part of the object when serializing.\n * This call signature requires ReflectDecorators and that the property type is always explicitly declared.\n */\nexport function jsonMember(target: Object, propertyKey: string | symbol): void;\n\nexport function jsonMember(optionsOrTarget?: IJsonMemberOptions | Object, propKey?: string | symbol): PropertyDecorator | void\n{\n if (optionsOrTarget instanceof Object && (typeof propKey === \"string\" || typeof propKey === \"symbol\"))\n {\n const target = optionsOrTarget as Object;\n // For error messages.\n const decoratorName = `@jsonMember on ${nameof(target.constructor)}.${String(propKey)}`;\n\n // jsonMember used directly, no additional information directly available besides target and propKey.\n // Obtain property constructor through ReflectDecorators.\n if (isReflectMetadataSupported)\n {\n const reflectPropCtor = Reflect.getMetadata(\"design:type\", target, propKey) as Function;\n\n if (!reflectPropCtor)\n {\n logError(`${decoratorName}: could not resolve detected property constructor at runtime.`);\n return;\n }\n\n if (isSpecialPropertyType(decoratorName, reflectPropCtor))\n {\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: reflectPropCtor,\n key: propKey.toString(),\n name: propKey.toString(),\n });\n }\n else\n {\n logError(`${decoratorName}: ReflectDecorators is required if no 'constructor' option is specified.`);\n return;\n }\n }\n else\n {\n // jsonMember used as a decorator factory.\n return (target: Object, _propKey: string | symbol) =>\n {\n let options: IJsonMemberOptions = optionsOrTarget || {};\n let propCtor: Function|undefined;\n let decoratorName = `@jsonMember on ${nameof(target.constructor)}.${String(_propKey)}`; // For error messages.\n\n if (options.hasOwnProperty(\"constructor\"))\n {\n if (!isValueDefined(options.constructor))\n {\n logError(`${decoratorName}: cannot resolve specified property constructor at runtime.`);\n return;\n }\n\n // Property constructor has been specified. Use ReflectDecorators (if available) to check whether that constructor is correct. Warn if not.\n if (isReflectMetadataSupported && !isSubtypeOf(options.constructor, Reflect.getMetadata(\"design:type\", target, _propKey)))\n {\n logWarning(`${decoratorName}: detected property type does not match 'constructor' option.`);\n }\n\n propCtor = options.constructor;\n }\n else\n {\n // Use ReflectDecorators to obtain property constructor.\n if (isReflectMetadataSupported)\n {\n propCtor = Reflect.getMetadata(\"design:type\", target, _propKey) as Function;\n\n if (!propCtor)\n {\n logError(`${decoratorName}: cannot resolve detected property constructor at runtime.`);\n return;\n }\n }\n else if (!options.deserializer)\n {\n logError(`${decoratorName}: ReflectDecorators is required if no 'constructor' option is specified.`);\n return;\n }\n }\n\n if (isSpecialPropertyType(decoratorName, propCtor))\n {\n return;\n }\n\n injectMetadataInformation(target, _propKey, {\n ctor: propCtor,\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: _propKey.toString(),\n name: options.name || _propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n }\n}\n\nfunction isSpecialPropertyType(decoratorName: string, propCtor?: Function)\n{\n if (propCtor === Array)\n {\n logError(`${decoratorName}: property is an Array. Use the jsonArrayMember decorator to`\n + ` serialize this property.`);\n return true;\n }\n\n if (propCtor === Set)\n {\n logError(`${decoratorName}: property is a Set. Use the jsonSetMember decorator to`\n + ` serialize this property.`);\n return true;\n }\n\n if (propCtor === Map)\n {\n logError(`${decoratorName}: property is a Map. Use the jsonMapMember decorator to`\n + ` serialize this property.`);\n return true;\n }\n\n return false;\n}\n","import { nameof, logError, isReflectMetadataSupported } from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonArrayMemberOptions\n{\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, an empty array is emitted if the property is undefined/uninitialized. */\n emitDefaultValue?: boolean;\n\n /** Sets array dimensions (e.g. 1 for 'number[]' or 2 for 'number[][]'). Defaults to 1. */\n dimensions?: number;\n\n /** When set, the key on the JSON that should be used instead of the class property name */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that a property, of type array, is part of an object when serializing.\n * @param elementConstructor Constructor of array elements (e.g. 'Number' for 'number[]', or 'Date' for 'Date[]').\n * @param options Additional options.\n */\nexport function jsonArrayMember(elementConstructor: Function, options: IJsonArrayMemberOptions = {})\n{\n return (target: Object, propKey: string | symbol) =>\n {\n let decoratorName = `@jsonArrayMember on ${nameof(target.constructor)}.${String(propKey)}`; // For error messages.\n\n if (typeof elementConstructor !== \"function\")\n {\n logError(`${decoratorName}: could not resolve constructor of array elements at runtime.`);\n return;\n }\n\n const dimensions = options.dimensions === undefined ? 1 : options.dimensions;\n if (!isNaN(dimensions) && dimensions < 1)\n {\n logError(`${decoratorName}: 'dimensions' option must be at least 1.`);\n return;\n }\n\n // If ReflectDecorators is available, use it to check whether 'jsonArrayMember' has been used on an array.\n if (isReflectMetadataSupported && Reflect.getMetadata(\"design:type\", target, propKey) !== Array)\n {\n logError(`${decoratorName}: property is not an Array.`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Array,\n elementType: createArrayElementType(elementConstructor, dimensions),\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: propKey.toString(),\n name: options.name || propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n}\n\nfunction createArrayElementType(elementCtor: Function, dimensions: number) {\n const elementTypes = new Array(dimensions).fill(Array, 0, -1);\n elementTypes[dimensions-1] = elementCtor;\n return elementTypes;\n}\n","import { nameof } from \"./helpers\";\nimport { IJsonMemberOptions } from \"./json-member\";\nimport { JsonMemberMetadata, JsonObjectMetadata, injectMetadataInformation } from \"./metadata\";\nimport * as Helpers from \"./helpers\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonSetMemberOptions\n{\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, a default value is emitted for each uninitialized json member. */\n emitDefaultValue?: boolean;\n\n /** When set, the key on the JSON that should be used instead of the class property name */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that the property is part of the object when serializing.\n * Use this decorator on properties of type Set.\n * @param elementConstructor Constructor of set elements (e.g. 'Number' for Set or 'Date' for Set).\n * @param options Additional options.\n */\nexport function jsonSetMember(elementConstructor: Function, options: IJsonSetMemberOptions = {})\n{\n return (target: Object, propKey: string | symbol) =>\n {\n var decoratorName = `@jsonSetMember on ${nameof(target.constructor)}.${String(propKey)}`; // For error messages.\n\n if (typeof elementConstructor !== \"function\")\n {\n Helpers.logError(`${decoratorName}: could not resolve constructor of set elements at runtime.`);\n return;\n }\n\n // If ReflectDecorators is available, use it to check whether 'jsonSetMember' has been used on a set. Warn if not.\n if (Helpers.isReflectMetadataSupported && Reflect.getMetadata(\"design:type\", target, propKey) !== Set)\n {\n Helpers.logError(`${decoratorName}: property is not a Set.`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Set,\n elementType: [elementConstructor],\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: propKey.toString(),\n name: options.name || propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n}\n","import { nameof, logError, isReflectMetadataSupported } from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonMapMemberOptions\n{\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, a default value is emitted for each uninitialized json member. */\n emitDefaultValue?: boolean;\n\n /** When set, the key on the JSON that should be used instead of the class property name */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that the property is part of the object when serializing.\n * Use this decorator on properties of type Map.\n * @param keyConstructor Constructor of map keys (e.g. 'Number' for 'Map').\n * @param valueConstructor Constructor of map values (e.g. 'Date' for 'Map').\n * @param options Additional options.\n */\nexport function jsonMapMember(keyConstructor: Function, valueConstructor: Function, options: IJsonMapMemberOptions = {})\n{\n return (target: Object, propKey: string | symbol) =>\n {\n let decoratorName = `@jsonMapMember on ${nameof(target.constructor)}.${String(propKey)}`; // For error messages.\n\n if (typeof keyConstructor !== \"function\")\n {\n logError(`${decoratorName}: could not resolve constructor of map keys at runtime.`);\n return;\n }\n\n if (typeof valueConstructor !== \"function\")\n {\n logError(`${decoratorName}: could not resolve constructor of map values at runtime.`);\n return;\n }\n\n // If ReflectDecorators is available, use it to check whether 'jsonMapMember' has been used on a map. Warn if not.\n if (isReflectMetadataSupported && Reflect.getMetadata(\"design:type\", target, propKey) !== Map)\n {\n logError(`${decoratorName}: property is not a Map.`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Map,\n elementType: [valueConstructor],\n keyType: keyConstructor,\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: propKey.toString(),\n name: options.name || propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n}\n","import { nameof, logError, logWarning, parseToJSObject } from './typedjson/helpers';\nimport { Constructor } from \"./typedjson/types\";\nimport { JsonObjectMetadata } from \"./typedjson/metadata\";\nimport { Deserializer } from \"./typedjson/deserializer\";\nimport { Serializer } from \"./typedjson/serializer\";\n\nexport type JsonTypes = Object|boolean|string|number|null|undefined;\n\nexport interface ITypedJSONSettings\n{\n /**\n * Sets the handler callback to invoke on errors during serializing and deserializing.\n * Re-throwing errors in this function will halt serialization/deserialization.\n * The default behavior is to log errors to the console.\n */\n errorHandler?: (e: Error) => void;\n\n /**\n * Sets a callback that determines the constructor of the correct sub-type of polymorphic\n * objects while deserializing.\n * The default behavior is to read the type-name from the '__type' property of 'sourceObject',\n * and look it up in 'knownTypes'.\n * The constructor of the sub-type should be returned.\n */\n typeResolver?: (sourceObject: Object, knownTypes: Map) => Function;\n\n nameResolver?: (ctor: Function) => string;\n\n /**\n * Sets a callback that writes type-hints to serialized objects.\n * The default behavior is to write the type-name to the '__type' property, if a derived type\n * is present in place of a base type.\n */\n typeHintEmitter?:\n (targetObject: Object, sourceObject: Object, expectedSourceType: Function) => void;\n\n /**\n * Sets the amount of indentation to use in produced JSON strings.\n * Default value is 0, or no indentation.\n */\n indent?: number;\n\n replacer?: (key: string, value: any) => any;\n\n knownTypes?: Array>;\n}\n\nexport class TypedJSON\n{\n //#region Static\n public static parse(\n object: any, rootType: Constructor, settings?: ITypedJSONSettings,\n ): T|undefined {\n return new TypedJSON(rootType, settings).parse(object);\n }\n\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings?: ITypedJSONSettings,\n dimensions?: 1\n ): T[];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 2\n ): T[][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 3\n ): T[][][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 4\n ): T[][][][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 5\n ): T[][][][][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings?: ITypedJSONSettings,\n dimensions?: number\n ): any[] {\n return new TypedJSON(elementType, settings).parseAsArray(object, dimensions as any);\n }\n\n public static parseAsSet(\n object: any, elementType: Constructor, settings?: ITypedJSONSettings,\n ): Set {\n return new TypedJSON(elementType, settings).parseAsSet(object);\n }\n\n public static parseAsMap(\n object: any,\n keyType: Constructor,\n valueType: Constructor,\n settings?: ITypedJSONSettings,\n ): Map {\n return new TypedJSON(valueType, settings).parseAsMap(object, keyType);\n }\n\n public static toPlainJson(\n object: T, rootType: Constructor, settings?: ITypedJSONSettings,\n ): JsonTypes {\n return new TypedJSON(rootType, settings).toPlainJson(object);\n }\n\n public static toPlainArray(\n object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings,\n ): Object[];\n public static toPlainArray(\n object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings,\n ): Object[][];\n public static toPlainArray(\n object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings,\n ): Object[][][];\n public static toPlainArray(\n object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings,\n ): Object[][][][];\n public static toPlainArray(\n object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings,\n ): Object[][][][][];\n public static toPlainArray(\n object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings,\n ): any[];\n public static toPlainArray(\n object: any[], elementType: Constructor, dimensions?: any, settings?: ITypedJSONSettings,\n ): any[] {\n return new TypedJSON(elementType, settings).toPlainArray(object, dimensions);\n }\n\n public static toPlainSet(\n object: Set, elementType: Constructor, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(elementType, settings).stringifyAsSet(object);\n }\n\n public static toPlainMap(\n object: Map,\n keyCtor: Constructor,\n valueCtor: Constructor,\n settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(valueCtor, settings).stringifyAsMap(object, keyCtor);\n }\n\n public static stringify(\n object: T, rootType: Constructor, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(rootType, settings).stringify(object);\n }\n\n public static stringifyAsArray(\n object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: any[], elementType: Constructor, dimensions?: any, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(elementType, settings).stringifyAsArray(object, dimensions);\n }\n\n public static stringifyAsSet(\n object: Set, elementType: Constructor, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(elementType, settings).stringifyAsSet(object);\n }\n\n public static stringifyAsMap(\n object: Map,\n keyCtor: Constructor,\n valueCtor: Constructor,\n settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(valueCtor, settings).stringifyAsMap(object, keyCtor);\n }\n\n private static _globalConfig: ITypedJSONSettings;\n\n public static setGlobalConfig(config: ITypedJSONSettings)\n {\n if (this._globalConfig)\n {\n Object.assign(this._globalConfig, config);\n }\n else\n {\n this._globalConfig = config;\n }\n }\n\n //#endregion\n\n private serializer: Serializer = new Serializer();\n private deserializer: Deserializer = new Deserializer();\n private globalKnownTypes: Array> = [];\n private indent: number = 0;\n private rootConstructor: Constructor;\n private errorHandler: (e: Error) => void;\n private nameResolver: (ctor: Function) => string;\n private replacer?: (key: string, value: any) => any;\n\n /**\n * Creates a new TypedJSON instance to serialize (stringify) and deserialize (parse) object\n * instances of the specified root class type.\n * @param rootType The constructor of the root class type.\n * @param settings Additional configuration settings.\n */\n constructor(rootConstructor: Constructor, settings?: ITypedJSONSettings)\n {\n let rootMetadata = JsonObjectMetadata.getFromConstructor(rootConstructor);\n\n if (!rootMetadata || (!rootMetadata.isExplicitlyMarked && !rootMetadata.isHandledWithoutAnnotation))\n {\n throw new TypeError(\"The TypedJSON root data type must have the @jsonObject decorator used.\");\n }\n\n this.nameResolver = (ctor) => nameof(ctor);\n this.rootConstructor = rootConstructor;\n this.errorHandler = (error) => logError(error);\n\n if (settings)\n {\n this.config(settings);\n }\n else if (TypedJSON._globalConfig)\n {\n this.config({});\n }\n }\n\n /**\n * Configures TypedJSON through a settings object.\n * @param settings The configuration settings object.\n */\n public config(settings: ITypedJSONSettings)\n {\n if (TypedJSON._globalConfig)\n {\n settings = {\n ...TypedJSON._globalConfig,\n ...settings\n };\n\n if (settings.knownTypes && TypedJSON._globalConfig.knownTypes)\n {\n // Merge known-types (also de-duplicate them, so Array -> Set -> Array).\n settings.knownTypes = Array.from(new Set(\n settings.knownTypes.concat(TypedJSON._globalConfig.knownTypes),\n ));\n }\n }\n\n if (settings.errorHandler)\n {\n this.errorHandler = settings.errorHandler;\n this.deserializer.setErrorHandler(settings.errorHandler);\n this.serializer.setErrorHandler(settings.errorHandler);\n }\n\n if (settings.replacer) this.replacer = settings.replacer;\n if (settings.typeResolver) this.deserializer.setTypeResolver(settings.typeResolver);\n if (settings.typeHintEmitter) this.serializer.setTypeHintEmitter(settings.typeHintEmitter);\n if (settings.indent) this.indent = settings.indent;\n\n if (settings.nameResolver)\n {\n this.nameResolver = settings.nameResolver;\n this.deserializer.setNameResolver(settings.nameResolver);\n // this.serializer.set\n }\n\n if (settings.knownTypes)\n {\n // Type-check knownTypes elements to recognize errors in advance.\n settings.knownTypes.forEach((knownType, i) =>\n {\n // tslint:disable-next-line:no-null-keyword\n if (typeof knownType === \"undefined\" || knownType === null)\n {\n logWarning(\n `TypedJSON.config: 'knownTypes' contains an undefined/null value (element ${i}).`);\n }\n });\n\n this.globalKnownTypes = settings.knownTypes;\n }\n }\n\n /**\n * Converts a JSON string to the root class type.\n * @param object The JSON to parse and convert.\n * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown).\n * @returns Deserialized T or undefined if there were errors.\n */\n public parse(object: any): T|undefined\n {\n const json = parseToJSObject(object, this.rootConstructor);\n\n let rootMetadata = JsonObjectMetadata.getFromConstructor(this.rootConstructor);\n let result: T|undefined;\n let knownTypes = new Map();\n\n this.globalKnownTypes.filter(ktc => ktc).forEach(knownTypeCtor =>\n {\n knownTypes.set(this.nameResolver(knownTypeCtor), knownTypeCtor);\n });\n\n if (rootMetadata)\n {\n rootMetadata.knownTypes.forEach(knownTypeCtor =>\n {\n knownTypes.set(this.nameResolver(knownTypeCtor), knownTypeCtor);\n });\n }\n\n try\n {\n result = this.deserializer.convertSingleValue(json, {\n selfConstructor: this.rootConstructor,\n knownTypes: knownTypes,\n }) as T;\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n\n return result;\n }\n\n public parseAsArray(object: any, dimensions?: 1): T[];\n public parseAsArray(object: any, dimensions: 2): T[][];\n public parseAsArray(object: any, dimensions: 3): T[][][];\n public parseAsArray(object: any, dimensions: 4): T[][][][];\n public parseAsArray(object: any, dimensions: 5): T[][][][][];\n public parseAsArray(object: any, dimensions: number): any[];\n public parseAsArray(object: any, dimensions: number = 1): any[]\n {\n const json = parseToJSObject(object, Array);\n if (json instanceof Array)\n {\n return this.deserializer.convertAsArray(json, {\n selfConstructor: Array,\n elementConstructor: new Array(dimensions - 1)\n .fill(Array)\n .concat(this.rootConstructor),\n knownTypes: this._mapKnownTypes(this.globalKnownTypes),\n });\n }\n else\n {\n this.errorHandler(new TypeError(`Expected 'json' to define an Array`\n + `, but got ${typeof json}.`));\n }\n\n return [];\n }\n\n public parseAsSet(object: any): Set\n {\n const json = parseToJSObject(object, Set);\n // A Set is serialized as T[].\n if (json instanceof Array)\n {\n return this.deserializer.convertAsSet(json, {\n selfConstructor: Array,\n elementConstructor: [this.rootConstructor],\n knownTypes: this._mapKnownTypes(this.globalKnownTypes)\n });\n }\n else\n {\n this.errorHandler(new TypeError(`Expected 'json' to define a Set (using an Array)`\n + `, but got ${typeof json}.`,\n ));\n }\n\n return new Set();\n }\n\n public parseAsMap(object: any, keyConstructor: Constructor): Map\n {\n const json = parseToJSObject(object, Map);\n // A Set is serialized as T[].\n if (json instanceof Array)\n {\n return this.deserializer.convertAsMap(json, {\n selfConstructor: Array,\n elementConstructor: [this.rootConstructor],\n knownTypes: this._mapKnownTypes(this.globalKnownTypes),\n keyConstructor: keyConstructor\n });\n }\n else\n {\n this.errorHandler(new TypeError(`Expected 'json' to define a Set (using an Array)`\n + `, but got ${typeof json}.`,\n ));\n }\n\n return new Map();\n }\n\n /**\n * Converts an instance of the specified class type to a plain JSON object.\n * @param object The instance to convert to a JSON string.\n * @returns Serialized object or undefined if an error has occured.\n */\n public toPlainJson(object: T): JsonTypes\n {\n try\n {\n return this.serializer.convertSingleValue(object, {\n selfType: this.rootConstructor\n });\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n public toPlainArray(object: T[], dimensions?: 1): Object[];\n public toPlainArray(object: T[][], dimensions: 2): Object[][];\n public toPlainArray(object: T[][][], dimensions: 3): Object[][][];\n public toPlainArray(object: T[][][][], dimensions: 4): Object[][][][];\n public toPlainArray(object: T[][][][][], dimensions: 5): Object[][][][][];\n public toPlainArray(object: any[], dimensions: 1|2|3|4|5 = 1): Object[]|undefined\n {\n try\n {\n const elementConstructorArray =\n new Array(dimensions - 1).fill(Array).concat(this.rootConstructor);\n return this.serializer.convertAsArray(object, elementConstructorArray);\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n public toPlainSet(object: Set): Object[]|undefined\n {\n try\n {\n return this.serializer.convertAsSet(object, this.rootConstructor);\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n public toPlainMap(object: Map, keyConstructor: Constructor): { key: any, value: any }[]|undefined\n {\n try\n {\n return this.serializer.convertAsMap(object, keyConstructor, this.rootConstructor);\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n /**\n * Converts an instance of the specified class type to a JSON string.\n * @param object The instance to convert to a JSON string.\n * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown).\n * @returns String with the serialized object or an empty string if an error has occured, but\n * the errorHandler did not throw.\n */\n public stringify(object: T): string\n {\n const result = this.toPlainJson(object);\n if (result === undefined) {\n return '';\n }\n return JSON.stringify(result, this.replacer, this.indent);\n }\n\n public stringifyAsArray(object: T[], dimensions?: 1): string;\n public stringifyAsArray(object: T[][], dimensions: 2): string;\n public stringifyAsArray(object: T[][][], dimensions: 3): string;\n public stringifyAsArray(object: T[][][][], dimensions: 4): string;\n public stringifyAsArray(object: T[][][][][], dimensions: 5): string;\n public stringifyAsArray(object: any[], dimensions: any): string\n {\n return JSON.stringify(this.toPlainArray(object, dimensions), this.replacer, this.indent);\n }\n\n public stringifyAsSet(object: Set): string\n {\n return JSON.stringify(this.toPlainSet(object), this.replacer, this.indent);\n }\n\n public stringifyAsMap(object: Map, keyConstructor: Constructor): string\n {\n return JSON.stringify(this.toPlainMap(object, keyConstructor), this.replacer, this.indent);\n }\n\n private _mapKnownTypes(constructors: Array>)\n {\n let map = new Map>();\n\n constructors.filter(ctor => ctor).forEach(ctor => map.set(this.nameResolver(ctor), ctor));\n\n return map;\n }\n}\n\nexport { jsonObject } from \"./typedjson/json-object\";\nexport { jsonMember } from \"./typedjson/json-member\";\nexport { jsonArrayMember } from \"./typedjson/json-array-member\";\nexport { jsonSetMember } from \"./typedjson/json-set-member\";\nexport { jsonMapMember } from \"./typedjson/json-map-member\";\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack://typedjson/webpack/universalModuleDefinition","webpack://typedjson/webpack/bootstrap","webpack://typedjson/./src/typedjson/helpers.ts","webpack://typedjson/./src/typedjson/metadata.ts","webpack://typedjson/./src/typedjson/serializer.ts","webpack://typedjson/./src/typedjson/deserializer.ts","webpack://typedjson/./src/parser.ts","webpack://typedjson/./src/typedjson/json-object.ts","webpack://typedjson/./src/typedjson/json-member.ts","webpack://typedjson/./src/typedjson/json-array-member.ts","webpack://typedjson/./src/typedjson/json-set-member.ts","webpack://typedjson/./src/typedjson/json-map-member.ts","webpack://typedjson/./src/typedjson.ts"],"names":["root","factory","exports","module","define","amd","self","this","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","METADATA_FIELD_KEY","isDirectlySerializableNativeType","type","Date","Number","String","Boolean","indexOf","isTypeTypedArray","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","parseToJSObject","json","expectedType","jsonStr","expectsTypesSerializedAsStrings","ArrayBuffer","DataView","hasQuotes","length","isInteger","test","trim","JSON","parse","isSubtypeOf","A","B","logError","message","optionalParams","_i","arguments","console","error","apply","concat","log","logWarning","warn","isValueDefined","isInstanceOf","constructor","isReflectMetadataSupported","Reflect","getMetadata","nameof","fn","metadata_JsonObjectMetadata","JsonObjectMetadata","classType","dataMembers","Map","knownTypes","Set","isExplicitlyMarked","isHandledWithoutAnnotation","getJsonObjectName","ctor","metadata","getFromConstructor","doesHandleWithoutAnnotation","primitiveMeta","getKnownTypeNameFromType","injectMetadataInformation","propKey","objectMetadata","decoratorName","deserializer","parentMetadata","forEach","_metadata","_propKey","set","configurable","writable","add","keyType","elementType","elemCtor","serializer_Serializer","Serializer","_typeHintEmitter","targetObject","sourceObject","expectedSourceType","sourceTypeMetadata","name_1","_errorHandler","setTypeHintEmitter","typeEmitterCallback","TypeError","setErrorHandler","errorHandlerCallback","convertSingleValue","typeInfo","memberName","selfType","convertAsArrayBuffer","convertAsDataView","Array","convertAsArray","elementTypes","convertAsSet","convertAsMap","convertAsTypedArray","convertAsObject","expectedName","actualName","_this","sourceMeta_1","memberMetadata","serializer","__assign","expectedElementType","element","expectedTypeName","actualTypeName","typeInfoForElements","slice","map","elementTypeInfo","resultArray","resultElement","push","expectedKeyType","keyTypeInfo","resultKeyValuePairObj","from","buffer","charCode","fromCharCode","join","dataView","deserializer_Deserializer","Deserializer","_typeResolver","__type","setNameResolver","nameResolverCallback","_nameResolver","setTypeResolver","typeResolverCallback","sourceObjectTypeInfo","objectName","expectedSelfType","selfConstructor","sourceObjectMetadata","knownTypeConstructors","_mergeKnownTypes","_createKnownTypesMap","typeFromTypeHint","sourceMetadata_1","sourceObjectWithDeserializedProperties_1","revivedValue","memberValue","memberNameForDebug","elementConstructor","keyConstructor","isRequired","initializerCallback","e","_instantiateType","assign","onDeserializedMethodName","targetObject_1","keys","sourceKey","srcTypeNameForDebug","_isDirectlyDeserializableNativeType","_makeTypeErrorMessage","_throwTypeMismatchError","every","elem","isNaN","_stringToArrayBuffer","_stringToDataView","resultSet","valueTypeInfo","resultMap","targetType","actualSourceType","actualType","knownTypeMaps","result","knowTypes","knownTypeMeta","convertNativeObject","str","buf","bufView","strLen","charCodeAt","parser_TypedJSON","TypedJSON","rootConstructor","settings","globalKnownTypes","indent","rootMetadata","nameResolver","errorHandler","config","_globalConfig","rootType","parseAsArray","dimensions","parseAsSet","parseAsMap","valueType","toPlainJson","toPlainArray","toPlainSet","stringifyAsSet","toPlainMap","keyCtor","valueCtor","stringifyAsMap","stringify","stringifyAsArray","setGlobalConfig","parser_assign","replacer","typeResolver","typeHintEmitter","knownType","filter","ktc","knownTypeCtor","fill","_mapKnownTypes","elementConstructorArray","undefined","constructors","jsonObject","optionsOrTarget","options","decorator","target","onDeserialized","initializer","knownTypeMethodName","jsonMember","propCtor","isSpecialPropertyType","emitDefaultValue","toString","reflectPropCtor","jsonArrayMember","elementCtor","jsonSetMember","jsonMapMember","valueConstructor","__webpack_exports__"],"mappings":"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","file":"typedjson.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"typedjson\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"typedjson\"] = factory();\n\telse\n\t\troot[\"typedjson\"] = factory();\n})((typeof self !== 'undefined' ? self : this), function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","declare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport const METADATA_FIELD_KEY = \"__typedJsonJsonObjectMetadataInformation__\";\n\nexport function getDefaultValue(type: { new (): T }): T|undefined\n{\n switch (type as any)\n {\n case Number:\n return 0 as any;\n\n case String:\n return \"\" as any;\n\n case Boolean:\n return false as any;\n\n case Array:\n return [] as any;\n\n default:\n return undefined;\n }\n}\n\n/**\n * Determines whether the specified type is a type that can be passed on \"as-is\" into `JSON.stringify`.\n * Values of these types don't need special conversion.\n * @param type The constructor of the type (wrapper constructor for primitive types, e.g. `Number` for `number`).\n */\nexport function isDirectlySerializableNativeType(type: Function): boolean\n{\n return !!(~[Date, Number, String, Boolean].indexOf(type as any));\n}\n\nexport function isTypeTypedArray(type: Function): boolean\n{\n return !!(~[Float32Array, Float64Array, Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array]\n .indexOf(type as any));\n}\n\nexport function isPrimitiveValue(obj: any): boolean\n{\n switch (typeof obj)\n {\n case \"string\":\n case \"number\":\n case \"boolean\":\n return true;\n default:\n return (obj instanceof String || obj instanceof Number || obj instanceof Boolean);\n }\n}\n\nexport function isObject(value: any): value is Object\n{\n return typeof value === \"object\";\n}\n\nfunction shouldOmitParseString(jsonStr: string, expectedType: Function): boolean {\n const expectsTypesSerializedAsStrings = expectedType === String\n || expectedType === ArrayBuffer\n || expectedType === DataView;\n\n const hasQuotes = jsonStr.length >= 2 && jsonStr[0] === '\"' && jsonStr[jsonStr.length-1] === '\"';\n const isInteger = /^\\d+$/.test(jsonStr.trim());\n\n return (expectsTypesSerializedAsStrings && !hasQuotes) || ((!hasQuotes && !isInteger) && expectedType === Date);\n}\n\nexport function parseToJSObject(json: any, expectedType: Function): Object {\n if (typeof json !== 'string' || shouldOmitParseString(json, expectedType))\n {\n return json;\n }\n return JSON.parse(json);\n}\n\n/**\n * Determines if 'A' is a sub-type of 'B' (or if 'A' equals 'B').\n * @param A The supposed derived type.\n * @param B The supposed base type.\n */\nexport function isSubtypeOf(A: Function, B: Function)\n{\n return A === B || A.prototype instanceof B;\n}\n\nexport function logError(message?: any, ...optionalParams: any[])\n{\n if (typeof console === \"object\" && typeof console.error === \"function\")\n {\n console.error(message, ...optionalParams);\n }\n else if (typeof console === \"object\" && typeof console.log === \"function\")\n {\n console.log(`ERROR: ${message}`, ...optionalParams);\n }\n}\n\nexport function logMessage(message?: any, ...optionalParams: any[])\n{\n if (typeof console === \"object\" && typeof console.log === \"function\")\n {\n console.log(message, ...optionalParams);\n }\n}\n\nexport function logWarning(message?: any, ...optionalParams: any[])\n{\n if (typeof console === \"object\" && typeof console.warn === \"function\")\n {\n console.warn(message, ...optionalParams);\n } else if (typeof console === \"object\" && typeof console.log === \"function\")\n {\n console.log(`WARNING: ${message}`, ...optionalParams);\n }\n}\n\n/**\n * Checks if the value is considered defined (not undefined and not null).\n * @param value\n */\nexport function isValueDefined(value: T): value is Exclude\n{\n return !(typeof value === \"undefined\" || value === null);\n}\n\nexport function isInstanceOf(value: any, constructor: Function): boolean\n{\n if (typeof value === \"number\")\n {\n return (constructor === Number);\n }\n else if (typeof value === \"string\")\n {\n return (constructor === String);\n }\n else if (typeof value === \"boolean\")\n {\n return (constructor === Boolean);\n }\n else if (isObject(value))\n {\n return (value instanceof constructor);\n }\n\n return false;\n}\n\nexport const isReflectMetadataSupported =\n (typeof Reflect === \"object\" && typeof Reflect.getMetadata === \"function\");\n\n/**\n * Gets the name of a function.\n * @param fn The function whose name to get.\n */\nexport function nameof(fn: Function & { name?: string })\n{\n if (typeof fn.name === \"string\")\n {\n return fn.name;\n }\n else\n {\n return \"undefined\";\n }\n}\n","import { nameof, logError, METADATA_FIELD_KEY, isDirectlySerializableNativeType, isTypeTypedArray } from \"./helpers\";\nimport { IndexedObject } from \"./types\";\n\nexport interface JsonMemberMetadata\n{\n /** If set, a default value will be emitted for uninitialized members. */\n emitDefaultValue?: boolean;\n\n /** Member name as it appears in the serialized JSON. */\n name: string;\n\n /** Property or field key of the json member. */\n key: string;\n\n /** Constuctor (type) reference of the member. */\n ctor?: Function;\n\n /** If set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** If the json member is an array, map or set, sets member options of elements/values. Subsequent values define the types of nested arrays. */\n elementType?: Function[];\n\n /** If the json member is a map, sets member options of array keys. */\n keyType?: Function;\n\n /** Custom deserializer to use. */\n deserializer?: (json: any) => any;\n\n /** Custom serializer to use. */\n serializer?: (value: any) => any;\n}\n\nexport class JsonObjectMetadata\n{\n //#region Static\n /**\n * Gets the name of a class as it appears in a serialized JSON string.\n * @param ctor The constructor of a class (with or without jsonObject).\n */\n public static getJsonObjectName(ctor: Function): string\n {\n const metadata = JsonObjectMetadata.getFromConstructor(ctor);\n return metadata ? nameof(metadata.classType) : nameof(ctor);\n }\n\n /**\n * Gets jsonObject metadata information from a class.\n * @param ctor The constructor class.\n */\n public static getFromConstructor(ctor: Function): JsonObjectMetadata|undefined\n {\n const prototype = ctor.prototype;\n if (!prototype)\n {\n return;\n }\n\n let metadata: JsonObjectMetadata|undefined;\n if (prototype.hasOwnProperty(METADATA_FIELD_KEY))\n {\n // The class prototype contains own jsonObject metadata\n metadata = prototype[METADATA_FIELD_KEY];\n }\n\n // Ignore implicitly added jsonObject (through jsonMember)\n if (metadata && metadata.isExplicitlyMarked)\n {\n return metadata;\n }\n\n // In the end maybe it is something which we can handle directly\n if (JsonObjectMetadata.doesHandleWithoutAnnotation(ctor))\n {\n const primitiveMeta = new JsonObjectMetadata(ctor);\n primitiveMeta.isExplicitlyMarked = true;\n // we do not store the metadata here to not modify builtin prototype\n return primitiveMeta;\n }\n }\n\n /**\n * Gets the known type name of a jsonObject class for type hint.\n * @param constructor The constructor class.\n */\n public static getKnownTypeNameFromType(constructor: Function): string\n {\n const metadata = JsonObjectMetadata.getFromConstructor(constructor);\n return metadata ? nameof(metadata.classType) : nameof(constructor);\n }\n\n private static doesHandleWithoutAnnotation(ctor: Function): boolean\n {\n return isDirectlySerializableNativeType(ctor) || isTypeTypedArray(ctor)\n || ctor === DataView || ctor === ArrayBuffer;\n }\n //#endregion\n\n constructor(\n classType: Function,\n ) {\n this.classType = classType;\n }\n\n public dataMembers: Map = new Map();\n\n public knownTypes: Set = new Set();\n\n public knownTypeMethodName?: string;\n\n /** Gets or sets the constructor function for the jsonObject. */\n public classType: Function;\n\n /**\n * Indicates whether this class was explicitly annotated with @jsonObject\n * or implicitly by @jsonMember\n */\n public isExplicitlyMarked: boolean = false;\n\n /**\n * Indicates whether this type is handled without annotation. This is usually\n * used for the builtin types (except for Maps, Sets, and normal Arrays).\n */\n public isHandledWithoutAnnotation: boolean = false;\n\n /** Name used to encode polymorphic type */\n public name?: string;\n\n public onDeserializedMethodName?: string;\n\n public initializerCallback?: (sourceObject: Object, rawSourceObject: Object) => Object;\n}\n\nexport function injectMetadataInformation(constructor: IndexedObject, propKey: string | symbol, metadata: JsonMemberMetadata)\n{\n const decoratorName = `@jsonMember on ${nameof(constructor.constructor)}.${String(propKey)}`; // For error messages.\n let objectMetadata: JsonObjectMetadata;\n\n // When a property decorator is applied to a static member, 'constructor' is a constructor function.\n // See: https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Decorators.md#property-decorators\n // ... and static members are not supported here, so abort.\n if (typeof constructor === \"function\")\n {\n logError(`${decoratorName}: cannot use a static property.`);\n return;\n }\n\n // Methods cannot be serialized.\n // @ts-ignore symbol indexing is not supported by ts\n if (typeof constructor[propKey] === \"function\")\n {\n logError(`${decoratorName}: cannot use a method property.`);\n return;\n }\n\n if (!metadata || (!metadata.ctor && !metadata.deserializer))\n {\n logError(`${decoratorName}: JsonMemberMetadata has unknown ctor.`);\n return;\n }\n\n // Add jsonObject metadata to 'constructor' if not yet exists ('constructor' is the prototype).\n // NOTE: this will not fire up custom serialization, as 'constructor' must be explicitly marked with '@jsonObject' as well.\n if (!constructor.hasOwnProperty(METADATA_FIELD_KEY))\n {\n // No *own* metadata, create new.\n objectMetadata = new JsonObjectMetadata(constructor.constructor);\n\n // Inherit @JsonMembers from parent @jsonObject (if any).\n const parentMetadata: JsonObjectMetadata = constructor[METADATA_FIELD_KEY];\n if (parentMetadata) // && !constructor.hasOwnProperty(Helpers.METADATA_FIELD_KEY)\n {\n parentMetadata.dataMembers.forEach((_metadata, _propKey) => objectMetadata.dataMembers.set(_propKey, _metadata));\n }\n\n // ('constructor' is the prototype of the involved class, metadata information is added to this class prototype).\n Object.defineProperty(constructor, METADATA_FIELD_KEY, {\n enumerable: false,\n configurable: false,\n writable: false,\n value: objectMetadata\n });\n }\n else\n {\n // JsonObjectMetadata already exists on 'constructor'.\n objectMetadata = constructor[METADATA_FIELD_KEY];\n }\n\n if (!metadata.deserializer)\n {\n // @ts-ignore above is a check (!deser && !ctor)\n objectMetadata.knownTypes.add(metadata.ctor);\n }\n\n if (metadata.keyType)\n objectMetadata.knownTypes.add(metadata.keyType);\n\n if (metadata.elementType)\n metadata.elementType.forEach(elemCtor => objectMetadata.knownTypes.add(elemCtor));\n\n objectMetadata.dataMembers.set(metadata.name, metadata);\n}\n","import { nameof, logError, isValueDefined, isInstanceOf, isTypeTypedArray, isDirectlySerializableNativeType } from \"./helpers\";\nimport { IndexedObject } from \"./types\";\nimport { JsonObjectMetadata } from \"./metadata\";\n\nexport interface IScopeTypeInfo\n{\n selfType: Function;\n elementTypes?: Function[];\n keyType?: Function;\n}\n\nexport interface IScopeArrayTypeInfo extends IScopeTypeInfo\n{\n selfType: new () => Array;\n elementTypes: Function[];\n}\n\nfunction isArrayTypeInfo(typeInfo: IScopeTypeInfo): typeInfo is IScopeArrayTypeInfo {\n return typeInfo.selfType === Array;\n}\n\nexport interface IScopeSetTypeInfo extends IScopeTypeInfo\n{\n selfType: new () => Set;\n elementTypes: [Function];\n}\n\nfunction isSetTypeInfo(typeInfo: IScopeTypeInfo): typeInfo is IScopeSetTypeInfo {\n return typeInfo.selfType === Set;\n}\n\nexport interface IScopeMapTypeInfo extends IScopeTypeInfo\n{\n selfType: new () => Map;\n elementTypes: [Function];\n keyType: Function;\n}\n\nfunction isMapTypeInfo(typeInfo: IScopeTypeInfo): typeInfo is IScopeMapTypeInfo {\n return typeInfo.selfType === Map;\n}\n\n/**\n * Utility class, converts a typed object tree (i.e. a tree of class instances, arrays of class instances, and so on) to an untyped javascript object (also\n * called \"simple javascript object\"), and emits any necessary type hints in the process (for polymorphism).\n *\n * The converted object tree is what will be given to `JSON.stringify` to convert to string as the last step, the serialization is basically like:\n *\n * (1) typed object-tree -> (2) simple JS object-tree -> (3) JSON-string\n */\nexport class Serializer\n{\n private _typeHintEmitter: (targetObject: IndexedObject, sourceObject: IndexedObject, expectedSourceType: Function, sourceTypeMetadata?: JsonObjectMetadata) => void;\n private _errorHandler: (error: Error) => void;\n\n constructor()\n {\n this._typeHintEmitter = (targetObject, sourceObject, expectedSourceType, sourceTypeMetadata?: JsonObjectMetadata) =>\n {\n // By default, we put a \"__type\" property on the output object if the actual object is not the same as the expected one, so that deserialization\n // will know what to deserialize into (given the required known-types are defined, and the object is a valid subtype of the expected type).\n if (sourceObject.constructor !== expectedSourceType)\n {\n const name = sourceTypeMetadata && sourceTypeMetadata.name\n ? sourceTypeMetadata.name\n : nameof(sourceObject.constructor);\n // TODO: Perhaps this can work correctly without string-literal access?\n // tslint:disable-next-line:no-string-literal\n targetObject[\"__type\"] = name;\n }\n };\n\n this._errorHandler = (error) => logError(error);\n }\n\n public setTypeHintEmitter(typeEmitterCallback: (targetObject: Object, sourceObject: Object, expectedSourceType: Function) => void)\n {\n if (typeof typeEmitterCallback !== \"function\")\n {\n throw new TypeError(\"'typeEmitterCallback' is not a function.\");\n }\n\n this._typeHintEmitter = typeEmitterCallback;\n }\n\n public setErrorHandler(errorHandlerCallback: (error: Error) => void)\n {\n if (typeof errorHandlerCallback !== \"function\")\n {\n throw new TypeError(\"'errorHandlerCallback' is not a function.\");\n }\n\n this._errorHandler = errorHandlerCallback;\n }\n\n /**\n * Convert a value of any supported serializable type.\n * The value type will be detected, and the correct serialization method will be called.\n */\n public convertSingleValue(sourceObject: any, typeInfo: IScopeTypeInfo, memberName: string = \"object\"): any\n {\n if (!isValueDefined(sourceObject)) return;\n\n if (!isInstanceOf(sourceObject, typeInfo.selfType))\n {\n let expectedName = nameof(typeInfo.selfType);\n let actualName = nameof(sourceObject.constructor);\n\n this._errorHandler(new TypeError(`Could not serialize '${memberName}': expected '${expectedName}', got '${actualName}'.`));\n return;\n }\n\n if (isDirectlySerializableNativeType(typeInfo.selfType))\n {\n return sourceObject;\n }\n else if (typeInfo.selfType === ArrayBuffer)\n {\n return this.convertAsArrayBuffer(sourceObject);\n }\n else if (typeInfo.selfType === DataView)\n {\n return this.convertAsDataView(sourceObject);\n }\n else if (isArrayTypeInfo(typeInfo))\n {\n return this.convertAsArray(sourceObject, typeInfo.elementTypes, memberName);\n }\n else if (isSetTypeInfo(typeInfo))\n {\n return this.convertAsSet(sourceObject, typeInfo.elementTypes[0], memberName);\n }\n else if (isMapTypeInfo(typeInfo))\n {\n return this.convertAsMap(sourceObject, typeInfo.keyType, typeInfo.elementTypes[0], memberName);\n }\n else if (isTypeTypedArray(typeInfo.selfType))\n {\n return this.convertAsTypedArray(sourceObject);\n }\n else if (typeof sourceObject === \"object\")\n {\n return this.convertAsObject(sourceObject, typeInfo, memberName);\n }\n }\n\n /**\n * Performs the conversion of a typed object (usually a class instance) to a simple javascript object for serialization.\n */\n public convertAsObject(sourceObject: IndexedObject, typeInfo: IScopeTypeInfo, memberName?: string)\n {\n let sourceTypeMetadata: JsonObjectMetadata|undefined;\n let targetObject: IndexedObject;\n\n if (sourceObject.constructor !== typeInfo.selfType && sourceObject instanceof typeInfo.selfType)\n {\n // The source object is not of the expected type, but it is a valid subtype.\n // This is OK, and we'll proceed to gather object metadata from the subtype instead.\n sourceTypeMetadata = JsonObjectMetadata.getFromConstructor(sourceObject.constructor);\n }\n else\n {\n sourceTypeMetadata = JsonObjectMetadata.getFromConstructor(typeInfo.selfType);\n }\n\n if (sourceTypeMetadata)\n {\n const sourceMeta = sourceTypeMetadata;\n // Strong-typed serialization available.\n // We'll serialize by members that have been marked with @jsonMember (including array/set/map members), and perform recursive conversion on\n // each of them. The converted objects are put on the 'targetObject', which is what will be put into 'JSON.stringify' finally.\n targetObject = {};\n\n sourceTypeMetadata.dataMembers.forEach((memberMetadata) =>\n {\n if (memberMetadata.serializer) {\n targetObject[memberMetadata.name] =\n memberMetadata.serializer(sourceObject[memberMetadata.key]);\n } else if (memberMetadata.ctor) {\n targetObject[memberMetadata.name] = this.convertSingleValue(\n sourceObject[memberMetadata.key],\n {\n selfType: memberMetadata.ctor,\n elementTypes: memberMetadata.elementType,\n keyType: memberMetadata.keyType,\n },\n `${nameof(sourceMeta.classType)}.${memberMetadata.key}`,\n );\n } else {\n throw new TypeError(\n `Could not serialize ${memberMetadata.name}, there is`\n + ` no constructor nor serialization function to use.`,\n );\n }\n });\n }\n else\n {\n // Untyped serialization, \"as-is\", we'll just pass the object on.\n // We'll clone the source object, because type hints are added to the object itself, and we don't want to modify to the original object.\n targetObject = { ...sourceObject };\n }\n\n // Add type-hint.\n this._typeHintEmitter(targetObject, sourceObject, typeInfo.selfType, sourceTypeMetadata);\n\n return targetObject;\n }\n\n /**\n * Performs the conversion of an array of typed objects (or primitive values) to an array of simple javascript objects (or primitive values) for\n * serialization.\n * @param expectedElementType The expected type of elements. If the array is supposed to be multi-dimensional, subsequent elements define lower dimensions.\n * @param memberName Name of the object being serialized, used for debugging purposes.\n */\n public convertAsArray(sourceObject: any[], expectedElementType: Function[], memberName = \"object\"): any[]\n {\n if (expectedElementType.length === 0 || !expectedElementType[0])\n throw new TypeError(`Could not serialize ${memberName} as Array: missing element type definition.`);\n\n // Check the type of each element, individually.\n // If at least one array element type is incorrect, we return undefined, which results in no value emitted during serialization.\n // This is so that invalid element types don't unexpectedly alter the ordering of other, valid elements, and that no unexpected undefined values are in\n // the emitted array.\n sourceObject.forEach((element, i) =>\n {\n if (!isInstanceOf(element, expectedElementType[0]))\n {\n const expectedTypeName = nameof(expectedElementType[0]);\n const actualTypeName = nameof(element.constructor);\n throw new TypeError(`Could not serialize ${memberName}[${i}]: expected '${expectedTypeName}', got '${actualTypeName}'.`);\n }\n });\n\n const typeInfoForElements: IScopeTypeInfo = {\n selfType: expectedElementType[0],\n elementTypes: expectedElementType.length > 1 ? expectedElementType.slice(1) : [], // For multidimensional arrays.\n };\n\n if (memberName)\n {\n // Just for debugging purposes.\n memberName += \"[]\";\n }\n\n return sourceObject.map(element => this.convertSingleValue(element, typeInfoForElements, memberName));\n }\n\n /**\n * Performs the conversion of a set of typed objects (or primitive values) into an array of simple javascript objects.\n *\n * @param sourceObject\n * @param expectedElementType The constructor of the expected Set elements (e.g. `Number` for `Set`, or `MyClass` for `Set`).\n * @param memberName Name of the object being serialized, used for debugging purposes.\n * @returns\n */\n public convertAsSet(sourceObject: Set, expectedElementType: Function, memberName = \"object\"): any[]\n {\n if (!expectedElementType)\n throw new TypeError(`Could not serialize ${memberName} as Set: missing element type definition.`);\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfType: expectedElementType,\n };\n\n // For debugging and error tracking.\n if (memberName) memberName += \"[]\";\n\n let resultArray: any[] = [];\n\n // Convert each element of the set, and put it into an output array.\n // The output array is the one serialized, as JSON.stringify does not support Set serialization. (TODO: clarification needed)\n sourceObject.forEach(element =>\n {\n let resultElement = this.convertSingleValue(element, elementTypeInfo, memberName);\n\n // Add to output if the source element was undefined, OR the converted element is defined. This will add intentionally undefined values to output,\n // but not values that became undefined DURING serializing (usually because of a type-error).\n if (!isValueDefined(element) || isValueDefined(resultElement))\n {\n resultArray.push(resultElement);\n }\n });\n\n return resultArray;\n }\n\n /**\n * Performs the conversion of a map of typed objects (or primitive values) into an array of simple javascript objects with `key` and `value` properties.\n *\n * @param sourceObject\n * @param expectedKeyType The constructor of the expected Map keys (e.g. `Number` for `Map`, or `MyClass` for `Map`).\n * @param expectedElementType The constructor of the expected Map values (e.g. `Number` for `Map`, or `MyClass` for `Map`).\n * @param memberName Name of the object being serialized, used for debugging purposes.\n */\n public convertAsMap(sourceObject: Map, expectedKeyType: Function, expectedElementType: Function, memberName = \"object\"): Array<{ key: any, value: any }>\n {\n if (!expectedElementType)\n throw new TypeError(`Could not serialize ${memberName} as Map: missing value type definition.`);\n\n if (!expectedKeyType)\n throw new TypeError(`Could not serialize ${memberName} as Map: missing key type definition.`);\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfType: expectedElementType,\n elementTypes: [expectedElementType]\n };\n\n let keyTypeInfo: IScopeTypeInfo = {\n selfType: expectedKeyType\n };\n\n if (memberName) memberName += \"[]\";\n\n let resultArray: Array<{ key: any, value: any }> = [];\n\n // Convert each *entry* in the map to a simple javascript object with key and value properties.\n sourceObject.forEach((value, key) =>\n {\n let resultKeyValuePairObj = {\n key: this.convertSingleValue(key, keyTypeInfo, memberName),\n value: this.convertSingleValue(value, elementTypeInfo, memberName)\n };\n\n // We are not going to emit entries with undefined keys OR undefined values.\n if (isValueDefined(resultKeyValuePairObj.key) && isValueDefined(resultKeyValuePairObj.value))\n {\n resultArray.push(resultKeyValuePairObj);\n }\n });\n\n return resultArray;\n }\n\n /**\n * Performs the conversion of a typed javascript array to a simple untyped javascript array.\n * This is needed because typed arrays are otherwise serialized as objects, so we'll end up with something like \"{ 0: 0, 1: 1, ... }\".\n *\n * @param sourceObject\n * @returns\n */\n public convertAsTypedArray(sourceObject: ArrayBufferView)\n {\n return Array.from(sourceObject as any);\n }\n\n /**\n * Performs the conversion of a raw ArrayBuffer to a string.\n */\n public convertAsArrayBuffer(buffer: ArrayBuffer)\n {\n // ArrayBuffer -> 16-bit character codes -> character array -> joined string.\n return Array.from(new Uint16Array(buffer)).map(charCode => String.fromCharCode(charCode)).join(\"\");\n }\n\n /**\n * Performs the conversion of DataView, converting its internal ArrayBuffer to a string and returning that string.\n */\n public convertAsDataView(dataView: DataView)\n {\n return this.convertAsArrayBuffer(dataView.buffer);\n }\n}\n","import { nameof, logError, isSubtypeOf, isValueDefined } from \"./helpers\";\nimport { IndexedObject } from \"./types\";\nimport { JsonObjectMetadata } from \"./metadata\";\n\nexport interface IScopeTypeInfo\n{\n selfConstructor: Function;\n elementConstructor?: Function[];\n keyConstructor?: Function;\n knownTypes: Map;\n}\n\n/**\n * Utility class, converts a simple/untyped javascript object-tree to a typed object-tree.\n * It is used after parsing a JSON-string.\n */\nexport class Deserializer\n{\n private _typeResolver: (sourceObject: Object, knownTypes: Map) => Function|undefined;\n private _nameResolver?: (ctor: Function) => string;\n private _errorHandler: (error: Error) => void;\n\n constructor()\n {\n this._typeResolver = (sourceObject: any, knownTypes: Map) =>\n {\n if (sourceObject.__type) return knownTypes.get(sourceObject.__type);\n };\n\n this._errorHandler = (error) => logError(error);\n }\n\n public setNameResolver(nameResolverCallback: (ctor: Function) => string)\n {\n this._nameResolver = nameResolverCallback;\n }\n\n public setTypeResolver(typeResolverCallback: (sourceObject: Object, knownTypes: Map) => Function)\n {\n if (typeof typeResolverCallback !== \"function\") throw new TypeError(\"'typeResolverCallback' is not a function.\");\n\n this._typeResolver = typeResolverCallback;\n }\n\n public setErrorHandler(errorHandlerCallback: (error: Error) => void)\n {\n if (typeof errorHandlerCallback !== \"function\")\n {\n throw new TypeError(\"'errorHandlerCallback' is not a function.\");\n }\n\n this._errorHandler = errorHandlerCallback;\n }\n\n public convertAsObject(\n sourceObject: IndexedObject,\n sourceObjectTypeInfo: IScopeTypeInfo,\n objectName = \"object\",\n ) {\n if (typeof sourceObject !== \"object\" || sourceObject === null)\n {\n this._errorHandler(new TypeError(`Cannot deserialize ${objectName}: 'sourceObject' must be a defined object.`));\n return undefined;\n }\n\n let expectedSelfType = sourceObjectTypeInfo.selfConstructor;\n let sourceObjectMetadata = JsonObjectMetadata.getFromConstructor(expectedSelfType);\n let knownTypeConstructors = sourceObjectTypeInfo.knownTypes;\n\n if (sourceObjectMetadata)\n {\n // Merge known types received from \"above\" with known types defined on the current type.\n knownTypeConstructors = this._mergeKnownTypes(\n knownTypeConstructors,\n this._createKnownTypesMap(sourceObjectMetadata.knownTypes),\n );\n }\n\n // Check if a type-hint is available from the source object.\n let typeFromTypeHint = this._typeResolver(sourceObject, knownTypeConstructors);\n\n if (typeFromTypeHint)\n {\n // Check if type hint is a valid subtype of the expected source type.\n if (isSubtypeOf(typeFromTypeHint, expectedSelfType))\n {\n // Hell yes.\n expectedSelfType = typeFromTypeHint;\n sourceObjectMetadata = JsonObjectMetadata.getFromConstructor(typeFromTypeHint);\n\n if (sourceObjectMetadata)\n {\n // Also merge new known types from subtype.\n knownTypeConstructors = this._mergeKnownTypes(\n knownTypeConstructors,\n this._createKnownTypesMap(sourceObjectMetadata.knownTypes),\n );\n }\n }\n }\n\n if (sourceObjectMetadata && sourceObjectMetadata.isExplicitlyMarked)\n {\n const sourceMetadata = sourceObjectMetadata;\n // Strong-typed deserialization available, get to it.\n // First deserialize properties into a temporary object.\n const sourceObjectWithDeserializedProperties = {} as IndexedObject;\n\n // Deserialize by expected properties.\n sourceMetadata.dataMembers.forEach((memberMetadata, propKey) =>\n {\n const memberValue = sourceObject[propKey];\n const memberNameForDebug = `${nameof(sourceMetadata.classType)}.${propKey}`;\n\n let revivedValue;\n if (memberMetadata.deserializer) {\n revivedValue = memberMetadata.deserializer(memberValue);\n } else if (memberMetadata.ctor) {\n revivedValue = this.convertSingleValue(\n memberValue,\n {\n selfConstructor: memberMetadata.ctor,\n elementConstructor: memberMetadata.elementType,\n keyConstructor: memberMetadata.keyType,\n knownTypes: knownTypeConstructors\n },\n memberNameForDebug,\n );\n } else {\n throw new TypeError(\n `Cannot deserialize ${memberNameForDebug} thers is`\n + ` no constructor nor deserlization function to use.`,\n );\n }\n\n if (isValueDefined(revivedValue))\n {\n sourceObjectWithDeserializedProperties[memberMetadata.key] = revivedValue;\n }\n else if (memberMetadata.isRequired)\n {\n this._errorHandler(new TypeError(`Missing required member '${memberNameForDebug}'.`));\n }\n });\n\n // Next, instantiate target object.\n let targetObject: IndexedObject;\n\n if (typeof sourceObjectMetadata.initializerCallback === \"function\")\n {\n try\n {\n targetObject = sourceObjectMetadata.initializerCallback(\n sourceObjectWithDeserializedProperties,\n sourceObject,\n );\n\n // Check the validity of user-defined initializer callback.\n if (!targetObject)\n {\n throw new TypeError(\n `Cannot deserialize ${objectName}:`\n + ` 'initializer' function returned undefined/null`\n + `, but '${nameof(sourceObjectMetadata.classType)}' was expected.`,\n );\n }\n else if (!(targetObject instanceof sourceObjectMetadata.classType))\n {\n throw new TypeError(\n `Cannot deserialize ${objectName}:`\n + `'initializer' returned '${nameof(targetObject.constructor)}'`\n + `, but '${nameof(sourceObjectMetadata.classType)}' was expected,`\n + `and '${nameof(targetObject.constructor)}' is not a subtype of`\n + ` '${nameof(sourceObjectMetadata.classType)}'`,\n );\n }\n }\n catch (e)\n {\n this._errorHandler(e);\n return undefined;\n }\n }\n else\n {\n targetObject = this._instantiateType(expectedSelfType);\n }\n\n // Finally, assign deserialized properties to target object.\n Object.assign(targetObject, sourceObjectWithDeserializedProperties);\n\n // Call onDeserialized method (if any).\n if (sourceObjectMetadata.onDeserializedMethodName)\n {\n if (typeof (targetObject.constructor as any)[sourceObjectMetadata.onDeserializedMethodName] === \"function\")\n {\n (targetObject.constructor as any)[sourceObjectMetadata.onDeserializedMethodName]();\n }\n else\n {\n this._errorHandler(new TypeError(\n `onDeserialized callback '${nameof(sourceObjectMetadata.classType)}.${sourceObjectMetadata.onDeserializedMethodName}' is not a method.`\n ));\n }\n }\n\n return targetObject;\n }\n else\n {\n // Untyped deserialization into Object instance.\n let targetObject = {} as IndexedObject;\n\n Object.keys(sourceObject).forEach(sourceKey =>\n {\n targetObject[sourceKey] = this.convertSingleValue(sourceObject[sourceKey], {\n selfConstructor: sourceObject[sourceKey].constructor,\n knownTypes: sourceObjectTypeInfo.knownTypes,\n elementConstructor: sourceObjectTypeInfo.elementConstructor,\n keyConstructor: sourceObjectTypeInfo.keyConstructor\n }, sourceKey);\n });\n\n return targetObject;\n }\n }\n\n public convertSingleValue(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\")\n {\n let expectedSelfType = typeInfo.selfConstructor;\n let srcTypeNameForDebug = sourceObject ? nameof(sourceObject.constructor) : \"undefined\";\n\n if (!isValueDefined(sourceObject))\n {\n return sourceObject;\n }\n else if (this._isDirectlyDeserializableNativeType(expectedSelfType))\n {\n if (sourceObject.constructor === expectedSelfType)\n {\n return sourceObject;\n }\n else\n {\n throw new TypeError(this._makeTypeErrorMessage(nameof(expectedSelfType), sourceObject.constructor, memberName));\n }\n }\n else if (expectedSelfType === Date)\n {\n // Support for Date with ISO 8601 format, or with numeric timestamp (milliseconds elapsed since the Epoch).\n // ISO 8601 spec.: https://www.w3.org/TR/NOTE-datetime\n\n if (typeof sourceObject === \"string\" || (typeof sourceObject === \"number\" && sourceObject > 0))\n return new Date(sourceObject as any);\n else\n this._throwTypeMismatchError(\"Date\", \"an ISO-8601 string\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Float32Array)\n {\n // Deserialize Float32Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Float32Array(sourceObject);\n else\n this._throwTypeMismatchError(\"Float32Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Float64Array)\n {\n // Deserialize Float64Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Float64Array(sourceObject);\n else\n this._throwTypeMismatchError(\"Float64Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint8Array)\n {\n // Deserialize Uint8Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint8Array(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint8Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint8ClampedArray)\n {\n // Deserialize Uint8Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint8ClampedArray(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint8ClampedArray\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint16Array)\n {\n // Deserialize Uint16Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint16Array(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint16Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Uint32Array)\n {\n // Deserialize Uint32Array from number[].\n\n if (sourceObject instanceof Array && sourceObject.every(elem => !isNaN(elem)))\n return new Uint32Array(sourceObject.map(value => ~~value));\n else\n this._throwTypeMismatchError(\"Uint32Array\", \"a numeric source array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === ArrayBuffer)\n {\n if (typeof sourceObject === \"string\")\n return this._stringToArrayBuffer(sourceObject);\n else\n this._throwTypeMismatchError(\"ArrayBuffer\", \"a string source\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === DataView)\n {\n if (typeof sourceObject === \"string\")\n return this._stringToDataView(sourceObject);\n else\n this._throwTypeMismatchError(\"DataView\", \"a string source\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Array)\n {\n if (sourceObject instanceof Array)\n return this.convertAsArray(sourceObject, typeInfo, memberName);\n else\n throw new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName));\n }\n else if (expectedSelfType === Set)\n {\n if (sourceObject instanceof Array)\n return this.convertAsSet(sourceObject, typeInfo, memberName);\n else\n this._throwTypeMismatchError(\"Set\", \"Array\", srcTypeNameForDebug, memberName);\n }\n else if (expectedSelfType === Map)\n {\n if (sourceObject instanceof Array)\n return this.convertAsMap(sourceObject, typeInfo, memberName);\n else\n this._throwTypeMismatchError(\"Map\", \"a source array of key-value-pair objects\", srcTypeNameForDebug, memberName);\n }\n else if (sourceObject && typeof sourceObject === \"object\")\n {\n return this.convertAsObject(sourceObject, typeInfo, memberName);\n }\n }\n\n public convertAsArray(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\"): any[]\n {\n if (!(sourceObject instanceof Array))\n {\n this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)));\n return [];\n }\n\n if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Array: missing constructor reference of Array elements.`));\n return [];\n }\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.elementConstructor[0],\n elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [],\n knownTypes: typeInfo.knownTypes\n };\n\n return sourceObject.map(element =>\n {\n // If an array element fails to deserialize, substitute with undefined. This is so that the original ordering is not interrupted by faulty\n // entries, as an Array is ordered.\n try\n {\n return this.convertSingleValue(element, elementTypeInfo);\n }\n catch (e)\n {\n this._errorHandler(e);\n\n // Keep filling the array here with undefined to keep original ordering.\n // Note: this is just aesthetics, not returning anything produces the same result.\n return undefined;\n }\n });\n }\n\n public convertAsSet(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\")\n {\n if (!(sourceObject instanceof Array))\n {\n this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)));\n return new Set();\n }\n\n if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Set: missing constructor reference of Set elements.`));\n return new Set();\n }\n\n let elementTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.elementConstructor[0],\n elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [],\n knownTypes: typeInfo.knownTypes\n };\n let resultSet = new Set();\n\n sourceObject.forEach((element, i) =>\n {\n try\n {\n resultSet.add(this.convertSingleValue(element, elementTypeInfo, memberName + `[${i}]`));\n }\n catch (e)\n {\n // Faulty entries are skipped, because a Set is not ordered, and skipping an entry does not affect others.\n this._errorHandler(e);\n }\n });\n\n return resultSet;\n }\n\n public convertAsMap(sourceObject: any, typeInfo: IScopeTypeInfo, memberName = \"object\")\n {\n if (!(sourceObject instanceof Array))\n this._errorHandler(new TypeError(this._makeTypeErrorMessage(Array, sourceObject.constructor, memberName)));\n\n if (!typeInfo.keyConstructor)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Map: missing key constructor.`));\n return new Map();\n }\n\n if (!typeInfo.elementConstructor || !typeInfo.elementConstructor.length)\n {\n this._errorHandler(new TypeError(`Could not deserialize ${memberName} as Map: missing value constructor.`));\n return new Map();\n }\n\n let keyTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.keyConstructor,\n knownTypes: typeInfo.knownTypes\n };\n\n let valueTypeInfo: IScopeTypeInfo = {\n selfConstructor: typeInfo.elementConstructor[0],\n elementConstructor: (typeInfo.elementConstructor.length > 1) ? typeInfo.elementConstructor.slice(1) : [],\n knownTypes: typeInfo.knownTypes\n };\n\n let resultMap = new Map();\n\n sourceObject.forEach((element: any) =>\n {\n try\n {\n let key = this.convertSingleValue(element.key, keyTypeInfo);\n\n // Undefined/null keys not supported, skip if so.\n if (isValueDefined(key))\n {\n resultMap.set(key, this.convertSingleValue(\n element.value, valueTypeInfo, `${memberName}[${key}]`,\n ));\n }\n }\n catch (e)\n {\n // Faulty entries are skipped, because a Map is not ordered,\n // and skipping an entry does not affect others.\n this._errorHandler(e);\n }\n });\n\n return resultMap;\n }\n\n private _throwTypeMismatchError(\n targetType: string,\n expectedSourceType: string,\n actualSourceType: string,\n memberName: string = \"object\",\n ) {\n throw new TypeError(\n `Could not deserialize ${memberName} as ${targetType}:`\n + ` expected ${expectedSourceType}, got ${actualSourceType}.`,\n );\n }\n\n private _makeTypeErrorMessage(expectedType: Function | string, actualType: Function | string, memberName = \"object\")\n {\n let expectedTypeName = (typeof expectedType === \"function\") ? nameof(expectedType) : expectedType;\n let actualTypeName = (typeof actualType === \"function\") ? nameof(actualType) : actualType;\n\n return `Could not deserialize ${memberName}: expected '${expectedTypeName}', got '${actualTypeName}'.`;\n }\n\n private _instantiateType(ctor: any)\n {\n return new ctor();\n }\n\n private _mergeKnownTypes(...knownTypeMaps: Array>)\n {\n let result = new Map();\n\n knownTypeMaps.forEach(knownTypes =>\n {\n knownTypes.forEach((ctor, name) =>\n {\n if (this._nameResolver)\n {\n result.set(this._nameResolver(ctor), ctor);\n }\n else\n {\n result.set(name, ctor);\n }\n });\n });\n\n return result;\n }\n\n private _createKnownTypesMap(knowTypes: Set)\n {\n const map = new Map();\n\n knowTypes.forEach(ctor =>\n {\n if (this._nameResolver)\n {\n map.set(this._nameResolver(ctor), ctor);\n }\n else\n {\n const knownTypeMeta = JsonObjectMetadata.getFromConstructor(ctor);\n const name = knownTypeMeta && knownTypeMeta.isExplicitlyMarked && knownTypeMeta.name\n ? knownTypeMeta.name\n : ctor.name;\n map.set(name, ctor);\n }\n });\n\n return map;\n }\n\n private _isDirectlyDeserializableNativeType(ctor: any)\n {\n return ~([Number, String, Boolean].indexOf(ctor));\n }\n\n public convertNativeObject(sourceObject: any)\n {\n return sourceObject;\n }\n\n private _stringToArrayBuffer(str: string)\n {\n let buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char\n let bufView = new Uint16Array(buf);\n\n for (let i = 0, strLen = str.length; i < strLen; i++)\n {\n bufView[i] = str.charCodeAt(i);\n }\n\n return buf;\n }\n\n private _stringToDataView(str: string)\n {\n return new DataView(this._stringToArrayBuffer(str));\n }\n}\n","import { Constructor } from \"./typedjson/types\";\nimport { Serializer } from \"./typedjson/serializer\";\nimport { Deserializer } from \"./typedjson/deserializer\";\nimport { JsonObjectMetadata } from \"./typedjson/metadata\";\nimport { logError, logWarning, nameof, parseToJSObject } from \"./typedjson/helpers\";\n\nexport type JsonTypes = Object|boolean|string|number|null|undefined;\n\nexport interface ITypedJSONSettings\n{\n /**\n * Sets the handler callback to invoke on errors during serializing and deserializing.\n * Re-throwing errors in this function will halt serialization/deserialization.\n * The default behavior is to log errors to the console.\n */\n errorHandler?: (e: Error) => void;\n\n /**\n * Sets a callback that determines the constructor of the correct sub-type of polymorphic\n * objects while deserializing.\n * The default behavior is to read the type-name from the '__type' property of 'sourceObject',\n * and look it up in 'knownTypes'.\n * The constructor of the sub-type should be returned.\n */\n typeResolver?: (sourceObject: Object, knownTypes: Map) => Function;\n\n nameResolver?: (ctor: Function) => string;\n\n /**\n * Sets a callback that writes type-hints to serialized objects.\n * The default behavior is to write the type-name to the '__type' property, if a derived type\n * is present in place of a base type.\n */\n typeHintEmitter?:\n (targetObject: Object, sourceObject: Object, expectedSourceType: Function) => void;\n\n /**\n * Sets the amount of indentation to use in produced JSON strings.\n * Default value is 0, or no indentation.\n */\n indent?: number;\n\n replacer?: (key: string, value: any) => any;\n\n knownTypes?: Array>;\n}\n\nexport class TypedJSON\n{\n //#region Static\n public static parse(\n object: any, rootType: Constructor, settings?: ITypedJSONSettings,\n ): T|undefined {\n return new TypedJSON(rootType, settings).parse(object);\n }\n\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings?: ITypedJSONSettings,\n dimensions?: 1\n ): T[];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 2\n ): T[][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 3\n ): T[][][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 4\n ): T[][][][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings: ITypedJSONSettings|undefined,\n dimensions: 5\n ): T[][][][][];\n public static parseAsArray(\n object: any,\n elementType: Constructor,\n settings?: ITypedJSONSettings,\n dimensions?: number\n ): any[] {\n return new TypedJSON(elementType, settings).parseAsArray(object, dimensions as any);\n }\n\n public static parseAsSet(\n object: any, elementType: Constructor, settings?: ITypedJSONSettings,\n ): Set {\n return new TypedJSON(elementType, settings).parseAsSet(object);\n }\n\n public static parseAsMap(\n object: any,\n keyType: Constructor,\n valueType: Constructor,\n settings?: ITypedJSONSettings,\n ): Map {\n return new TypedJSON(valueType, settings).parseAsMap(object, keyType);\n }\n\n public static toPlainJson(\n object: T, rootType: Constructor, settings?: ITypedJSONSettings,\n ): JsonTypes {\n return new TypedJSON(rootType, settings).toPlainJson(object);\n }\n\n public static toPlainArray(\n object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings,\n ): Object[];\n public static toPlainArray(\n object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings,\n ): Object[][];\n public static toPlainArray(\n object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings,\n ): Object[][][];\n public static toPlainArray(\n object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings,\n ): Object[][][][];\n public static toPlainArray(\n object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings,\n ): Object[][][][][];\n public static toPlainArray(\n object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings,\n ): any[];\n public static toPlainArray(\n object: any[], elementType: Constructor, dimensions?: any, settings?: ITypedJSONSettings,\n ): any[] {\n return new TypedJSON(elementType, settings).toPlainArray(object, dimensions);\n }\n\n public static toPlainSet(\n object: Set, elementType: Constructor, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(elementType, settings).stringifyAsSet(object);\n }\n\n public static toPlainMap(\n object: Map,\n keyCtor: Constructor,\n valueCtor: Constructor,\n settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(valueCtor, settings).stringifyAsMap(object, keyCtor);\n }\n\n public static stringify(\n object: T, rootType: Constructor, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(rootType, settings).stringify(object);\n }\n\n public static stringifyAsArray(\n object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings,\n ): string;\n public static stringifyAsArray(\n object: any[], elementType: Constructor, dimensions?: any, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(elementType, settings).stringifyAsArray(object, dimensions);\n }\n\n public static stringifyAsSet(\n object: Set, elementType: Constructor, settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(elementType, settings).stringifyAsSet(object);\n }\n\n public static stringifyAsMap(\n object: Map,\n keyCtor: Constructor,\n valueCtor: Constructor,\n settings?: ITypedJSONSettings,\n ): string {\n return new TypedJSON(valueCtor, settings).stringifyAsMap(object, keyCtor);\n }\n\n private static _globalConfig: ITypedJSONSettings;\n\n public static setGlobalConfig(config: ITypedJSONSettings)\n {\n if (this._globalConfig)\n {\n Object.assign(this._globalConfig, config);\n }\n else\n {\n this._globalConfig = config;\n }\n }\n\n //#endregion\n\n private serializer: Serializer = new Serializer();\n private deserializer: Deserializer = new Deserializer();\n private globalKnownTypes: Array> = [];\n private indent: number = 0;\n private rootConstructor: Constructor;\n private errorHandler: (e: Error) => void;\n private nameResolver: (ctor: Function) => string;\n private replacer?: (key: string, value: any) => any;\n\n /**\n * Creates a new TypedJSON instance to serialize (stringify) and deserialize (parse) object\n * instances of the specified root class type.\n * @param rootType The constructor of the root class type.\n * @param settings Additional configuration settings.\n */\n constructor(rootConstructor: Constructor, settings?: ITypedJSONSettings)\n {\n let rootMetadata = JsonObjectMetadata.getFromConstructor(rootConstructor);\n\n if (!rootMetadata || (!rootMetadata.isExplicitlyMarked && !rootMetadata.isHandledWithoutAnnotation))\n {\n throw new TypeError(\"The TypedJSON root data type must have the @jsonObject decorator used.\");\n }\n\n this.nameResolver = (ctor) => nameof(ctor);\n this.rootConstructor = rootConstructor;\n this.errorHandler = (error) => logError(error);\n\n if (settings)\n {\n this.config(settings);\n }\n else if (TypedJSON._globalConfig)\n {\n this.config({});\n }\n }\n\n /**\n * Configures TypedJSON through a settings object.\n * @param settings The configuration settings object.\n */\n public config(settings: ITypedJSONSettings)\n {\n if (TypedJSON._globalConfig)\n {\n settings = {\n ...TypedJSON._globalConfig,\n ...settings\n };\n\n if (settings.knownTypes && TypedJSON._globalConfig.knownTypes)\n {\n // Merge known-types (also de-duplicate them, so Array -> Set -> Array).\n settings.knownTypes = Array.from(new Set(\n settings.knownTypes.concat(TypedJSON._globalConfig.knownTypes),\n ));\n }\n }\n\n if (settings.errorHandler)\n {\n this.errorHandler = settings.errorHandler;\n this.deserializer.setErrorHandler(settings.errorHandler);\n this.serializer.setErrorHandler(settings.errorHandler);\n }\n\n if (settings.replacer) this.replacer = settings.replacer;\n if (settings.typeResolver) this.deserializer.setTypeResolver(settings.typeResolver);\n if (settings.typeHintEmitter) this.serializer.setTypeHintEmitter(settings.typeHintEmitter);\n if (settings.indent) this.indent = settings.indent;\n\n if (settings.nameResolver)\n {\n this.nameResolver = settings.nameResolver;\n this.deserializer.setNameResolver(settings.nameResolver);\n // this.serializer.set\n }\n\n if (settings.knownTypes)\n {\n // Type-check knownTypes elements to recognize errors in advance.\n settings.knownTypes.forEach((knownType, i) =>\n {\n // tslint:disable-next-line:no-null-keyword\n if (typeof knownType === \"undefined\" || knownType === null)\n {\n logWarning(\n `TypedJSON.config: 'knownTypes' contains an undefined/null value (element ${i}).`);\n }\n });\n\n this.globalKnownTypes = settings.knownTypes;\n }\n }\n\n /**\n * Converts a JSON string to the root class type.\n * @param object The JSON to parse and convert.\n * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown).\n * @returns Deserialized T or undefined if there were errors.\n */\n public parse(object: any): T|undefined\n {\n const json = parseToJSObject(object, this.rootConstructor);\n\n let rootMetadata = JsonObjectMetadata.getFromConstructor(this.rootConstructor);\n let result: T|undefined;\n let knownTypes = new Map();\n\n this.globalKnownTypes.filter(ktc => ktc).forEach(knownTypeCtor =>\n {\n knownTypes.set(this.nameResolver(knownTypeCtor), knownTypeCtor);\n });\n\n if (rootMetadata)\n {\n rootMetadata.knownTypes.forEach(knownTypeCtor =>\n {\n knownTypes.set(this.nameResolver(knownTypeCtor), knownTypeCtor);\n });\n }\n\n try\n {\n result = this.deserializer.convertSingleValue(json, {\n selfConstructor: this.rootConstructor,\n knownTypes: knownTypes,\n }) as T;\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n\n return result;\n }\n\n public parseAsArray(object: any, dimensions?: 1): T[];\n public parseAsArray(object: any, dimensions: 2): T[][];\n public parseAsArray(object: any, dimensions: 3): T[][][];\n public parseAsArray(object: any, dimensions: 4): T[][][][];\n public parseAsArray(object: any, dimensions: 5): T[][][][][];\n public parseAsArray(object: any, dimensions: number): any[];\n public parseAsArray(object: any, dimensions: number = 1): any[]\n {\n const json = parseToJSObject(object, Array);\n if (json instanceof Array)\n {\n return this.deserializer.convertAsArray(json, {\n selfConstructor: Array,\n elementConstructor: new Array(dimensions - 1)\n .fill(Array)\n .concat(this.rootConstructor),\n knownTypes: this._mapKnownTypes(this.globalKnownTypes),\n });\n }\n else\n {\n this.errorHandler(new TypeError(`Expected 'json' to define an Array`\n + `, but got ${typeof json}.`));\n }\n\n return [];\n }\n\n public parseAsSet(object: any): Set\n {\n const json = parseToJSObject(object, Set);\n // A Set is serialized as T[].\n if (json instanceof Array)\n {\n return this.deserializer.convertAsSet(json, {\n selfConstructor: Array,\n elementConstructor: [this.rootConstructor],\n knownTypes: this._mapKnownTypes(this.globalKnownTypes)\n });\n }\n else\n {\n this.errorHandler(new TypeError(`Expected 'json' to define a Set (using an Array)`\n + `, but got ${typeof json}.`,\n ));\n }\n\n return new Set();\n }\n\n public parseAsMap(object: any, keyConstructor: Constructor): Map\n {\n const json = parseToJSObject(object, Map);\n // A Set is serialized as T[].\n if (json instanceof Array)\n {\n return this.deserializer.convertAsMap(json, {\n selfConstructor: Array,\n elementConstructor: [this.rootConstructor],\n knownTypes: this._mapKnownTypes(this.globalKnownTypes),\n keyConstructor: keyConstructor\n });\n }\n else\n {\n this.errorHandler(new TypeError(`Expected 'json' to define a Set (using an Array)`\n + `, but got ${typeof json}.`,\n ));\n }\n\n return new Map();\n }\n\n /**\n * Converts an instance of the specified class type to a plain JSON object.\n * @param object The instance to convert to a JSON string.\n * @returns Serialized object or undefined if an error has occured.\n */\n public toPlainJson(object: T): JsonTypes\n {\n try\n {\n return this.serializer.convertSingleValue(object, {\n selfType: this.rootConstructor\n });\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n public toPlainArray(object: T[], dimensions?: 1): Object[];\n public toPlainArray(object: T[][], dimensions: 2): Object[][];\n public toPlainArray(object: T[][][], dimensions: 3): Object[][][];\n public toPlainArray(object: T[][][][], dimensions: 4): Object[][][][];\n public toPlainArray(object: T[][][][][], dimensions: 5): Object[][][][][];\n public toPlainArray(object: any[], dimensions: 1|2|3|4|5 = 1): Object[]|undefined\n {\n try\n {\n const elementConstructorArray =\n new Array(dimensions - 1).fill(Array).concat(this.rootConstructor);\n return this.serializer.convertAsArray(object, elementConstructorArray);\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n public toPlainSet(object: Set): Object[]|undefined\n {\n try\n {\n return this.serializer.convertAsSet(object, this.rootConstructor);\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n public toPlainMap(object: Map, keyConstructor: Constructor): { key: any, value: any }[]|undefined\n {\n try\n {\n return this.serializer.convertAsMap(object, keyConstructor, this.rootConstructor);\n }\n catch (e)\n {\n this.errorHandler(e);\n }\n }\n\n /**\n * Converts an instance of the specified class type to a JSON string.\n * @param object The instance to convert to a JSON string.\n * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown).\n * @returns String with the serialized object or an empty string if an error has occured, but\n * the errorHandler did not throw.\n */\n public stringify(object: T): string\n {\n const result = this.toPlainJson(object);\n if (result === undefined) {\n return '';\n }\n return JSON.stringify(result, this.replacer, this.indent);\n }\n\n public stringifyAsArray(object: T[], dimensions?: 1): string;\n public stringifyAsArray(object: T[][], dimensions: 2): string;\n public stringifyAsArray(object: T[][][], dimensions: 3): string;\n public stringifyAsArray(object: T[][][][], dimensions: 4): string;\n public stringifyAsArray(object: T[][][][][], dimensions: 5): string;\n public stringifyAsArray(object: any[], dimensions: any): string\n {\n return JSON.stringify(this.toPlainArray(object, dimensions), this.replacer, this.indent);\n }\n\n public stringifyAsSet(object: Set): string\n {\n return JSON.stringify(this.toPlainSet(object), this.replacer, this.indent);\n }\n\n public stringifyAsMap(object: Map, keyConstructor: Constructor): string\n {\n return JSON.stringify(this.toPlainMap(object, keyConstructor), this.replacer, this.indent);\n }\n\n private _mapKnownTypes(constructors: Array>)\n {\n let map = new Map>();\n\n constructors.filter(ctor => ctor).forEach(ctor => map.set(this.nameResolver(ctor), ctor));\n\n return map;\n }\n}\n","import { Constructor, ParameterlessConstructor } from \"./types\";\nimport { METADATA_FIELD_KEY } from \"./helpers\";\nimport { JsonObjectMetadata } from \"./metadata\";\n\nexport interface IJsonObjectOptionsBase\n{\n /**\n * An array of known types to recognize when encountering type-hints,\n * or the name of a static method used for determining known types.\n */\n knownTypes?: Function[] | string;\n\n /**\n * The name of a static or instance method to call when deserialization\n * of the object is completed.\n */\n onDeserialized?: string;\n\n /**\n * The name used to differentiate between different polymorphic types.\n */\n name?: string;\n}\n\nexport interface IJsonObjectOptionsWithInitializer extends IJsonObjectOptionsBase\n{\n /**\n * The name of a static method to call before deserializing and initializing the object, accepting two arguments: (1) sourceObject, an 'Object' instance\n * with all properties already deserialized, and (2) rawSourceObject, a raw 'Object' instance representation of the current object in the serialized JSON\n * (i.e. without deserialized properties).\n */\n initializer: (sourceObject: T, rawSourceObject: T) => T;\n}\n\nexport interface IJsonObjectOptions extends IJsonObjectOptionsBase\n{\n /**\n * The name of a static method to call before deserializing and initializing the object, accepting two arguments: (1) sourceObject, an 'Object' instance\n * with all properties already deserialized, and (2) rawSourceObject, a raw 'Object' instance representation of the current object in the serialized JSON\n * (i.e. without deserialized properties).\n */\n initializer?: (sourceObject: T, rawSourceObject: T) => T;\n}\n\n/**\n * Marks that a class with a parameterized constructor is serializable using TypedJSON, with additional settings. The 'initializer' setting must be specified.\n * @param options Configuration settings.\n */\nexport function jsonObject(options?: IJsonObjectOptionsWithInitializer): (target: Constructor) => void;\n\n/**\n * Marks that a class is serializable using TypedJSON, with additional settings.\n * @param options Configuration settings.\n */\nexport function jsonObject(options?: IJsonObjectOptions): (target: ParameterlessConstructor) => void;\n\n/**\n * Marks that a class with a parameterless constructor is serializable using TypedJSON.\n */\nexport function jsonObject(target: ParameterlessConstructor): void;\n\nexport function jsonObject(optionsOrTarget?: IJsonObjectOptions | Constructor\n): ((target: Constructor) => void) | void {\n let options: IJsonObjectOptions;\n\n if (typeof optionsOrTarget === \"function\")\n {\n // jsonObject is being used as a decorator, directly.\n options = {};\n }\n else\n {\n // jsonObject is being used as a decorator factory.\n options = optionsOrTarget || {};\n }\n\n function decorator(\n target: Function\n ): void {\n let objectMetadata: JsonObjectMetadata;\n\n // Create or obtain JsonObjectMetadata object.\n if (!target.prototype.hasOwnProperty(METADATA_FIELD_KEY))\n {\n // Target has no JsonObjectMetadata associated with it yet, create it now.\n objectMetadata = new JsonObjectMetadata(target);\n\n // Inherit json members and known types from parent @jsonObject (if any).\n const parentMetadata: JsonObjectMetadata = target.prototype[METADATA_FIELD_KEY];\n if (parentMetadata)\n {\n parentMetadata.dataMembers\n .forEach((memberMetadata, propKey) =>\n objectMetadata.dataMembers.set(propKey, memberMetadata));\n parentMetadata.knownTypes\n .forEach((knownType) => objectMetadata.knownTypes.add(knownType));\n }\n\n Object.defineProperty(target.prototype, METADATA_FIELD_KEY, {\n enumerable: false,\n configurable: false,\n writable: false,\n value: objectMetadata\n });\n }\n else\n {\n // Target already has JsonObjectMetadata associated with it.\n objectMetadata = target.prototype[METADATA_FIELD_KEY];\n objectMetadata.classType = target;\n }\n\n // Fill JsonObjectMetadata.\n objectMetadata.isExplicitlyMarked = true;\n objectMetadata.onDeserializedMethodName = options.onDeserialized;\n // T extend Object so it is fine\n objectMetadata.initializerCallback = options.initializer as any;\n if (options.name)\n {\n objectMetadata.name = options.name;\n }\n\n // Obtain known-types.\n if (typeof options.knownTypes === \"string\")\n {\n objectMetadata.knownTypeMethodName = options.knownTypes;\n }\n else if (options.knownTypes instanceof Array)\n {\n options.knownTypes\n .filter(knownType => !!knownType)\n .forEach(knownType => objectMetadata.knownTypes.add(knownType));\n }\n }\n\n if (typeof optionsOrTarget === \"function\")\n {\n // jsonObject is being used as a decorator, directly.\n decorator(optionsOrTarget);\n }\n else\n {\n // jsonObject is being used as a decorator factory.\n return decorator;\n }\n}\n","import {\n nameof, logError, isReflectMetadataSupported, isValueDefined, logWarning, isSubtypeOf\n} from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonMemberOptions\n{\n /**\n * Sets the constructor of the property.\n * Optional with ReflectDecorators.\n */\n constructor?: Function;\n\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, a default value is emitted if the property is uninitialized/undefined. */\n emitDefaultValue?: boolean;\n\n /** When set, the key on the JSON that should be used instead of the class property name. */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that a property is part of the object when serializing, with additional options.\n * Omitting the 'constructor' option requires ReflectDecorators and that the property type is always explicitly declared.\n * @param options Additional options.\n */\nexport function jsonMember(options: IJsonMemberOptions): PropertyDecorator;\n\n/**\n * Specifies that a property is part of the object when serializing.\n * This call signature requires ReflectDecorators and that the property type is always explicitly declared.\n */\nexport function jsonMember(target: Object, propertyKey: string | symbol): void;\n\nexport function jsonMember(optionsOrTarget?: IJsonMemberOptions | Object, propKey?: string | symbol): PropertyDecorator | void\n{\n if (optionsOrTarget instanceof Object && (typeof propKey === \"string\" || typeof propKey === \"symbol\"))\n {\n const target = optionsOrTarget as Object;\n // For error messages.\n const decoratorName = `@jsonMember on ${nameof(target.constructor)}.${String(propKey)}`;\n\n // jsonMember used directly, no additional information directly available besides target and propKey.\n // Obtain property constructor through ReflectDecorators.\n if (isReflectMetadataSupported)\n {\n const reflectPropCtor = Reflect.getMetadata(\"design:type\", target, propKey) as Function;\n\n if (!reflectPropCtor)\n {\n logError(`${decoratorName}: could not resolve detected property constructor at runtime.`);\n return;\n }\n\n if (isSpecialPropertyType(decoratorName, reflectPropCtor))\n {\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: reflectPropCtor,\n key: propKey.toString(),\n name: propKey.toString(),\n });\n }\n else\n {\n logError(`${decoratorName}: ReflectDecorators is required if no 'constructor' option is specified.`);\n return;\n }\n }\n else\n {\n // jsonMember used as a decorator factory.\n return (target: Object, _propKey: string | symbol) =>\n {\n let options: IJsonMemberOptions = optionsOrTarget || {};\n let propCtor: Function|undefined;\n let decoratorName = `@jsonMember on ${nameof(target.constructor)}.${String(_propKey)}`; // For error messages.\n\n if (options.hasOwnProperty(\"constructor\"))\n {\n if (!isValueDefined(options.constructor))\n {\n logError(`${decoratorName}: cannot resolve specified property constructor at runtime.`);\n return;\n }\n\n // Property constructor has been specified. Use ReflectDecorators (if available) to check whether that constructor is correct. Warn if not.\n if (isReflectMetadataSupported && !isSubtypeOf(options.constructor, Reflect.getMetadata(\"design:type\", target, _propKey)))\n {\n logWarning(`${decoratorName}: detected property type does not match 'constructor' option.`);\n }\n\n propCtor = options.constructor;\n }\n else\n {\n // Use ReflectDecorators to obtain property constructor.\n if (isReflectMetadataSupported)\n {\n propCtor = Reflect.getMetadata(\"design:type\", target, _propKey) as Function;\n\n if (!propCtor)\n {\n logError(`${decoratorName}: cannot resolve detected property constructor at runtime.`);\n return;\n }\n }\n else if (!options.deserializer)\n {\n logError(`${decoratorName}: ReflectDecorators is required if no 'constructor' option is specified.`);\n return;\n }\n }\n\n if (isSpecialPropertyType(decoratorName, propCtor))\n {\n return;\n }\n\n injectMetadataInformation(target, _propKey, {\n ctor: propCtor,\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: _propKey.toString(),\n name: options.name || _propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n }\n}\n\nfunction isSpecialPropertyType(decoratorName: string, propCtor?: Function)\n{\n if (propCtor === Array)\n {\n logError(`${decoratorName}: property is an Array. Use the jsonArrayMember decorator to`\n + ` serialize this property.`);\n return true;\n }\n\n if (propCtor === Set)\n {\n logError(`${decoratorName}: property is a Set. Use the jsonSetMember decorator to`\n + ` serialize this property.`);\n return true;\n }\n\n if (propCtor === Map)\n {\n logError(`${decoratorName}: property is a Map. Use the jsonMapMember decorator to`\n + ` serialize this property.`);\n return true;\n }\n\n return false;\n}\n","import { nameof, logError, isReflectMetadataSupported } from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonArrayMemberOptions\n{\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, an empty array is emitted if the property is undefined/uninitialized. */\n emitDefaultValue?: boolean;\n\n /** Sets array dimensions (e.g. 1 for 'number[]' or 2 for 'number[][]'). Defaults to 1. */\n dimensions?: number;\n\n /** When set, the key on the JSON that should be used instead of the class property name */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that a property, of type array, is part of an object when serializing.\n * @param elementConstructor Constructor of array elements (e.g. 'Number' for 'number[]', or 'Date' for 'Date[]').\n * @param options Additional options.\n */\nexport function jsonArrayMember(elementConstructor: Function, options: IJsonArrayMemberOptions = {})\n{\n return (target: Object, propKey: string | symbol) =>\n {\n let decoratorName = `@jsonArrayMember on ${nameof(target.constructor)}.${String(propKey)}`; // For error messages.\n\n if (typeof elementConstructor !== \"function\")\n {\n logError(`${decoratorName}: could not resolve constructor of array elements at runtime.`);\n return;\n }\n\n const dimensions = options.dimensions === undefined ? 1 : options.dimensions;\n if (!isNaN(dimensions) && dimensions < 1)\n {\n logError(`${decoratorName}: 'dimensions' option must be at least 1.`);\n return;\n }\n\n // If ReflectDecorators is available, use it to check whether 'jsonArrayMember' has been used on an array.\n if (isReflectMetadataSupported && Reflect.getMetadata(\"design:type\", target, propKey) !== Array)\n {\n logError(`${decoratorName}: property is not an Array.`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Array,\n elementType: createArrayElementType(elementConstructor, dimensions),\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: propKey.toString(),\n name: options.name || propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n}\n\nfunction createArrayElementType(elementCtor: Function, dimensions: number) {\n const elementTypes = new Array(dimensions).fill(Array, 0, -1);\n elementTypes[dimensions-1] = elementCtor;\n return elementTypes;\n}\n","import { nameof } from \"./helpers\";\nimport { IJsonMemberOptions } from \"./json-member\";\nimport { JsonMemberMetadata, JsonObjectMetadata, injectMetadataInformation } from \"./metadata\";\nimport * as Helpers from \"./helpers\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonSetMemberOptions\n{\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, a default value is emitted for each uninitialized json member. */\n emitDefaultValue?: boolean;\n\n /** When set, the key on the JSON that should be used instead of the class property name */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that the property is part of the object when serializing.\n * Use this decorator on properties of type Set.\n * @param elementConstructor Constructor of set elements (e.g. 'Number' for Set or 'Date' for Set).\n * @param options Additional options.\n */\nexport function jsonSetMember(elementConstructor: Function, options: IJsonSetMemberOptions = {})\n{\n return (target: Object, propKey: string | symbol) =>\n {\n var decoratorName = `@jsonSetMember on ${nameof(target.constructor)}.${String(propKey)}`; // For error messages.\n\n if (typeof elementConstructor !== \"function\")\n {\n Helpers.logError(`${decoratorName}: could not resolve constructor of set elements at runtime.`);\n return;\n }\n\n // If ReflectDecorators is available, use it to check whether 'jsonSetMember' has been used on a set. Warn if not.\n if (Helpers.isReflectMetadataSupported && Reflect.getMetadata(\"design:type\", target, propKey) !== Set)\n {\n Helpers.logError(`${decoratorName}: property is not a Set.`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Set,\n elementType: [elementConstructor],\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: propKey.toString(),\n name: options.name || propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n}\n","import { nameof, logError, isReflectMetadataSupported } from \"./helpers\";\nimport { injectMetadataInformation } from \"./metadata\";\n\ndeclare abstract class Reflect\n{\n public static getMetadata(metadataKey: string, target: any, targetKey: string | symbol): any;\n}\n\nexport interface IJsonMapMemberOptions\n{\n /** When set, indicates that the member must be present when deserializing. */\n isRequired?: boolean;\n\n /** When set, a default value is emitted for each uninitialized json member. */\n emitDefaultValue?: boolean;\n\n /** When set, the key on the JSON that should be used instead of the class property name */\n name?: string;\n\n /** When set, this deserializer will be used to deserialize the member. The callee must assure the correct type. */\n deserializer?: (json: any) => any;\n\n /** When set, this serializer will be used to serialize the member. */\n serializer?: (value: any) => any;\n}\n\n/**\n * Specifies that the property is part of the object when serializing.\n * Use this decorator on properties of type Map.\n * @param keyConstructor Constructor of map keys (e.g. 'Number' for 'Map').\n * @param valueConstructor Constructor of map values (e.g. 'Date' for 'Map').\n * @param options Additional options.\n */\nexport function jsonMapMember(keyConstructor: Function, valueConstructor: Function, options: IJsonMapMemberOptions = {})\n{\n return (target: Object, propKey: string | symbol) =>\n {\n let decoratorName = `@jsonMapMember on ${nameof(target.constructor)}.${String(propKey)}`; // For error messages.\n\n if (typeof keyConstructor !== \"function\")\n {\n logError(`${decoratorName}: could not resolve constructor of map keys at runtime.`);\n return;\n }\n\n if (typeof valueConstructor !== \"function\")\n {\n logError(`${decoratorName}: could not resolve constructor of map values at runtime.`);\n return;\n }\n\n // If ReflectDecorators is available, use it to check whether 'jsonMapMember' has been used on a map. Warn if not.\n if (isReflectMetadataSupported && Reflect.getMetadata(\"design:type\", target, propKey) !== Map)\n {\n logError(`${decoratorName}: property is not a Map.`);\n return;\n }\n\n injectMetadataInformation(target, propKey, {\n ctor: Map,\n elementType: [valueConstructor],\n keyType: keyConstructor,\n emitDefaultValue: options.emitDefaultValue || false,\n isRequired: options.isRequired || false,\n key: propKey.toString(),\n name: options.name || propKey.toString(),\n deserializer: options.deserializer,\n serializer: options.serializer,\n });\n };\n}\n","export { TypedJSON, ITypedJSONSettings, JsonTypes } from \"./parser\";\nexport { jsonObject } from \"./typedjson/json-object\";\nexport { jsonMember } from \"./typedjson/json-member\";\nexport { jsonArrayMember } from \"./typedjson/json-array-member\";\nexport { jsonSetMember } from \"./typedjson/json-set-member\";\nexport { jsonMapMember } from \"./typedjson/json-map-member\";\n"],"sourceRoot":""} \ No newline at end of file diff --git a/src/parser.ts b/src/parser.ts new file mode 100644 index 0000000..e6bf9fc --- /dev/null +++ b/src/parser.ts @@ -0,0 +1,534 @@ +import { Constructor } from "./typedjson/types"; +import { Serializer } from "./typedjson/serializer"; +import { Deserializer } from "./typedjson/deserializer"; +import { JsonObjectMetadata } from "./typedjson/metadata"; +import { logError, logWarning, nameof, parseToJSObject } from "./typedjson/helpers"; + +export type JsonTypes = Object|boolean|string|number|null|undefined; + +export interface ITypedJSONSettings +{ + /** + * Sets the handler callback to invoke on errors during serializing and deserializing. + * Re-throwing errors in this function will halt serialization/deserialization. + * The default behavior is to log errors to the console. + */ + errorHandler?: (e: Error) => void; + + /** + * Sets a callback that determines the constructor of the correct sub-type of polymorphic + * objects while deserializing. + * The default behavior is to read the type-name from the '__type' property of 'sourceObject', + * and look it up in 'knownTypes'. + * The constructor of the sub-type should be returned. + */ + typeResolver?: (sourceObject: Object, knownTypes: Map) => Function; + + nameResolver?: (ctor: Function) => string; + + /** + * Sets a callback that writes type-hints to serialized objects. + * The default behavior is to write the type-name to the '__type' property, if a derived type + * is present in place of a base type. + */ + typeHintEmitter?: + (targetObject: Object, sourceObject: Object, expectedSourceType: Function) => void; + + /** + * Sets the amount of indentation to use in produced JSON strings. + * Default value is 0, or no indentation. + */ + indent?: number; + + replacer?: (key: string, value: any) => any; + + knownTypes?: Array>; +} + +export class TypedJSON +{ + //#region Static + public static parse( + object: any, rootType: Constructor, settings?: ITypedJSONSettings, + ): T|undefined { + return new TypedJSON(rootType, settings).parse(object); + } + + public static parseAsArray( + object: any, + elementType: Constructor, + settings?: ITypedJSONSettings, + dimensions?: 1 + ): T[]; + public static parseAsArray( + object: any, + elementType: Constructor, + settings: ITypedJSONSettings|undefined, + dimensions: 2 + ): T[][]; + public static parseAsArray( + object: any, + elementType: Constructor, + settings: ITypedJSONSettings|undefined, + dimensions: 3 + ): T[][][]; + public static parseAsArray( + object: any, + elementType: Constructor, + settings: ITypedJSONSettings|undefined, + dimensions: 4 + ): T[][][][]; + public static parseAsArray( + object: any, + elementType: Constructor, + settings: ITypedJSONSettings|undefined, + dimensions: 5 + ): T[][][][][]; + public static parseAsArray( + object: any, + elementType: Constructor, + settings?: ITypedJSONSettings, + dimensions?: number + ): any[] { + return new TypedJSON(elementType, settings).parseAsArray(object, dimensions as any); + } + + public static parseAsSet( + object: any, elementType: Constructor, settings?: ITypedJSONSettings, + ): Set { + return new TypedJSON(elementType, settings).parseAsSet(object); + } + + public static parseAsMap( + object: any, + keyType: Constructor, + valueType: Constructor, + settings?: ITypedJSONSettings, + ): Map { + return new TypedJSON(valueType, settings).parseAsMap(object, keyType); + } + + public static toPlainJson( + object: T, rootType: Constructor, settings?: ITypedJSONSettings, + ): JsonTypes { + return new TypedJSON(rootType, settings).toPlainJson(object); + } + + public static toPlainArray( + object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings, + ): Object[]; + public static toPlainArray( + object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings, + ): Object[][]; + public static toPlainArray( + object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings, + ): Object[][][]; + public static toPlainArray( + object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings, + ): Object[][][][]; + public static toPlainArray( + object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings, + ): Object[][][][][]; + public static toPlainArray( + object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings, + ): any[]; + public static toPlainArray( + object: any[], elementType: Constructor, dimensions?: any, settings?: ITypedJSONSettings, + ): any[] { + return new TypedJSON(elementType, settings).toPlainArray(object, dimensions); + } + + public static toPlainSet( + object: Set, elementType: Constructor, settings?: ITypedJSONSettings, + ): string { + return new TypedJSON(elementType, settings).stringifyAsSet(object); + } + + public static toPlainMap( + object: Map, + keyCtor: Constructor, + valueCtor: Constructor, + settings?: ITypedJSONSettings, + ): string { + return new TypedJSON(valueCtor, settings).stringifyAsMap(object, keyCtor); + } + + public static stringify( + object: T, rootType: Constructor, settings?: ITypedJSONSettings, + ): string { + return new TypedJSON(rootType, settings).stringify(object); + } + + public static stringifyAsArray( + object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings, + ): string; + public static stringifyAsArray( + object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings, + ): string; + public static stringifyAsArray( + object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings, + ): string; + public static stringifyAsArray( + object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings, + ): string; + public static stringifyAsArray( + object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings, + ): string; + public static stringifyAsArray( + object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings, + ): string; + public static stringifyAsArray( + object: any[], elementType: Constructor, dimensions?: any, settings?: ITypedJSONSettings, + ): string { + return new TypedJSON(elementType, settings).stringifyAsArray(object, dimensions); + } + + public static stringifyAsSet( + object: Set, elementType: Constructor, settings?: ITypedJSONSettings, + ): string { + return new TypedJSON(elementType, settings).stringifyAsSet(object); + } + + public static stringifyAsMap( + object: Map, + keyCtor: Constructor, + valueCtor: Constructor, + settings?: ITypedJSONSettings, + ): string { + return new TypedJSON(valueCtor, settings).stringifyAsMap(object, keyCtor); + } + + private static _globalConfig: ITypedJSONSettings; + + public static setGlobalConfig(config: ITypedJSONSettings) + { + if (this._globalConfig) + { + Object.assign(this._globalConfig, config); + } + else + { + this._globalConfig = config; + } + } + + //#endregion + + private serializer: Serializer = new Serializer(); + private deserializer: Deserializer = new Deserializer(); + private globalKnownTypes: Array> = []; + private indent: number = 0; + private rootConstructor: Constructor; + private errorHandler: (e: Error) => void; + private nameResolver: (ctor: Function) => string; + private replacer?: (key: string, value: any) => any; + + /** + * Creates a new TypedJSON instance to serialize (stringify) and deserialize (parse) object + * instances of the specified root class type. + * @param rootType The constructor of the root class type. + * @param settings Additional configuration settings. + */ + constructor(rootConstructor: Constructor, settings?: ITypedJSONSettings) + { + let rootMetadata = JsonObjectMetadata.getFromConstructor(rootConstructor); + + if (!rootMetadata || (!rootMetadata.isExplicitlyMarked && !rootMetadata.isHandledWithoutAnnotation)) + { + throw new TypeError("The TypedJSON root data type must have the @jsonObject decorator used."); + } + + this.nameResolver = (ctor) => nameof(ctor); + this.rootConstructor = rootConstructor; + this.errorHandler = (error) => logError(error); + + if (settings) + { + this.config(settings); + } + else if (TypedJSON._globalConfig) + { + this.config({}); + } + } + + /** + * Configures TypedJSON through a settings object. + * @param settings The configuration settings object. + */ + public config(settings: ITypedJSONSettings) + { + if (TypedJSON._globalConfig) + { + settings = { + ...TypedJSON._globalConfig, + ...settings + }; + + if (settings.knownTypes && TypedJSON._globalConfig.knownTypes) + { + // Merge known-types (also de-duplicate them, so Array -> Set -> Array). + settings.knownTypes = Array.from(new Set( + settings.knownTypes.concat(TypedJSON._globalConfig.knownTypes), + )); + } + } + + if (settings.errorHandler) + { + this.errorHandler = settings.errorHandler; + this.deserializer.setErrorHandler(settings.errorHandler); + this.serializer.setErrorHandler(settings.errorHandler); + } + + if (settings.replacer) this.replacer = settings.replacer; + if (settings.typeResolver) this.deserializer.setTypeResolver(settings.typeResolver); + if (settings.typeHintEmitter) this.serializer.setTypeHintEmitter(settings.typeHintEmitter); + if (settings.indent) this.indent = settings.indent; + + if (settings.nameResolver) + { + this.nameResolver = settings.nameResolver; + this.deserializer.setNameResolver(settings.nameResolver); + // this.serializer.set + } + + if (settings.knownTypes) + { + // Type-check knownTypes elements to recognize errors in advance. + settings.knownTypes.forEach((knownType, i) => + { + // tslint:disable-next-line:no-null-keyword + if (typeof knownType === "undefined" || knownType === null) + { + logWarning( + `TypedJSON.config: 'knownTypes' contains an undefined/null value (element ${i}).`); + } + }); + + this.globalKnownTypes = settings.knownTypes; + } + } + + /** + * Converts a JSON string to the root class type. + * @param object The JSON to parse and convert. + * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown). + * @returns Deserialized T or undefined if there were errors. + */ + public parse(object: any): T|undefined + { + const json = parseToJSObject(object, this.rootConstructor); + + let rootMetadata = JsonObjectMetadata.getFromConstructor(this.rootConstructor); + let result: T|undefined; + let knownTypes = new Map(); + + this.globalKnownTypes.filter(ktc => ktc).forEach(knownTypeCtor => + { + knownTypes.set(this.nameResolver(knownTypeCtor), knownTypeCtor); + }); + + if (rootMetadata) + { + rootMetadata.knownTypes.forEach(knownTypeCtor => + { + knownTypes.set(this.nameResolver(knownTypeCtor), knownTypeCtor); + }); + } + + try + { + result = this.deserializer.convertSingleValue(json, { + selfConstructor: this.rootConstructor, + knownTypes: knownTypes, + }) as T; + } + catch (e) + { + this.errorHandler(e); + } + + return result; + } + + public parseAsArray(object: any, dimensions?: 1): T[]; + public parseAsArray(object: any, dimensions: 2): T[][]; + public parseAsArray(object: any, dimensions: 3): T[][][]; + public parseAsArray(object: any, dimensions: 4): T[][][][]; + public parseAsArray(object: any, dimensions: 5): T[][][][][]; + public parseAsArray(object: any, dimensions: number): any[]; + public parseAsArray(object: any, dimensions: number = 1): any[] + { + const json = parseToJSObject(object, Array); + if (json instanceof Array) + { + return this.deserializer.convertAsArray(json, { + selfConstructor: Array, + elementConstructor: new Array(dimensions - 1) + .fill(Array) + .concat(this.rootConstructor), + knownTypes: this._mapKnownTypes(this.globalKnownTypes), + }); + } + else + { + this.errorHandler(new TypeError(`Expected 'json' to define an Array` + + `, but got ${typeof json}.`)); + } + + return []; + } + + public parseAsSet(object: any): Set + { + const json = parseToJSObject(object, Set); + // A Set is serialized as T[]. + if (json instanceof Array) + { + return this.deserializer.convertAsSet(json, { + selfConstructor: Array, + elementConstructor: [this.rootConstructor], + knownTypes: this._mapKnownTypes(this.globalKnownTypes) + }); + } + else + { + this.errorHandler(new TypeError(`Expected 'json' to define a Set (using an Array)` + + `, but got ${typeof json}.`, + )); + } + + return new Set(); + } + + public parseAsMap(object: any, keyConstructor: Constructor): Map + { + const json = parseToJSObject(object, Map); + // A Set is serialized as T[]. + if (json instanceof Array) + { + return this.deserializer.convertAsMap(json, { + selfConstructor: Array, + elementConstructor: [this.rootConstructor], + knownTypes: this._mapKnownTypes(this.globalKnownTypes), + keyConstructor: keyConstructor + }); + } + else + { + this.errorHandler(new TypeError(`Expected 'json' to define a Set (using an Array)` + + `, but got ${typeof json}.`, + )); + } + + return new Map(); + } + + /** + * Converts an instance of the specified class type to a plain JSON object. + * @param object The instance to convert to a JSON string. + * @returns Serialized object or undefined if an error has occured. + */ + public toPlainJson(object: T): JsonTypes + { + try + { + return this.serializer.convertSingleValue(object, { + selfType: this.rootConstructor + }); + } + catch (e) + { + this.errorHandler(e); + } + } + + public toPlainArray(object: T[], dimensions?: 1): Object[]; + public toPlainArray(object: T[][], dimensions: 2): Object[][]; + public toPlainArray(object: T[][][], dimensions: 3): Object[][][]; + public toPlainArray(object: T[][][][], dimensions: 4): Object[][][][]; + public toPlainArray(object: T[][][][][], dimensions: 5): Object[][][][][]; + public toPlainArray(object: any[], dimensions: 1|2|3|4|5 = 1): Object[]|undefined + { + try + { + const elementConstructorArray = + new Array(dimensions - 1).fill(Array).concat(this.rootConstructor); + return this.serializer.convertAsArray(object, elementConstructorArray); + } + catch (e) + { + this.errorHandler(e); + } + } + + public toPlainSet(object: Set): Object[]|undefined + { + try + { + return this.serializer.convertAsSet(object, this.rootConstructor); + } + catch (e) + { + this.errorHandler(e); + } + } + + public toPlainMap(object: Map, keyConstructor: Constructor): { key: any, value: any }[]|undefined + { + try + { + return this.serializer.convertAsMap(object, keyConstructor, this.rootConstructor); + } + catch (e) + { + this.errorHandler(e); + } + } + + /** + * Converts an instance of the specified class type to a JSON string. + * @param object The instance to convert to a JSON string. + * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown). + * @returns String with the serialized object or an empty string if an error has occured, but + * the errorHandler did not throw. + */ + public stringify(object: T): string + { + const result = this.toPlainJson(object); + if (result === undefined) { + return ''; + } + return JSON.stringify(result, this.replacer, this.indent); + } + + public stringifyAsArray(object: T[], dimensions?: 1): string; + public stringifyAsArray(object: T[][], dimensions: 2): string; + public stringifyAsArray(object: T[][][], dimensions: 3): string; + public stringifyAsArray(object: T[][][][], dimensions: 4): string; + public stringifyAsArray(object: T[][][][][], dimensions: 5): string; + public stringifyAsArray(object: any[], dimensions: any): string + { + return JSON.stringify(this.toPlainArray(object, dimensions), this.replacer, this.indent); + } + + public stringifyAsSet(object: Set): string + { + return JSON.stringify(this.toPlainSet(object), this.replacer, this.indent); + } + + public stringifyAsMap(object: Map, keyConstructor: Constructor): string + { + return JSON.stringify(this.toPlainMap(object, keyConstructor), this.replacer, this.indent); + } + + private _mapKnownTypes(constructors: Array>) + { + let map = new Map>(); + + constructors.filter(ctor => ctor).forEach(ctor => map.set(this.nameResolver(ctor), ctor)); + + return map; + } +} diff --git a/src/typedjson.ts b/src/typedjson.ts index 04b7fe7..3a20c19 100644 --- a/src/typedjson.ts +++ b/src/typedjson.ts @@ -1,538 +1,4 @@ -import { nameof, logError, logWarning, parseToJSObject } from './typedjson/helpers'; -import { Constructor } from "./typedjson/types"; -import { JsonObjectMetadata } from "./typedjson/metadata"; -import { Deserializer } from "./typedjson/deserializer"; -import { Serializer } from "./typedjson/serializer"; - -export type JsonTypes = Object|boolean|string|number|null|undefined; - -export interface ITypedJSONSettings -{ - /** - * Sets the handler callback to invoke on errors during serializing and deserializing. - * Re-throwing errors in this function will halt serialization/deserialization. - * The default behavior is to log errors to the console. - */ - errorHandler?: (e: Error) => void; - - /** - * Sets a callback that determines the constructor of the correct sub-type of polymorphic - * objects while deserializing. - * The default behavior is to read the type-name from the '__type' property of 'sourceObject', - * and look it up in 'knownTypes'. - * The constructor of the sub-type should be returned. - */ - typeResolver?: (sourceObject: Object, knownTypes: Map) => Function; - - nameResolver?: (ctor: Function) => string; - - /** - * Sets a callback that writes type-hints to serialized objects. - * The default behavior is to write the type-name to the '__type' property, if a derived type - * is present in place of a base type. - */ - typeHintEmitter?: - (targetObject: Object, sourceObject: Object, expectedSourceType: Function) => void; - - /** - * Sets the amount of indentation to use in produced JSON strings. - * Default value is 0, or no indentation. - */ - indent?: number; - - replacer?: (key: string, value: any) => any; - - knownTypes?: Array>; -} - -export class TypedJSON -{ - //#region Static - public static parse( - object: any, rootType: Constructor, settings?: ITypedJSONSettings, - ): T|undefined { - return new TypedJSON(rootType, settings).parse(object); - } - - public static parseAsArray( - object: any, - elementType: Constructor, - settings?: ITypedJSONSettings, - dimensions?: 1 - ): T[]; - public static parseAsArray( - object: any, - elementType: Constructor, - settings: ITypedJSONSettings|undefined, - dimensions: 2 - ): T[][]; - public static parseAsArray( - object: any, - elementType: Constructor, - settings: ITypedJSONSettings|undefined, - dimensions: 3 - ): T[][][]; - public static parseAsArray( - object: any, - elementType: Constructor, - settings: ITypedJSONSettings|undefined, - dimensions: 4 - ): T[][][][]; - public static parseAsArray( - object: any, - elementType: Constructor, - settings: ITypedJSONSettings|undefined, - dimensions: 5 - ): T[][][][][]; - public static parseAsArray( - object: any, - elementType: Constructor, - settings?: ITypedJSONSettings, - dimensions?: number - ): any[] { - return new TypedJSON(elementType, settings).parseAsArray(object, dimensions as any); - } - - public static parseAsSet( - object: any, elementType: Constructor, settings?: ITypedJSONSettings, - ): Set { - return new TypedJSON(elementType, settings).parseAsSet(object); - } - - public static parseAsMap( - object: any, - keyType: Constructor, - valueType: Constructor, - settings?: ITypedJSONSettings, - ): Map { - return new TypedJSON(valueType, settings).parseAsMap(object, keyType); - } - - public static toPlainJson( - object: T, rootType: Constructor, settings?: ITypedJSONSettings, - ): JsonTypes { - return new TypedJSON(rootType, settings).toPlainJson(object); - } - - public static toPlainArray( - object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings, - ): Object[]; - public static toPlainArray( - object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings, - ): Object[][]; - public static toPlainArray( - object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings, - ): Object[][][]; - public static toPlainArray( - object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings, - ): Object[][][][]; - public static toPlainArray( - object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings, - ): Object[][][][][]; - public static toPlainArray( - object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings, - ): any[]; - public static toPlainArray( - object: any[], elementType: Constructor, dimensions?: any, settings?: ITypedJSONSettings, - ): any[] { - return new TypedJSON(elementType, settings).toPlainArray(object, dimensions); - } - - public static toPlainSet( - object: Set, elementType: Constructor, settings?: ITypedJSONSettings, - ): string { - return new TypedJSON(elementType, settings).stringifyAsSet(object); - } - - public static toPlainMap( - object: Map, - keyCtor: Constructor, - valueCtor: Constructor, - settings?: ITypedJSONSettings, - ): string { - return new TypedJSON(valueCtor, settings).stringifyAsMap(object, keyCtor); - } - - public static stringify( - object: T, rootType: Constructor, settings?: ITypedJSONSettings, - ): string { - return new TypedJSON(rootType, settings).stringify(object); - } - - public static stringifyAsArray( - object: T[], elementType: Constructor, dimensions?: 1, settings?: ITypedJSONSettings, - ): string; - public static stringifyAsArray( - object: T[][], elementType: Constructor, dimensions: 2, settings?: ITypedJSONSettings, - ): string; - public static stringifyAsArray( - object: T[][][], elementType: Constructor, dimensions: 3, settings?: ITypedJSONSettings, - ): string; - public static stringifyAsArray( - object: T[][][][], elementType: Constructor, dimensions: 4, settings?: ITypedJSONSettings, - ): string; - public static stringifyAsArray( - object: T[][][][][], elementType: Constructor, dimensions: 5, settings?: ITypedJSONSettings, - ): string; - public static stringifyAsArray( - object: any[], elementType: Constructor, dimensions: number, settings?: ITypedJSONSettings, - ): string; - public static stringifyAsArray( - object: any[], elementType: Constructor, dimensions?: any, settings?: ITypedJSONSettings, - ): string { - return new TypedJSON(elementType, settings).stringifyAsArray(object, dimensions); - } - - public static stringifyAsSet( - object: Set, elementType: Constructor, settings?: ITypedJSONSettings, - ): string { - return new TypedJSON(elementType, settings).stringifyAsSet(object); - } - - public static stringifyAsMap( - object: Map, - keyCtor: Constructor, - valueCtor: Constructor, - settings?: ITypedJSONSettings, - ): string { - return new TypedJSON(valueCtor, settings).stringifyAsMap(object, keyCtor); - } - - private static _globalConfig: ITypedJSONSettings; - - public static setGlobalConfig(config: ITypedJSONSettings) - { - if (this._globalConfig) - { - Object.assign(this._globalConfig, config); - } - else - { - this._globalConfig = config; - } - } - - //#endregion - - private serializer: Serializer = new Serializer(); - private deserializer: Deserializer = new Deserializer(); - private globalKnownTypes: Array> = []; - private indent: number = 0; - private rootConstructor: Constructor; - private errorHandler: (e: Error) => void; - private nameResolver: (ctor: Function) => string; - private replacer?: (key: string, value: any) => any; - - /** - * Creates a new TypedJSON instance to serialize (stringify) and deserialize (parse) object - * instances of the specified root class type. - * @param rootType The constructor of the root class type. - * @param settings Additional configuration settings. - */ - constructor(rootConstructor: Constructor, settings?: ITypedJSONSettings) - { - let rootMetadata = JsonObjectMetadata.getFromConstructor(rootConstructor); - - if (!rootMetadata || (!rootMetadata.isExplicitlyMarked && !rootMetadata.isHandledWithoutAnnotation)) - { - throw new TypeError("The TypedJSON root data type must have the @jsonObject decorator used."); - } - - this.nameResolver = (ctor) => nameof(ctor); - this.rootConstructor = rootConstructor; - this.errorHandler = (error) => logError(error); - - if (settings) - { - this.config(settings); - } - else if (TypedJSON._globalConfig) - { - this.config({}); - } - } - - /** - * Configures TypedJSON through a settings object. - * @param settings The configuration settings object. - */ - public config(settings: ITypedJSONSettings) - { - if (TypedJSON._globalConfig) - { - settings = { - ...TypedJSON._globalConfig, - ...settings - }; - - if (settings.knownTypes && TypedJSON._globalConfig.knownTypes) - { - // Merge known-types (also de-duplicate them, so Array -> Set -> Array). - settings.knownTypes = Array.from(new Set( - settings.knownTypes.concat(TypedJSON._globalConfig.knownTypes), - )); - } - } - - if (settings.errorHandler) - { - this.errorHandler = settings.errorHandler; - this.deserializer.setErrorHandler(settings.errorHandler); - this.serializer.setErrorHandler(settings.errorHandler); - } - - if (settings.replacer) this.replacer = settings.replacer; - if (settings.typeResolver) this.deserializer.setTypeResolver(settings.typeResolver); - if (settings.typeHintEmitter) this.serializer.setTypeHintEmitter(settings.typeHintEmitter); - if (settings.indent) this.indent = settings.indent; - - if (settings.nameResolver) - { - this.nameResolver = settings.nameResolver; - this.deserializer.setNameResolver(settings.nameResolver); - // this.serializer.set - } - - if (settings.knownTypes) - { - // Type-check knownTypes elements to recognize errors in advance. - settings.knownTypes.forEach((knownType, i) => - { - // tslint:disable-next-line:no-null-keyword - if (typeof knownType === "undefined" || knownType === null) - { - logWarning( - `TypedJSON.config: 'knownTypes' contains an undefined/null value (element ${i}).`); - } - }); - - this.globalKnownTypes = settings.knownTypes; - } - } - - /** - * Converts a JSON string to the root class type. - * @param object The JSON to parse and convert. - * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown). - * @returns Deserialized T or undefined if there were errors. - */ - public parse(object: any): T|undefined - { - const json = parseToJSObject(object, this.rootConstructor); - - let rootMetadata = JsonObjectMetadata.getFromConstructor(this.rootConstructor); - let result: T|undefined; - let knownTypes = new Map(); - - this.globalKnownTypes.filter(ktc => ktc).forEach(knownTypeCtor => - { - knownTypes.set(this.nameResolver(knownTypeCtor), knownTypeCtor); - }); - - if (rootMetadata) - { - rootMetadata.knownTypes.forEach(knownTypeCtor => - { - knownTypes.set(this.nameResolver(knownTypeCtor), knownTypeCtor); - }); - } - - try - { - result = this.deserializer.convertSingleValue(json, { - selfConstructor: this.rootConstructor, - knownTypes: knownTypes, - }) as T; - } - catch (e) - { - this.errorHandler(e); - } - - return result; - } - - public parseAsArray(object: any, dimensions?: 1): T[]; - public parseAsArray(object: any, dimensions: 2): T[][]; - public parseAsArray(object: any, dimensions: 3): T[][][]; - public parseAsArray(object: any, dimensions: 4): T[][][][]; - public parseAsArray(object: any, dimensions: 5): T[][][][][]; - public parseAsArray(object: any, dimensions: number): any[]; - public parseAsArray(object: any, dimensions: number = 1): any[] - { - const json = parseToJSObject(object, Array); - if (json instanceof Array) - { - return this.deserializer.convertAsArray(json, { - selfConstructor: Array, - elementConstructor: new Array(dimensions - 1) - .fill(Array) - .concat(this.rootConstructor), - knownTypes: this._mapKnownTypes(this.globalKnownTypes), - }); - } - else - { - this.errorHandler(new TypeError(`Expected 'json' to define an Array` - + `, but got ${typeof json}.`)); - } - - return []; - } - - public parseAsSet(object: any): Set - { - const json = parseToJSObject(object, Set); - // A Set is serialized as T[]. - if (json instanceof Array) - { - return this.deserializer.convertAsSet(json, { - selfConstructor: Array, - elementConstructor: [this.rootConstructor], - knownTypes: this._mapKnownTypes(this.globalKnownTypes) - }); - } - else - { - this.errorHandler(new TypeError(`Expected 'json' to define a Set (using an Array)` - + `, but got ${typeof json}.`, - )); - } - - return new Set(); - } - - public parseAsMap(object: any, keyConstructor: Constructor): Map - { - const json = parseToJSObject(object, Map); - // A Set is serialized as T[]. - if (json instanceof Array) - { - return this.deserializer.convertAsMap(json, { - selfConstructor: Array, - elementConstructor: [this.rootConstructor], - knownTypes: this._mapKnownTypes(this.globalKnownTypes), - keyConstructor: keyConstructor - }); - } - else - { - this.errorHandler(new TypeError(`Expected 'json' to define a Set (using an Array)` - + `, but got ${typeof json}.`, - )); - } - - return new Map(); - } - - /** - * Converts an instance of the specified class type to a plain JSON object. - * @param object The instance to convert to a JSON string. - * @returns Serialized object or undefined if an error has occured. - */ - public toPlainJson(object: T): JsonTypes - { - try - { - return this.serializer.convertSingleValue(object, { - selfType: this.rootConstructor - }); - } - catch (e) - { - this.errorHandler(e); - } - } - - public toPlainArray(object: T[], dimensions?: 1): Object[]; - public toPlainArray(object: T[][], dimensions: 2): Object[][]; - public toPlainArray(object: T[][][], dimensions: 3): Object[][][]; - public toPlainArray(object: T[][][][], dimensions: 4): Object[][][][]; - public toPlainArray(object: T[][][][][], dimensions: 5): Object[][][][][]; - public toPlainArray(object: any[], dimensions: 1|2|3|4|5 = 1): Object[]|undefined - { - try - { - const elementConstructorArray = - new Array(dimensions - 1).fill(Array).concat(this.rootConstructor); - return this.serializer.convertAsArray(object, elementConstructorArray); - } - catch (e) - { - this.errorHandler(e); - } - } - - public toPlainSet(object: Set): Object[]|undefined - { - try - { - return this.serializer.convertAsSet(object, this.rootConstructor); - } - catch (e) - { - this.errorHandler(e); - } - } - - public toPlainMap(object: Map, keyConstructor: Constructor): { key: any, value: any }[]|undefined - { - try - { - return this.serializer.convertAsMap(object, keyConstructor, this.rootConstructor); - } - catch (e) - { - this.errorHandler(e); - } - } - - /** - * Converts an instance of the specified class type to a JSON string. - * @param object The instance to convert to a JSON string. - * @throws Error if any errors are thrown in the specified errorHandler callback (re-thrown). - * @returns String with the serialized object or an empty string if an error has occured, but - * the errorHandler did not throw. - */ - public stringify(object: T): string - { - const result = this.toPlainJson(object); - if (result === undefined) { - return ''; - } - return JSON.stringify(result, this.replacer, this.indent); - } - - public stringifyAsArray(object: T[], dimensions?: 1): string; - public stringifyAsArray(object: T[][], dimensions: 2): string; - public stringifyAsArray(object: T[][][], dimensions: 3): string; - public stringifyAsArray(object: T[][][][], dimensions: 4): string; - public stringifyAsArray(object: T[][][][][], dimensions: 5): string; - public stringifyAsArray(object: any[], dimensions: any): string - { - return JSON.stringify(this.toPlainArray(object, dimensions), this.replacer, this.indent); - } - - public stringifyAsSet(object: Set): string - { - return JSON.stringify(this.toPlainSet(object), this.replacer, this.indent); - } - - public stringifyAsMap(object: Map, keyConstructor: Constructor): string - { - return JSON.stringify(this.toPlainMap(object, keyConstructor), this.replacer, this.indent); - } - - private _mapKnownTypes(constructors: Array>) - { - let map = new Map>(); - - constructors.filter(ctor => ctor).forEach(ctor => map.set(this.nameResolver(ctor), ctor)); - - return map; - } -} - +export { TypedJSON, ITypedJSONSettings, JsonTypes } from "./parser"; export { jsonObject } from "./typedjson/json-object"; export { jsonMember } from "./typedjson/json-member"; export { jsonArrayMember } from "./typedjson/json-array-member";